cmd/go: clear GOPATH from build context when importing from module

In module mode, we shouldn't handle packages under GOPATH any
differently from other packages. Clear GOPATH from the build context
before Importing to ensure that.

Fixes #37015.

Change-Id: I0203e25013716bca346fd4a67d80f1d05bbaea77
Reviewed-on: https://go-review.googlesource.com/c/go/+/412476
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Bryan Mills <bcmills@google.com>
This commit is contained in:
Michael Matloob 2022-06-15 14:24:12 -04:00 committed by Gopher Robot
parent 0857633f8b
commit 73c38f226e
4 changed files with 41 additions and 46 deletions

View file

@ -47,6 +47,17 @@ Do not send CLs removing the interior tags from such phrases.
TODO: <a href="https://go.dev/issue/45454">https://go.dev/issue/45454</a>: provide build tags for architecture environment variables
</p>
<p><!-- https://go.dev/issue/37015 -->
When the main module is located within <code>GOPATH/src</code>,
<code>go</code> <code>install</code> no longer installs libraries for
non-<code>main</code> packages to <code>GOPATH/pkg</code>,
and <code>go</code> <code>list</code> no longer reports a <code>Target</code>
field for such packages. (In module mode, compiled packages are stored in the
<a href="https://pkg.go.dev/cmd/go#hdr-Build_and_test_caching">build cache</a>
only, but <a href="https://go.dev/issue/37015">a bug</a> had caused
the <code>GOPATH</code> install targets to unexpectedly remain in effect.)
</p>
<h3 id="vet">Vet</h3>
<p><!-- https://go.dev/issue/48801, CL 354010 -->

View file

@ -873,8 +873,11 @@ func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoo
var data packageData
if r.dir != "" {
var buildMode build.ImportMode
buildContext := cfg.BuildContext
if !cfg.ModulesEnabled {
buildMode = build.ImportComment
} else {
buildContext.GOPATH = "" // Clear GOPATH so packages are imported as pure module packages
}
modroot := modload.PackageModRoot(ctx, r.path)
if modroot == "" && str.HasPathPrefix(r.dir, cfg.GOROOTsrc) {
@ -891,7 +894,7 @@ func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoo
base.Fatalf("go: %v", err)
}
}
data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
data.p, data.err = buildContext.ImportDir(r.dir, buildMode)
Happy:
if cfg.ModulesEnabled {
// Override data.p.Root, since ImportDir sets it to $GOPATH, if

View file

@ -399,11 +399,7 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
// In build.go, p.Root should only be set in the non-local-import case, or in
// GOROOT or GOPATH. Since module mode only calls Import with path set to "."
// and the module index doesn't apply outside modules, the GOROOT case is
// the only case where GOROOT needs to be set.
// But: p.Root is actually set in the local-import case outside GOROOT, if
// the directory is contained in GOPATH/src
// TODO(#37015): fix that behavior in go/build and remove the gopath case
// below.
// the only case where p.Root needs to be set.
if ctxt.GOROOT != "" && str.HasFilePathPrefix(p.Dir, cfg.GOROOTsrc) && p.Dir != cfg.GOROOTsrc {
p.Root = ctxt.GOROOT
p.Goroot = true
@ -412,47 +408,32 @@ func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *b
if modprefix != "" {
p.ImportPath = filepath.Join(modprefix, p.ImportPath)
}
}
for _, root := range ctxt.gopath() {
// TODO(matloob): do we need to reimplement the conflictdir logic?
// TODO(matloob): ctxt.hasSubdir evaluates symlinks, so it
// can be slower than we'd like. Find out if we can drop this
// logic before the release.
if sub, ok := ctxt.hasSubdir(filepath.Join(root, "src"), p.Dir); ok {
p.ImportPath = sub
p.Root = root
// Set GOROOT-specific fields (sometimes for modules in a GOPATH directory).
// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
// are only set in build.Import if p.Root != "".
var pkgtargetroot string
var pkga string
suffix := ""
if ctxt.InstallSuffix != "" {
suffix = "_" + ctxt.InstallSuffix
}
switch ctxt.Compiler {
case "gccgo":
pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
dir, elem := path.Split(p.ImportPath)
pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
case "gc":
pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
}
p.SrcRoot = ctxt.joinPath(p.Root, "src")
p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
p.BinDir = ctxt.joinPath(p.Root, "bin")
if pkga != "" {
p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
p.PkgObj = ctxt.joinPath(p.Root, pkga)
}
}
}
if p.Root != "" {
// Set GOROOT-specific fields (sometimes for modules in a GOPATH directory).
// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
// are only set in build.Import if p.Root != "". As noted in the comment
// on setting p.Root above, p.Root should only be set in the GOROOT case for the
// set of packages we care about, but is also set for modules in a GOPATH src
// directory.
var pkgtargetroot string
var pkga string
suffix := ""
if ctxt.InstallSuffix != "" {
suffix = "_" + ctxt.InstallSuffix
}
switch ctxt.Compiler {
case "gccgo":
pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
dir, elem := path.Split(p.ImportPath)
pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
case "gc":
pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
}
p.SrcRoot = ctxt.joinPath(p.Root, "src")
p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
p.BinDir = ctxt.joinPath(p.Root, "bin")
if pkga != "" {
p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
p.PkgObj = ctxt.joinPath(p.Root, pkga)
}
}

View file

@ -27,7 +27,7 @@ cmp go.mod go.mod.orig
! go list -mod=vendor all
! stderr '^go: inconsistent vendoring'
stderr 'cannot find package "vendor/example.com/badedit" in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$'
stderr 'cannot find package "." in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$'
# When we set -mod=mod, the go version should be updated immediately,
# to the current version, converting the requirements from eager to lazy.