Go: cmd/go: CC variable misparsed when set to a path containing spaces

Created on 15 Sep 2020  ·  18Comments  ·  Source: golang/go

go build -buildmode=c-shared -o C:\Users\XAMARI~1\AppData\Local\Temp\gomobile-work-285666087\lib\armeabi-v7a\libbasic.so golang.org/x/mobile/example/basic failed: exit status 2

runtime/cgo

exec: "C:\Program": file does not exist

E:\GoWorkDir>go env

set GO111MODULE=auto
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Xamarin Developer\AppData\Local\go-build
set GOENV=C:\Users\Xamarin Developer\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=E:\GoWorkDir\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=E:\GoWorkDir
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\XAMARI~1\AppData\Local\Temp\go-build823121506=/tmp/go-build -gno-record-gcc-switches

NeedsInvestigation

Most helpful comment

@XamarinPOC
You need to install the android sdk/ndk to a path without spaces like C:\androidsdk
Make sure you changed the variable ANDROID_HOME too

All 18 comments

Your go installation is corrupt and/or the time stamps have been disrupted, possibly by unpacking one version of go over another

Please delete c:\go and reinstall from a fresh copy

I am actually able to repro this.

exact command: CC="C:\\path with spaces\\bin\\gcc" go build or CC="C:/path with spaces/bin/gcc" go build
works with any source file that uses cgo

It's specific to the CC/CXX class of variables so looks like something is wrong with how go parses them.

cc @ianlancetaylor

@bcmills I just uninstalled and installed fresh Go version 1.15.2 but no luck.

I'm trying to run build command => gomobile build -target=android golang.org/x/.............. to generate apk file

@AlexRouSg, thanks for the detail. I can even reproduce it on Linux:

example.com/bin with spaces$ echo "$CC"
/tmp/tmp.jTseVJjT2L/example.com/bin with spaces/gcc

example.com/bin with spaces$ "$CC" --version
gcc (Debian 9.3.0-13) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


example.com/bin with spaces$ go env CC
/tmp/tmp.jTseVJjT2L/example.com/bin

So looks like there are multiple places that needs fixing ...

I've found
https://github.com/golang/go/blob/29634436fd741a7c685bf8f242b6fd62f093d1ad/src/cmd/cgo/gcc.go#L1536
which only affects running the cgo binary direcly

go build and go tool cgo seems to have a different issue and I can't seem to figure out where that is. But likely it's related to calling strings.Fields or something along those lines.

Yes, there are several places where we're calling strings.Fields to split this sort of command, which seems clearly incorrect to me.

But I think we also try to follow the usual C toolchain behavior for the CC environment variable, so I'm trying to figure out if there is a standard format for escaping paths containing spaces. (Perhaps @ianlancetaylor or @jayconrod knows?)

@XamarinPOC @chaitanyaevoke In the meantime for gomobile, you'll have to install the SDK to a path without spaces

I just uninstalled and installed fresh Go version 1.15.2 but no luck.

I'm trying to run build command => gomobile build -target=android golang.org/x/.............. to generate apk file

@AlexRouSg Which Sdk?? Can you . please explain it .

@XamarinPOC
You need to install the android sdk/ndk to a path without spaces like C:\androidsdk
Make sure you changed the variable ANDROID_HOME too

Change https://golang.org/cl/255018 mentions this issue: cmd/go: allow the CC path to contain spaces

Yup ,after removing spaces its working now. Can we get this fix in next release.

Wait. Right now I can run

CC="gcc -O3" go build

and all my cgo files will be built with -O3.

Now, maybe that is a mistake and maybe we should change it. But we definitely shouldn't change that behavior casually. We should discuss it on the mailing list, we should find out whether it will break anybody.

In particular there is no documented way to pass C compiler flags when running make.bash other than setting CC to include the compiler and the flags. And the value of the CC environment variable used when running make.bash because the default value of the C compiler used when building programs.

In other words, we can't just treat this a minor bug that we should just fix. We have to think about how this has worked in the past and how it should work going forward.

The CL that I mailed preserves the property that space-separated arguments following the executable name are treated as arguments: it uses exec.LookPath to identify the first space that could plausibly indicate a break between the command and its arguments, and falls back to the old strings.Fields behavior if none of the possible prefixes resolves to an executable.

I believe that preserves the existing behavior for all commands that would successfully invoke a compiler, and also fixes some number of cases that previously would have failed.

OK, thanks. I'm a bit worried about the possibility of confusion. I guess it should work but it seems pretty complicated.

Agreed. I was kind of hoping that there would be some existing standard or extension for quoting within CC, but I couldn't find one.

As an alternative, I suppose that we could allow shell-style quoting within the CC variable. (Do you think that would be better or worse?)

Shell style quoting sounds better to me. I can imagine people having args like -I/path with spaces/ which wouldn't be covered by the current CL. Tho that makes me wonder if cgo handles args with spaces correctly for #cgo CFLAGS family of comments or pkgconfig provided flags ...

EDIT:
Looks like #cgo comments understands shell quoting while pkgconfig is kinda weird.
pkgconfig escapes spaces with \ so it looks like -L/path\ with\ spaces which then causes cgo to error

Shell quoting sounds a little better to me, I guess.

Was this page helpful?
0 / 5 - 0 ratings