aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/load/pkg.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2023-08-23 16:32:46 -0400
committerGopher Robot <gobot@golang.org>2023-08-23 21:55:28 +0000
commit079dfdcac0448168e22a72baa61b9ab5de8ce54e (patch)
tree2154a8a4b0f68ddfc8be062c284c6daf0bb5965e /src/cmd/go/internal/load/pkg.go
parent2763146099384e320e2d1c0fc41b3b3906050652 (diff)
downloadgo-079dfdcac0448168e22a72baa61b9ab5de8ce54e.tar.gz
go-079dfdcac0448168e22a72baa61b9ab5de8ce54e.zip
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>
Diffstat (limited to 'src/cmd/go/internal/load/pkg.go')
-rw-r--r--src/cmd/go/internal/load/pkg.go49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 0abc09186d..1adc9220ba 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -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,