From 4255b78c7da08170321a166d540dfc2c4cfd2ac5 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Tue, 27 Oct 2015 13:36:11 +1300 Subject: [PATCH] cmd/go: handle linking against a shared library that implicitly includes a package If you say "go install -buildmode=shared a b" and package a depends on another package c, package c is implicitly included in the resulting shared library (as specified by "Go Execution Modes"). But if c depends on b, linking against this shared library hangs, because the go tool doesn't know when computing c's dependencies that c is part of the same shared library as c. Fix this by tracking the shared library a package *is* in separately from the shared library a package has been explicitly linked into. Fixes #13044 Change-Id: Iacfedab24ae9731ed53d225678b447a2a888823c Reviewed-on: https://go-review.googlesource.com/16338 Run-TryBot: Michael Hudson-Doyle TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/go/build.go | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index 7e48c17f6c..4c832d38d3 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -835,15 +835,17 @@ func readpkglist(shlibpath string) (pkgs []*Package) { // action returns the action for applying the given operation (mode) to the package. // depMode is the action to use when building dependencies. -// action never looks for p in a shared library. +// action never looks for p in a shared library, but may find p's dependencies in a +// shared library if buildLinkshared is true. func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action { - return b.action1(mode, depMode, p, false) + return b.action1(mode, depMode, p, false, "") } // action1 returns the action for applying the given operation (mode) to the package. // depMode is the action to use when building dependencies. // action1 will look for p in a shared library if lookshared is true. -func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool) *action { +// forShlib is the shared library that p will become part of, if any. +func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool, forShlib string) *action { shlib := "" if lookshared { shlib = p.Shlib @@ -875,13 +877,23 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha b.actionCache[key] = a for _, p1 := range p.imports { - ls := buildLinkshared - // If p1 is part of the same shared library as p, we need the action - // that builds p here, not the shared libary or we get action loops. - if p1.Shlib == p.Shlib { - ls = false + if forShlib != "" { + // p is part of a shared library. + if p1.Shlib != "" && p1.Shlib != forShlib { + // p1 is explicitly part of a different shared library. + // Put the action for that shared library into a.deps. + a.deps = append(a.deps, b.action1(depMode, depMode, p1, true, p1.Shlib)) + } else { + // p1 is (implicitly or not) part of this shared library. + // Put the action for p1 into a.deps. + a.deps = append(a.deps, b.action1(depMode, depMode, p1, false, forShlib)) + } + } else { + // p is not part of a shared library. + // If p1 is in a shared library, put the action for that into + // a.deps, otherwise put the action for p1 into a.deps. + a.deps = append(a.deps, b.action1(depMode, depMode, p1, buildLinkshared, p1.Shlib)) } - a.deps = append(a.deps, b.action1(depMode, depMode, p1, ls)) } // If we are not doing a cross-build, then record the binary we'll @@ -937,7 +949,7 @@ func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, looksha switch mode { case modeInstall: a.f = (*builder).install - a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared)} + a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared, forShlib)} a.target = a.p.target // Install header for cgo in c-archive and c-shared modes. @@ -1079,7 +1091,7 @@ func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode build if err != nil || lstat.ModTime().After(built) { stale = true } - a.deps = append(a.deps, b.action(depMode, depMode, p)) + a.deps = append(a.deps, b.action1(depMode, depMode, p, false, a.target)) } if stale { -- 2.48.1