golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.23k stars 17.7k forks source link

`cmd/go`: missing diagnostic when the default `GOPATH` conflicts with an explicit `GOROOT` #60492

Open mejedi opened 1 year ago

mejedi commented 1 year ago

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

$ go version
go version go1.20.4 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/nickz/.cache/go-build"
GOENV="/home/nickz/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/nickz/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/nickz/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/nickz/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/nickz/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.4"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/test/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build373437021=/tmp/go-build -gno-record-gcc-switches"

What did you do?

It used to be possible to have go run inside //go:generate lines. It is very handy since a project can require the specific generator version via go.mod.

Following examples by cilium/ebpf, I created a main.go file

package main

import (
    _ "github.com/cilium/ebpf"
)

//go:generate go run github.com/cilium/ebpf/cmd/bpf2go

...and invoked go generate ./....

(I'm using a specific generator in my bug report, but it looks like a generic issue affecting anyone using go run inside go:generate technique. Therefore I believe that the specific generator being used is irrelevant.)

What did you expect to see?

The generator to complain about missing arguments.

What did you see instead?

$ go generate ./...
go: module cache not found: neither GOMODCACHE nor GOPATH is set
cmd/test/main.go:10: running "env": exit status 1

Further info

If I invoke go run directly, everything works as expected.

$ go run github.com/cilium/ebpf/cmd/bpf2go
Error: missing package, are you running via go generate?
exit status 1

$ GOPACKAGE=main go run github.com/cilium/ebpf/cmd/bpf2go
Error: expected at least two arguments
exit status 1

It's clear that the generator gets executed and complains as expected.

However, if I set GOROOT (as go generate does):

$ GOROOT=/home/nickz/go GOPACKAGE=main go run github.com/cilium/ebpf/cmd/bpf2go
go: module cache not found: neither GOMODCACHE nor GOPATH is set

Changing go:generate line as below also "fixes" the problem:

//go:generate env --unset=GOROOT go run github.com/cilium/ebpf/cmd/bpf2go
$ go generate ./...
Error: expected at least two arguments
exit status 1

I believe that I have the most boring go setup possible. $ env | grep GO yields nothing.

seankhliao commented 1 year ago

how did you end up with GOROOT == GOPATH? what's in /home/nickz/.config/go/env?

mejedi commented 1 year ago

@seankhliao

how did you end up with GOROOT == GOPATH?

By unpacking the tarball into ~/go. Is it not supposed to work?

$ which go
/home/nickz/go/bin/go

The config file doesn't exist.

I can confirm that the issue goes away when GOROOT != GOPATH.

seankhliao commented 1 year ago

That's perhaps the only place where it doesn't work. GOROOT == place where go is installed needs to be different from GOPATH == place where it places some user data

I don't think we recommend doing what you did anywhere?

mejedi commented 1 year ago

I don’t think “first party” resources suggest doing what I did. There might have been some third party ones, at least some years back when I did the setup.

It would be nice if the toolchain plain rejected this invalid setup rather than breaking in subtle ways.

Otherwise, please feel free to close. Thank you very much for the help!

bcmills commented 1 year ago

It would be nice if the toolchain plain rejected this invalid setup rather than breaking in subtle ways.

It is supposed to: https://cs.opensource.google/go/go/+/master:src/cmd/go/main.go;l=121;drc=44e51e60acb8a1ff6ba10d698615fde98b2b28b0

However, that warning has no effect if GOPATH is not set explicitly: https://cs.opensource.google/go/go/+/master:src/go/build/build.go;l=298-302;drc=d22f287f12f4782082cd93785ad91e78dbe0d4d6

It looks like the attempt to improve the error message in https://go.dev/cl/331529 was incomplete. It should probably be extended to more places.

gopherbot commented 1 year ago

Change https://go.dev/cl/538738 mentions this issue: cmd/go: return a warning if GOROOT is the same as default GOPATH