mirror of
https://github.com/golang/go
synced 2024-11-18 22:44:48 -07:00
cmd/go: error out of linking package main if cgo is required but not enabled
Fixes #46330. Fixes #62123. Updates #31544. Change-Id: I023aa2bdb5a24e126a0de5192a077e8cf1a0a67c Reviewed-on: https://go-review.googlesource.com/c/go/+/522239 Run-TryBot: Bryan Mills <bcmills@google.com> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
2763146099
commit
079dfdcac0
@ -1920,7 +1920,12 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
|
||||
|
||||
// The linker loads implicit dependencies.
|
||||
if p.Name == "main" && !p.Internal.ForceLibrary {
|
||||
for _, dep := range LinkerDeps(p) {
|
||||
ldDeps, err := LinkerDeps(p)
|
||||
if err != nil {
|
||||
setError(err)
|
||||
return
|
||||
}
|
||||
for _, dep := range ldDeps {
|
||||
addImport(dep, false)
|
||||
}
|
||||
}
|
||||
@ -2556,12 +2561,15 @@ func SafeArg(name string) bool {
|
||||
}
|
||||
|
||||
// LinkerDeps returns the list of linker-induced dependencies for main package p.
|
||||
func LinkerDeps(p *Package) []string {
|
||||
func LinkerDeps(p *Package) ([]string, error) {
|
||||
// Everything links runtime.
|
||||
deps := []string{"runtime"}
|
||||
|
||||
// External linking mode forces an import of runtime/cgo.
|
||||
if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
|
||||
if what := externalLinkingReason(p); what != "" && cfg.BuildContext.Compiler != "gccgo" {
|
||||
if !cfg.BuildContext.CgoEnabled {
|
||||
return nil, fmt.Errorf("%s requires external (cgo) linking, but cgo is not enabled", what)
|
||||
}
|
||||
deps = append(deps, "runtime/cgo")
|
||||
}
|
||||
// On ARM with GOARM=5, it forces an import of math, for soft floating point.
|
||||
@ -2585,30 +2593,27 @@ func LinkerDeps(p *Package) []string {
|
||||
deps = append(deps, "runtime/coverage")
|
||||
}
|
||||
|
||||
return deps
|
||||
return deps, nil
|
||||
}
|
||||
|
||||
// externalLinkingForced reports whether external linking is being
|
||||
// forced even for programs that do not use cgo.
|
||||
func externalLinkingForced(p *Package) bool {
|
||||
if !cfg.BuildContext.CgoEnabled {
|
||||
return false
|
||||
}
|
||||
|
||||
// externalLinkingForced reports the reason external linking is required
|
||||
// even for programs that do not use cgo, or the empty string if external
|
||||
// linking is not required.
|
||||
func externalLinkingReason(p *Package) (what string) {
|
||||
// Some targets must use external linking even inside GOROOT.
|
||||
if platform.MustLinkExternal(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH, false) {
|
||||
return true
|
||||
if platform.MustLinkExternal(cfg.Goos, cfg.Goarch, false) {
|
||||
return cfg.Goos + "/" + cfg.Goarch
|
||||
}
|
||||
|
||||
// Some build modes always require external linking.
|
||||
switch cfg.BuildBuildmode {
|
||||
case "c-shared", "plugin":
|
||||
return true
|
||||
return "-buildmode=" + cfg.BuildBuildmode
|
||||
}
|
||||
|
||||
// Using -linkshared always requires external linking.
|
||||
if cfg.BuildLinkshared {
|
||||
return true
|
||||
return "-linkshared"
|
||||
}
|
||||
|
||||
// Decide whether we are building a PIE,
|
||||
@ -2623,27 +2628,29 @@ func externalLinkingForced(p *Package) bool {
|
||||
// that does not support PIE with internal linking mode,
|
||||
// then we must use external linking.
|
||||
if isPIE && !platform.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH) {
|
||||
return true
|
||||
if cfg.BuildBuildmode == "pie" {
|
||||
return "-buildmode=pie"
|
||||
}
|
||||
return "default PIE binary"
|
||||
}
|
||||
|
||||
// Using -ldflags=-linkmode=external forces external linking.
|
||||
// If there are multiple -linkmode options, the last one wins.
|
||||
linkmodeExternal := false
|
||||
if p != nil {
|
||||
ldflags := BuildLdflags.For(p)
|
||||
for i := len(ldflags) - 1; i >= 0; i-- {
|
||||
a := ldflags[i]
|
||||
if a == "-linkmode=external" ||
|
||||
a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
|
||||
linkmodeExternal = true
|
||||
break
|
||||
return a
|
||||
} else if a == "-linkmode=internal" ||
|
||||
a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
|
||||
break
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
return linkmodeExternal
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// mkAbs rewrites list, which must be paths relative to p.Dir,
|
||||
|
@ -298,7 +298,11 @@ func TestPackagesAndErrors(ctx context.Context, done func(), opts PackageOpts, p
|
||||
// Also the linker introduces implicit dependencies reported by LinkerDeps.
|
||||
stk.Push("testmain")
|
||||
deps := TestMainDeps // cap==len, so safe for append
|
||||
for _, d := range LinkerDeps(p) {
|
||||
ldDeps, err := LinkerDeps(p)
|
||||
if err != nil && pmain.Error == nil {
|
||||
pmain.Error = &PackageError{Err: err}
|
||||
}
|
||||
for _, d := range ldDeps {
|
||||
deps = append(deps, d)
|
||||
}
|
||||
for _, dep := range deps {
|
||||
|
@ -853,7 +853,11 @@ func (b *Builder) linkSharedAction(mode, depMode BuildMode, shlib string, a1 *Ac
|
||||
|
||||
// The linker step still needs all the usual linker deps.
|
||||
// (For example, the linker always opens runtime.a.)
|
||||
for _, dep := range load.LinkerDeps(nil) {
|
||||
ldDeps, err := load.LinkerDeps(nil)
|
||||
if err != nil {
|
||||
base.Error(err)
|
||||
}
|
||||
for _, dep := range ldDeps {
|
||||
add(a, dep, true)
|
||||
}
|
||||
}
|
||||
|
19
src/cmd/go/testdata/script/test_android_issue62123.txt
vendored
Normal file
19
src/cmd/go/testdata/script/test_android_issue62123.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
env GOOS=android GOARCH=amd64 CGO_ENABLED=0
|
||||
|
||||
! go build -o $devnull cmd/buildid
|
||||
stderr 'android/amd64 requires external \(cgo\) linking, but cgo is not enabled'
|
||||
! stderr 'cannot find runtime/cgo'
|
||||
|
||||
! go test -c -o $devnull os
|
||||
stderr '# os\nandroid/amd64 requires external \(cgo\) linking, but cgo is not enabled'
|
||||
! stderr 'cannot find runtime/cgo'
|
||||
|
||||
env GOOS=ios GOARCH=arm64 CGO_ENABLED=0
|
||||
|
||||
! go build -o $devnull cmd/buildid
|
||||
stderr 'ios/arm64 requires external \(cgo\) linking, but cgo is not enabled'
|
||||
! stderr 'cannot find runtime/cgo'
|
||||
|
||||
! go test -c -o $devnull os
|
||||
stderr '# os\nios/arm64 requires external \(cgo\) linking, but cgo is not enabled'
|
||||
! stderr 'cannot find runtime/cgo'
|
Loading…
Reference in New Issue
Block a user