1
0
mirror of https://github.com/golang/go synced 2024-11-23 15:40:06 -07:00

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 <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
Cherry Mui 2023-03-02 19:16:34 -05:00
parent 74502e9bb4
commit 34d6aaae29
3 changed files with 16 additions and 4 deletions

View File

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

View File

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

View File

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