Skip to content
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

go/build: Module support is disabled when ReleaseTags don't match the default. #46856

Open
nevkontakte opened this issue Jun 21, 2021 · 1 comment
Labels
modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@nevkontakte
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.16.5 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/aleks/.cache/go-build"
GOENV="/home/aleks/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/aleks/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/aleks/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.5"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/aleks/go/src/github.com/gopherjs/gopherjs/go.mod"
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-build2418058575=/tmp/go-build -gno-record-gcc-switches"

Problem description

go/build implements module support by calling out to the go list command, which is very nice. Unfortunately, this functionality is disabled if build.Context has ReleaseTags different from the default build context (determined by the version of Go that built the binary). I assume this restriction comes from the fact that you can't pass ReleaseTags to the go list command.

Unfortunately, this check is not particularly helpful because there's no guarantee that the go tool in PATH will match the version the program was built. A typical example would be a tool that is distributed as a pre-built binary.

In addition, when a go/build user tries to match release tags to the GOROOT they are working with, module support may silently turn off, which is a surprising and tricky to debug behavior.

Possible solution

A better version of that condition could be checking that go version matches ReleaseTags, and let the library user to add GOROOT/bin to PATH if they require so, or maybe even use the go list from GOROOT by default.

In addition, it's worth considering whether a silent fallback is appropriate in case of ReleaseTags specifically. I can see that the fallback allows us to maintain compatibility with earlier behavior, which did not depend on the go tool or its version. But maybe disabling the fallback when GO111MODULE=on is set would be reasonable?

A side note on x/tools/go/packages

go/packages sidesteps this problem by not allowing the user to set ReleaseTags to begin with. #41231 suggests the user to manipulate PATH to achieve the desired effect.

Foressing a suggestion to use the go/packages instead of go/build, it is unfortunately difficult in my case for two reasons:

  • There's a lot of per-existing code that already relies on go/build, updating it is a lot of work.
  • At the moment, go/packages doesn't seem to expose any information about embedded files, but go/build does.
@bcmills
Copy link
Contributor

bcmills commented Jun 23, 2021

Compare #46648.

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 23, 2021
@bcmills bcmills added this to the Backlog milestone Jun 23, 2021
nevkontakte added a commit to nevkontakte/gopherjs that referenced this issue Jul 18, 2021
go/build disables its module support (arguably incorrectly) whenever
ReleaseTags are set to anything other than default. While such situation
should be rare in practice, GopherJS formally supports being built by a
version other than it's compatible Go version, and this hack ensures
module support doesn't mysteriously disappear in such cases.
nevkontakte added a commit to nevkontakte/gopherjs that referenced this issue Jul 18, 2021
go/build disables its module support (arguably incorrectly) whenever
ReleaseTags are set to anything other than default. While such situation
should be rare in practice, GopherJS formally supports being built by a
version other than it's compatible Go version, and this hack ensures
module support doesn't mysteriously disappear in such cases.
nevkontakte added a commit to nevkontakte/gopherjs that referenced this issue Aug 2, 2021
go/build disables its module support (arguably incorrectly) whenever
ReleaseTags are set to anything other than default. While such situation
should be rare in practice, GopherJS formally supports being built by a
version other than it's compatible Go version, and this hack ensures
module support doesn't mysteriously disappear in such cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

2 participants