]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: attach PGO profile for test dependencies
authorCherry Mui <cherryyz@google.com>
Tue, 18 Jul 2023 20:23:27 +0000 (16:23 -0400)
committerCherry Mui <cherryyz@google.com>
Thu, 20 Jul 2023 19:59:18 +0000 (19:59 +0000)
When running "go test" including a main package which has a PGO
profile, we currently build the package being tested and its
dependencies with PGO, but we failed to attach the profile to
test-only dependencies. If a package is (transitively) imported
by both the package being tested and the test, the PGO version
and the non-PGO version of the package are both linked into the
binary, causing link-time error.

This CL fixes this by attaching the PGO profile to dependencies of
the test.

Fixes #61376.

Change-Id: I2559db9843c4cdab596b31e2025d8475ffbf58ec
Reviewed-on: https://go-review.googlesource.com/c/go/+/510835
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/internal/load/test.go
src/cmd/go/testdata/script/build_pgo_auto_multi.txt

index ceedb99e2f1e3a19c40abcf8a978e2fec26c5740..e9ed0d332bc64e1723f010f75841fbeb3695167a 100644 (file)
@@ -473,6 +473,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) *PackageError {
                        p.Target = ""
                        p.Internal.BuildInfo = nil
                        p.Internal.ForceLibrary = true
+                       p.Internal.PGOProfile = preal.Internal.PGOProfile
                }
 
                // Update p.Internal.Imports to use test copies.
@@ -496,6 +497,11 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) *PackageError {
                if p.Name == "main" && p != pmain && p != ptest {
                        split()
                }
+               // Split and attach PGO information to test dependencies if preal
+               // is built with PGO.
+               if preal.Internal.PGOProfile != "" && p.Internal.PGOProfile == "" {
+                       split()
+               }
        }
 
        // Do search to find cycle.
index 9ac57ce0c164ad15256c57178d0dcd927fcd2f2a..991b72ce850b92304d9f000b92d9d5c0e063c09e 100644 (file)
@@ -45,6 +45,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'
 
+# test-only dependencies also have profiles attached
+stderr 'compile.*-pgoprofile=.*a(/|\\\\)default\.pgo.*testdep(/|\\\\)testdep\.go'
+stderr 'compile.*-pgoprofile=.*b(/|\\\\)default\.pgo.*testdep(/|\\\\)testdep\.go'
+stderr 'compile.*-pgoprofile=.*a(/|\\\\)default\.pgo.*testdep2(/|\\\\)testdep2\.go'
+stderr 'compile.*-pgoprofile=.*b(/|\\\\)default\.pgo.*testdep2(/|\\\\)testdep2\.go'
+
 # go list -deps prints packages built multiple times.
 go list -pgo=auto -deps ./a ./b ./nopgo
 stdout 'test/dep \[test/a\]'
@@ -66,6 +72,7 @@ func main() {}
 -- a/a_test.go --
 package main
 import "testing"
+import _ "test/testdep"
 func TestA(*testing.T) {}
 -- a/default.pgo --
 -- b/b.go --
@@ -76,6 +83,7 @@ func main() {}
 -- b/b_test.go --
 package main
 import "testing"
+import _ "test/testdep"
 func TestB(*testing.T) {}
 -- b/default.pgo --
 -- nopgo/nopgo.go --
@@ -94,3 +102,8 @@ import _ "test/dep3"
 package dep2
 -- dep3/dep3.go --
 package dep3
+-- testdep/testdep.go --
+package testdep
+import _ "test/testdep2"
+-- testdep2/testdep2.go --
+package testdep2