go: cmd/go: give a better error message when building Go package with CGO_ENABLED=0
When trying to cross compile the go compiler silently ignores any files that use import "C"
statement.
In this example I’ve tried to compile for windows on a linux host machine, but this issue seems to be present on other host platforms as well.
It seems to do this because it disables CGO_ENABLED
being disabled by default when the host and target platform mismatch despite the required toolchains being present (mingw-w64 in my case).
I managed to resolve this issue by enabling CGO_ENABLED
and setting CC
and CXX
, but this issue is more about the unclear error message.
What version of Go are you using (go version
)?
go version go1.10 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
Without GOOS:
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ikkerens/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/lib/go:/var/git/Go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build897508503=/tmp/go-build -gno-record-gcc-switches"
With GOOS=windows
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ikkerens/.cache/go-build"
GOEXE=".exe"
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="windows"
GOPATH="/usr/lib/go:/var/git/Go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-m64 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build822882573=/tmp/go-build -gno-record-gcc-switches"
What did you do?
2 Go files:
// cgo.go
package main
import "C"
func test() {
}
// main.go
package main
func main() {
test()
}
What did you expect to see?
Some kind of warning that cgo.go is being skipped in compilation due to CGO_ENABLED
being 0
.
What did you see instead?
# test
./main.go:4:2: undefined: test
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 17
- Comments: 22 (15 by maintainers)
Commits related to this issue
- cmd/cgo: clarify implicit "cgo" build constraint When using the special import "C", the "cgo" build constraint is implied for the go file, potentially triggering unclear "undefined" error messages. E... — committed to golang/go by ikkerens 6 years ago
- Note about https://github.com/golang/go/issues/24068 — committed to zchee/golang-wiki by avivey 5 years ago
imho the result is even worse if you consider the example of @ikkerens with any external package imported, e.g.
Instead of
./main.go:4:2: undefined: test
the error message will becannot find module for path github.com/pkg/errors
. This just took me literally hours, because I was expecting an imported package to be dependent on CGO, while the actual issue was just me forgetting about animport "C"
in the code.This is really misleading and hard to track down…
One way we could do better would be for the go tool, if there is a compilation error, to report that some files were excluded due to build constraints (we already do that for the case where build constraints exclude all files). We could perhaps even pay closer attention to the cgo build constraint, and explicitly point the user to docs about the
CGO_ENABLED
environment variable.Something else that comes to mind is a static analysis check (in vet?) that would say something along the lines of
this package will fail to cross-compile and build with CGO_ENABLED=0
. That is, checking if a package typechecks properly both with and without thecgo
build tag.cgo is disabled when cross compiling.
On 23 February 2018 at 23:51, mingrammer notifications@github.com wrote:
That is, we don’t have the type check the package assuming a different set of build constraints. We just note that the compilation failed and print “by the way, the following files were not passed to the compiler due to build constraints: x.go …”.
I just recently experienced something similar when trying to cross-compile, I think that the error message should also print the build constraints being applied, i.e.:
if the constraints happen to exclude all files, then it’d be great if it printed something like the following:
In my case I was cross-compiling from Windows Subsystem for Linux to a windows target that had CGO files, I initially had not set
CGO_ENABLED=1
and it took me a while to realize it b.c. the only build constraints I had in mind wherewindows
,386
andabc
and the error message did not bring it up.Getting the applied build constraints would allow one to do the following:
It’d be great if the
go list
command supported printing also the non-go files that are ignored, something like: