Skip to content

Commit a40b76a

Browse files
Jay ConrodBryan C. Mills
Jay Conrod
authored and
Bryan C. Mills
committed
[release-branch.go1.12] cmd/go: avoid link errors when -coverpkg covers main packages
The -coverpkg lets users specify a list of packages that should have coverage instrumentation. This may include packages not transitively imported by tests. For each tested package, the synthetic main package imports all covered packages so they can be registered with testing.RegisterCover. This makes it possible for a main package to import another main package. When we compile a package with p.Internal.BuildInfo set (set on main packages by Package.load in module mode), we set runtime/debug.modinfo. Multiple main packages may be passed to the linker because of the above scenario, so this causes duplicate symbol errors. This change copies p.Internal.BuildInfo to the synthetic main package instead of the internal test package. Additionally, it forces main packages imported by the synthetic test main package to be recompiled for testing. Recompiled packages won't have p.Internal.BuildInfo set. Fixes #30684 Change-Id: I06f028d55905039907940ec89d2835f5a1040203 Reviewed-on: https://go-review.googlesource.com/c/go/+/164877 Run-TryBot: Jay Conrod <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> (cherry picked from commit 10156b6) Reviewed-on: https://go-review.googlesource.com/c/go/+/166318 TryBot-Result: Gobot Gobot <[email protected]>
1 parent 7e88015 commit a40b76a

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/cmd/go/internal/load/test.go

+10
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
129129
ptest.Internal.Imports = append(imports, p.Internal.Imports...)
130130
ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
131131
ptest.Internal.ForceLibrary = true
132+
ptest.Internal.BuildInfo = ""
132133
ptest.Internal.Build = new(build.Package)
133134
*ptest.Internal.Build = *p.Internal.Build
134135
m := map[string][]token.Position{}
@@ -186,6 +187,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
186187
},
187188
Internal: PackageInternal{
188189
Build: &build.Package{Name: "main"},
190+
BuildInfo: p.Internal.BuildInfo,
189191
Asmflags: p.Internal.Asmflags,
190192
Gcflags: p.Internal.Gcflags,
191193
Ldflags: p.Internal.Ldflags,
@@ -352,6 +354,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
352354
copy(p1.Imports, p.Imports)
353355
p = p1
354356
p.Target = ""
357+
p.Internal.BuildInfo = ""
355358
}
356359

357360
// Update p.Internal.Imports to use test copies.
@@ -361,6 +364,13 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
361364
p.Internal.Imports[i] = p1
362365
}
363366
}
367+
368+
// Don't compile build info from a main package. This can happen
369+
// if -coverpkg patterns include main packages, since those packages
370+
// are imported by pmain.
371+
if p.Internal.BuildInfo != "" && p != pmain {
372+
split()
373+
}
364374
}
365375
}
366376

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This test checks that multiple main packages can be tested
2+
# with -coverpkg=all without duplicate symbol errors.
3+
# Verifies golang.org/issue/30374.
4+
5+
env GO111MODULE=on
6+
7+
[short] skip
8+
9+
go test -coverpkg=all ./main1 ./main2
10+
11+
-- go.mod --
12+
module example.com/cov
13+
14+
-- main1/main1.go --
15+
package main
16+
17+
func main() {}
18+
19+
-- main1/main1_test.go --
20+
package main
21+
22+
import "testing"
23+
24+
func TestMain1(t *testing.T) {}
25+
26+
-- main2/main2.go --
27+
package main
28+
29+
func main() {}
30+
31+
-- main2/main2_test.go --
32+
package main
33+
34+
import "testing"
35+
36+
func TestMain2(t *testing.T) {}
37+

0 commit comments

Comments
 (0)