New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: give a better error message when building Go package with CGO_ENABLED=0 #24068

Open
ikkerens opened this Issue Feb 23, 2018 · 14 comments

Comments

Projects
None yet
8 participants
@ikkerens
Contributor

ikkerens commented Feb 23, 2018

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
@mingrammer

This comment has been minimized.

Contributor

mingrammer commented Feb 23, 2018

Did you run go build ?

@ikkerens

This comment has been minimized.

Contributor

ikkerens commented Feb 23, 2018

Yes, the two commands I used for comparison are:

GOOS=linux go build
GOOS=windows go build

The second one produces the "undefined" error message.

@mingrammer

This comment has been minimized.

Contributor

mingrammer commented Feb 23, 2018

Hmm .. same problem to me. It seems like go can not find source file which import "C" when GOOS=windows

@davecheney

This comment has been minimized.

Contributor

davecheney commented Feb 23, 2018

@ikkerens

This comment has been minimized.

Contributor

ikkerens commented Feb 23, 2018

@davecheney I am aware, the issue in question is more about the lack of a proper error message instead of silently ignoring the affected files and thus causing "undefined" errors.

@mvdan

This comment has been minimized.

Member

mvdan commented Feb 23, 2018

Should all packages using cgo fail to build with CGO_ENABLED=0? That seems wrong to me - some standard library packages build both with and without cgo, such as os/user.

@mvdan

This comment has been minimized.

Member

mvdan commented Feb 23, 2018

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 the cgo build tag.

@ikkerens

This comment has been minimized.

Contributor

ikkerens commented Feb 23, 2018

Even go vet would indeed be very helpful, as I spent quite some time trying to find out why my build wouldn't work.

Regarding letting builds fail, I definitely don't think it should, but even building with -x -v doesn't give any information about skipping the file because there isn't any.

All I'm asking for is more information for when this occurs. And you could potentially suppress any warnings/errors when the //+build cgo is used.

@mvdan

This comment has been minimized.

Member

mvdan commented Feb 23, 2018

The Go compiler doesn't have a notion of warnings, so -x -v should not affect its output.

I guess another option, which is similar to what you're asking, is to make the compiler give a helpful message in this case. But, for it to know to do that, it would have to know that the package type-checks properly with CGO. That's a non-trivial amount of extra work involved.

@ikkerens

This comment has been minimized.

Contributor

ikkerens commented Feb 23, 2018

I'll leave that one to you/the team, as I have no knowledge of the compiler itself. I opened this issue as someone I had spoken to not too long ago was getting this same error without knowing why, and it wasn't until encountering it myself that I understood the cause of it. Any kind of message either in the compiler or even the documentation would be very helpful.

The documentation ( https://golang.org/cmd/cgo/#hdr-Using_cgo_with_the_go_command ) currently specifies that CGO_ENABLED will be disabled if the target platform is different from the host, but fails to mention that any files still using import "C" will be ignored as if //+build cgo is implied.

So even if the amount of work required to add a helpful compiler message is non-trivial, I'd imagine a slight addition to the documentation wouldn't be.

@mvdan

This comment has been minimized.

Member

mvdan commented Feb 23, 2018

Agreed that improving the documentation is an easy win - if you'd like to help, you're most welcome to. Should be easy now that we accept pull requests.

@gopherbot

This comment has been minimized.

gopherbot commented Feb 23, 2018

Change https://golang.org/cl/96655 mentions this issue: cmd/cgo: clarify implicit "cgo" build constraint

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Feb 23, 2018

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.

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Feb 23, 2018

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 ...".

gopherbot pushed a commit that referenced this issue Feb 26, 2018

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.
Explicitly explain this in the documentation.

Updates #24068

Change-Id: Ib656ceccd52c749ffe7fb2d3db9ac144f17abb32
GitHub-Last-Rev: 5a13f00
GitHub-Pull-Request: #24072
Reviewed-on: https://go-review.googlesource.com/96655
Reviewed-by: Ian Lance Taylor <iant@golang.org>

@ianlancetaylor ianlancetaylor changed the title from cmd/compile: bad error message when cross-compiling while using cgo to cmd/go: give a better error message when building Go package with CGO_ENABLED=0 Mar 28, 2018

@ianlancetaylor ianlancetaylor added this to the Go1.11 milestone Mar 28, 2018

@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Go1.12 Jul 6, 2018

@bcmills bcmills modified the milestones: Go1.12, Go1.13 Nov 13, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment