Skip to content

Commit b78bce0

Browse files
committed
cmd/go: ignore -linkmode=external during cmd/cgo build
cmd/cgo is special among the build tools because it is (re)built on demand when needed for a package using cgo, to avoid additional bootstrap logic elsewhere. (This is in contrast to cmd/compile, cmd/link, and so on, which must be specially built before even invoking the go command.) When the go command starts using content-based decisions about staleness, it is important that the build of cmd/cgo never use -linkmode=external, because that depends on runtime/cgo, which in turn depends on cmd/cgo. Change-Id: I72a2be748606d1ed4b93a54f2a5c7084e87d5fbc Reviewed-on: https://go-review.googlesource.com/67310 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 3cdf610 commit b78bce0

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/cmd/go/internal/work/build.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2573,12 +2573,23 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg string, allaction
25732573
} else {
25742574
compiler = envList("CC", cfg.DefaultCC)
25752575
}
2576-
ldflags = setextld(ldflags, compiler)
25772576
ldflags = append(ldflags, "-buildmode="+ldBuildmode)
25782577
if root.Package.Internal.BuildID != "" {
25792578
ldflags = append(ldflags, "-buildid="+root.Package.Internal.BuildID)
25802579
}
25812580
ldflags = append(ldflags, cfg.BuildLdflags...)
2581+
if root.Package.Goroot {
2582+
// Cannot force -linkmode=external inside GOROOT.
2583+
// cmd/cgo cannot be linkmode=external,
2584+
// because that implies having runtime/cgo available,
2585+
// and runtime/cgo is built using cmd/cgo.
2586+
// It's possible the restriction can be limited to just cmd/cgo,
2587+
// but the whole-GOROOT prohibition matches the similar
2588+
// logic in ../load/pkg.go that decides whether to add an
2589+
// implicit runtime/cgo dependency.
2590+
ldflags = removeLinkmodeExternal(ldflags)
2591+
}
2592+
ldflags = setextld(ldflags, compiler)
25822593

25832594
// On OS X when using external linking to build a shared library,
25842595
// the argument passed here to -o ends up recorded in the final
@@ -2595,6 +2606,27 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg string, allaction
25952606
return b.run(dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg)
25962607
}
25972608

2609+
// removeLinkmodeExternal removes any attempt to set linkmode=external
2610+
// from ldflags, modifies ldflags in place, and returns ldflags.
2611+
func removeLinkmodeExternal(ldflags []string) []string {
2612+
out := ldflags[:0]
2613+
for i := 0; i < len(ldflags); i++ {
2614+
flag := ldflags[i]
2615+
if strings.HasPrefix(flag, "--") {
2616+
flag = flag[1:]
2617+
}
2618+
if flag == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
2619+
i++
2620+
continue
2621+
}
2622+
if flag == "-linkmode=external" {
2623+
continue
2624+
}
2625+
out = append(out, flag)
2626+
}
2627+
return out
2628+
}
2629+
25982630
func (gcToolchain) ldShared(b *Builder, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
25992631
ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
26002632
ldflags = append(ldflags, "-buildmode=shared")

0 commit comments

Comments
 (0)