From 34d6aaae29023b9edfef2d3360d89e48c8dd118f Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Thu, 2 Mar 2023 19:16:34 -0500 Subject: [PATCH] cmd/go: distinguish packages built for different main packages in printing In -pgo=auto mode, a package may be built multiple times. E.g. for go build -pgo=auto cmd/a cmd/b and both cmd/a and cmd/b imports package p, p may be built twice, one using a's profile, one using b's. If we need to print p, e.g. in "go list -deps" or when there is a build failure, p will be printed twice, and currently we don't distinguish them. We have a precedence for a similar case: for testing, there is the original package, and the (internal) test version of the package (which includes _test.go files). Packages that import the package under testing may also have two versions (one imports the original, one imports the testing version). In printing, the go command distinguishes them by adding a "[p.test]" suffix for the latter, as they are specifically built for the p.test binary. We do the similar. When a package needs to be compiled multiple times for different main packages, we attach the main package's import path, like "p [cmd/a]" for package p built specifically for cmd/a. For #58099. Change-Id: I4a040cf17e1dceb5ca1810c217f16e734c858ab6 Reviewed-on: https://go-review.googlesource.com/c/go/+/473275 Reviewed-by: Michael Pratt TryBot-Result: Gopher Robot Run-TryBot: Cherry Mui Reviewed-by: Bryan Mills --- src/cmd/go/internal/list/list.go | 9 +++++---- src/cmd/go/internal/load/pkg.go | 5 +++++ src/cmd/go/testdata/script/build_pgo_auto_multi.txt | 6 ++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go index 259fa2c857f..6d6deda8846 100644 --- a/src/cmd/go/internal/list/list.go +++ b/src/cmd/go/internal/list/list.go @@ -733,19 +733,20 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { } } - if *listTest { + if *listTest || (cfg.BuildPGO == "auto" && len(cmdline) > 1) { all := pkgs if !*listDeps { all = loadPackageList(pkgs) } // Update import paths to distinguish the real package p - // from p recompiled for q.test. + // from p recompiled for q.test, or to distinguish between + // p compiled with different PGO profiles. // This must happen only once the build code is done // looking at import paths, because it will get very confused // if it sees these. old := make(map[string]string) for _, p := range all { - if p.ForTest != "" { + if p.ForTest != "" || p.Internal.ForMain != "" { new := p.Desc() old[new] = p.ImportPath p.ImportPath = new @@ -756,7 +757,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) { m := make(map[string]string) for _, p := range all { for _, p1 := range p.Internal.Imports { - if p1.ForTest != "" { + if p1.ForTest != "" || p1.Internal.ForMain != "" { m[old[p1.ImportPath]] = p1.ImportPath } } diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go index 62849552289..40278dda4d2 100644 --- a/src/cmd/go/internal/load/pkg.go +++ b/src/cmd/go/internal/load/pkg.go @@ -195,6 +195,9 @@ func (p *Package) Desc() string { if p.ForTest != "" { return p.ImportPath + " [" + p.ForTest + ".test]" } + if p.Internal.ForMain != "" { + return p.ImportPath + " [" + p.Internal.ForMain + "]" + } return p.ImportPath } @@ -234,6 +237,7 @@ type PackageInternal struct { Embed map[string][]string // //go:embed comment mapping OrigImportPath string // original import path before adding '_test' suffix PGOProfile string // path to PGO profile + ForMain string // the main package if this package is built specifically for it Asmflags []string // -asmflags for this package Gcflags []string // -gcflags for this package @@ -2944,6 +2948,7 @@ func setPGOProfilePath(pkgs []*Package) { p1.Internal.Imports = slices.Clone(p.Internal.Imports) copied[p] = p1 p = p1 + p.Internal.ForMain = pmain.ImportPath } p.Internal.PGOProfile = file // Recurse to dependencies. diff --git a/src/cmd/go/testdata/script/build_pgo_auto_multi.txt b/src/cmd/go/testdata/script/build_pgo_auto_multi.txt index 6905ad94f66..19f022838d8 100644 --- a/src/cmd/go/testdata/script/build_pgo_auto_multi.txt +++ b/src/cmd/go/testdata/script/build_pgo_auto_multi.txt @@ -40,6 +40,12 @@ stderr 'compile.*-pgoprofile=.*b(/|\\\\)default\.pgo.*b(/|\\\\)b_test\.go' stderr 'compile.*-pgoprofile=.*b(/|\\\\)default\.pgo.*dep(/|\\\\)dep\.go' ! stderr 'compile.*-pgoprofile=.*nopgo(/|\\\\)nopgo_test\.go' +# go list -deps prints packages built multiple times. +go list -pgo=auto -deps ./a ./b ./nopgo +stdout 'test/dep \[test/a\]' +stdout 'test/dep \[test/b\]' +stdout 'test/dep$' + # Here we have 3 main packages, a, b, and nopgo, where a and b each has # its own default.pgo profile, and nopgo has none. # All 3 main packages import dep and dep2, both of which then import dep3