aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Conrod <jayconrod@google.com>2019-03-01 17:20:28 -0500
committerBryan C. Mills <bcmills@google.com>2019-03-13 19:48:23 +0000
commita40b76a40c024fb018045d1d2fd94f9e7b186a15 (patch)
treeb2610f212b99e6119bb28f13b06ae6e92545c3b2
parent7e880151b1763ebe608d7c2cadf36b71f184332a (diff)
downloadgo-a40b76a40c024fb018045d1d2fd94f9e7b186a15.tar.gz
go-a40b76a40c024fb018045d1d2fd94f9e7b186a15.zip
[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 <jayconrod@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com> (cherry picked from commit 10156b678336f7628a7f1fdd84ffe2a28d66969a) Reviewed-on: https://go-review.googlesource.com/c/go/+/166318 TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/go/internal/load/test.go10
-rw-r--r--src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt37
2 files changed, 47 insertions, 0 deletions
diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go
index bd6f00bb66..6293aea3c3 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -129,6 +129,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
ptest.Internal.Imports = append(imports, p.Internal.Imports...)
ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
ptest.Internal.ForceLibrary = true
+ ptest.Internal.BuildInfo = ""
ptest.Internal.Build = new(build.Package)
*ptest.Internal.Build = *p.Internal.Build
m := map[string][]token.Position{}
@@ -186,6 +187,7 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag
},
Internal: PackageInternal{
Build: &build.Package{Name: "main"},
+ BuildInfo: p.Internal.BuildInfo,
Asmflags: p.Internal.Asmflags,
Gcflags: p.Internal.Gcflags,
Ldflags: p.Internal.Ldflags,
@@ -352,6 +354,7 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
copy(p1.Imports, p.Imports)
p = p1
p.Target = ""
+ p.Internal.BuildInfo = ""
}
// Update p.Internal.Imports to use test copies.
@@ -361,6 +364,13 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) {
p.Internal.Imports[i] = p1
}
}
+
+ // Don't compile build info from a main package. This can happen
+ // if -coverpkg patterns include main packages, since those packages
+ // are imported by pmain.
+ if p.Internal.BuildInfo != "" && p != pmain {
+ split()
+ }
}
}
diff --git a/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
new file mode 100644
index 0000000000..8ee4848d0a
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt
@@ -0,0 +1,37 @@
+# This test checks that multiple main packages can be tested
+# with -coverpkg=all without duplicate symbol errors.
+# Verifies golang.org/issue/30374.
+
+env GO111MODULE=on
+
+[short] skip
+
+go test -coverpkg=all ./main1 ./main2
+
+-- go.mod --
+module example.com/cov
+
+-- main1/main1.go --
+package main
+
+func main() {}
+
+-- main1/main1_test.go --
+package main
+
+import "testing"
+
+func TestMain1(t *testing.T) {}
+
+-- main2/main2.go --
+package main
+
+func main() {}
+
+-- main2/main2_test.go --
+package main
+
+import "testing"
+
+func TestMain2(t *testing.T) {}
+