mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/dist: refactor generated cgo-support logic
During bootstrapping, cmd/dist writes a file indicating which GOOS/GOARCH combinations are valid, and which support cgo-enabled builds. That information previously went into the go/build package, but today it fits in more naturally in the internal/platform package (which already has a number of functions indicating feature support for GOOS/GOARCH combinations). Moreover, as of CL 450739 the cmd/go logic for determining whether to use cgo is somewhat more nuanced than the go/build logic: cmd/go checks for the presence of a C compiler, whereas go/build does not (mostly because it determines its configuration at package-init time, and checking $PATH for a C compiler is somewhat expensive). To simplify this situation, this change: - consolidates the “cgo supported” check in internal/platform (alongside many other platform-support checks) instead of making it a one-off in go/build, - and updates a couple of tests to use testenv.HasCGO instead of build.Default.CgoEnabled to decide whether to test a cgo-specific behavior. For #58884. For #59500. Change-Id: I0bb2502dba4545a3d98c9e915727382ce536a0f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/483695 Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
0d699b6cb3
commit
d22f287f12
1
.gitignore
vendored
1
.gitignore
vendored
@ -38,6 +38,7 @@ _testmain.go
|
|||||||
/src/go/build/zcgo.go
|
/src/go/build/zcgo.go
|
||||||
/src/go/doc/headscan
|
/src/go/doc/headscan
|
||||||
/src/internal/buildcfg/zbootstrap.go
|
/src/internal/buildcfg/zbootstrap.go
|
||||||
|
/src/internal/platform/zosarch.go
|
||||||
/src/runtime/internal/sys/zversion.go
|
/src/runtime/internal/sys/zversion.go
|
||||||
/src/unicode/maketables
|
/src/unicode/maketables
|
||||||
/src/time/tzdata/zzipdata.go
|
/src/time/tzdata/zzipdata.go
|
||||||
|
11
src/cmd/dist/build.go
vendored
11
src/cmd/dist/build.go
vendored
@ -626,14 +626,16 @@ var deptab = []struct {
|
|||||||
}{
|
}{
|
||||||
{"cmd/go/internal/cfg", []string{
|
{"cmd/go/internal/cfg", []string{
|
||||||
"zdefaultcc.go",
|
"zdefaultcc.go",
|
||||||
|
}},
|
||||||
|
{"go/build", []string{
|
||||||
|
"zcgo.go",
|
||||||
|
}},
|
||||||
|
{"internal/platform", []string{
|
||||||
"zosarch.go",
|
"zosarch.go",
|
||||||
}},
|
}},
|
||||||
{"runtime/internal/sys", []string{
|
{"runtime/internal/sys", []string{
|
||||||
"zversion.go",
|
"zversion.go",
|
||||||
}},
|
}},
|
||||||
{"go/build", []string{
|
|
||||||
"zcgo.go",
|
|
||||||
}},
|
|
||||||
{"time/tzdata", []string{
|
{"time/tzdata", []string{
|
||||||
"zzipdata.go",
|
"zzipdata.go",
|
||||||
}},
|
}},
|
||||||
@ -650,10 +652,10 @@ var gentab = []struct {
|
|||||||
nameprefix string
|
nameprefix string
|
||||||
gen func(string, string)
|
gen func(string, string)
|
||||||
}{
|
}{
|
||||||
|
{"zcgo.go", mkzcgo},
|
||||||
{"zdefaultcc.go", mkzdefaultcc},
|
{"zdefaultcc.go", mkzdefaultcc},
|
||||||
{"zosarch.go", mkzosarch},
|
{"zosarch.go", mkzosarch},
|
||||||
{"zversion.go", mkzversion},
|
{"zversion.go", mkzversion},
|
||||||
{"zcgo.go", mkzcgo},
|
|
||||||
{"zzipdata.go", mktzdata},
|
{"zzipdata.go", mktzdata},
|
||||||
|
|
||||||
// not generated anymore, but delete the file if we see it
|
// not generated anymore, but delete the file if we see it
|
||||||
@ -1196,6 +1198,7 @@ var cleanlist = []string{
|
|||||||
"runtime/internal/sys",
|
"runtime/internal/sys",
|
||||||
"cmd/cgo",
|
"cmd/cgo",
|
||||||
"cmd/go/internal/cfg",
|
"cmd/go/internal/cfg",
|
||||||
|
"internal/platform",
|
||||||
"go/build",
|
"go/build",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
38
src/cmd/dist/buildgo.go
vendored
38
src/cmd/dist/buildgo.go
vendored
@ -91,55 +91,19 @@ func defaultCCFunc(name string, defaultcc map[string]string) string {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkzosarch writes zosarch.go for cmd/go.
|
|
||||||
func mkzosarch(dir, file string) {
|
|
||||||
// sort for deterministic zosarch.go file
|
|
||||||
var list []string
|
|
||||||
for plat := range cgoEnabled {
|
|
||||||
list = append(list, plat)
|
|
||||||
}
|
|
||||||
sort.Strings(list)
|
|
||||||
|
|
||||||
var buf strings.Builder
|
|
||||||
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n\n")
|
|
||||||
fmt.Fprintf(&buf, "package cfg\n\n")
|
|
||||||
fmt.Fprintf(&buf, "var OSArchSupportsCgo = map[string]bool{\n")
|
|
||||||
for _, plat := range list {
|
|
||||||
fmt.Fprintf(&buf, "\t%s: %v,\n", quote(plat), cgoEnabled[plat])
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&buf, "}\n")
|
|
||||||
|
|
||||||
writefile(buf.String(), file, writeSkipSame)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mkzcgo writes zcgo.go for the go/build package:
|
// mkzcgo writes zcgo.go for the go/build package:
|
||||||
//
|
//
|
||||||
// package build
|
// package build
|
||||||
// var cgoEnabled = map[string]bool{}
|
// const defaultCGO_ENABLED = <CGO_ENABLED>
|
||||||
//
|
//
|
||||||
// It is invoked to write go/build/zcgo.go.
|
// It is invoked to write go/build/zcgo.go.
|
||||||
func mkzcgo(dir, file string) {
|
func mkzcgo(dir, file string) {
|
||||||
// sort for deterministic zcgo.go file
|
|
||||||
var list []string
|
|
||||||
for plat, hasCgo := range cgoEnabled {
|
|
||||||
if hasCgo {
|
|
||||||
list = append(list, plat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Strings(list)
|
|
||||||
|
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
|
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
|
||||||
fmt.Fprintln(&buf)
|
fmt.Fprintln(&buf)
|
||||||
fmt.Fprintf(&buf, "package build\n")
|
fmt.Fprintf(&buf, "package build\n")
|
||||||
fmt.Fprintln(&buf)
|
fmt.Fprintln(&buf)
|
||||||
fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %s\n", quote(os.Getenv("CGO_ENABLED")))
|
fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %s\n", quote(os.Getenv("CGO_ENABLED")))
|
||||||
fmt.Fprintln(&buf)
|
|
||||||
fmt.Fprintf(&buf, "var cgoEnabled = map[string]bool{\n")
|
|
||||||
for _, plat := range list {
|
|
||||||
fmt.Fprintf(&buf, "\t%s: true,\n", quote(plat))
|
|
||||||
}
|
|
||||||
fmt.Fprintf(&buf, "}\n")
|
|
||||||
|
|
||||||
writefile(buf.String(), file, writeSkipSame)
|
writefile(buf.String(), file, writeSkipSame)
|
||||||
}
|
}
|
||||||
|
24
src/cmd/dist/buildruntime.go
vendored
24
src/cmd/dist/buildruntime.go
vendored
@ -6,6 +6,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,3 +83,26 @@ func mkobjabi(file string) {
|
|||||||
|
|
||||||
writefile(buf.String(), file, writeSkipSame)
|
writefile(buf.String(), file, writeSkipSame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mkzosarch writes zosarch.go for internal/platform.
|
||||||
|
func mkzosarch(dir, file string) {
|
||||||
|
// sort for deterministic file contents.
|
||||||
|
var list []string
|
||||||
|
for plat := range cgoEnabled {
|
||||||
|
list = append(list, plat)
|
||||||
|
}
|
||||||
|
sort.Strings(list)
|
||||||
|
|
||||||
|
var buf strings.Builder
|
||||||
|
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
|
||||||
|
fmt.Fprintln(&buf)
|
||||||
|
fmt.Fprintf(&buf, "package platform\n")
|
||||||
|
fmt.Fprintln(&buf)
|
||||||
|
fmt.Fprintf(&buf, "var osArchSupportsCgo = map[string]bool{\n")
|
||||||
|
for _, plat := range list {
|
||||||
|
fmt.Fprintf(&buf, "\t\t%s: %v,\n", quote(plat), cgoEnabled[plat])
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&buf, "}\n")
|
||||||
|
|
||||||
|
writefile(buf.String(), file, writeSkipSame)
|
||||||
|
}
|
||||||
|
1
src/cmd/dist/buildtool.go
vendored
1
src/cmd/dist/buildtool.go
vendored
@ -121,6 +121,7 @@ func bootstrapBuildTools() {
|
|||||||
|
|
||||||
mkbuildcfg(pathf("%s/src/internal/buildcfg/zbootstrap.go", goroot))
|
mkbuildcfg(pathf("%s/src/internal/buildcfg/zbootstrap.go", goroot))
|
||||||
mkobjabi(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
|
mkobjabi(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
|
||||||
|
mkzosarch("", pathf("%s/src/internal/platform/zosarch.go", goroot))
|
||||||
|
|
||||||
// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
|
// Use $GOROOT/pkg/bootstrap as the bootstrap workspace root.
|
||||||
// We use a subdirectory of $GOROOT/pkg because that's the
|
// We use a subdirectory of $GOROOT/pkg because that's the
|
||||||
|
@ -141,6 +141,7 @@ func defaultContext() build.Context {
|
|||||||
// (1) environment, (2) go/env file, (3) runtime constants,
|
// (1) environment, (2) go/env file, (3) runtime constants,
|
||||||
// while go/build.Default.GOOS/GOARCH are derived from the preference list
|
// while go/build.Default.GOOS/GOARCH are derived from the preference list
|
||||||
// (1) environment, (2) runtime constants.
|
// (1) environment, (2) runtime constants.
|
||||||
|
//
|
||||||
// We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH;
|
// We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH;
|
||||||
// no matter how that happened, go/build.Default will make the
|
// no matter how that happened, go/build.Default will make the
|
||||||
// same decision (either the environment variables are set explicitly
|
// same decision (either the environment variables are set explicitly
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"debug/elf"
|
"debug/elf"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"internal/platform"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -355,7 +356,7 @@ func closeBuilders() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CheckGOOSARCHPair(goos, goarch string) error {
|
func CheckGOOSARCHPair(goos, goarch string) error {
|
||||||
if _, ok := cfg.OSArchSupportsCgo[goos+"/"+goarch]; !ok && cfg.BuildContext.Compiler == "gc" {
|
if !platform.BuildModeSupported(cfg.BuildContext.Compiler, "default", goos, goarch) {
|
||||||
return fmt.Errorf("unsupported GOOS/GOARCH pair %s/%s", goos, goarch)
|
return fmt.Errorf("unsupported GOOS/GOARCH pair %s/%s", goos, goarch)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -283,7 +283,7 @@ func buildModeInit() {
|
|||||||
base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
|
base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !platform.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
|
if cfg.BuildBuildmode != "default" && !platform.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
|
||||||
base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
|
base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
package main_test
|
package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go/build"
|
"internal/testenv"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ func TestNoteReading(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case !build.Default.CgoEnabled:
|
case !testenv.HasCGO():
|
||||||
t.Skipf("skipping - no cgo, so assuming external linking not available")
|
t.Skipf("skipping - no cgo, so assuming external linking not available")
|
||||||
case runtime.GOOS == "plan9":
|
case runtime.GOOS == "plan9":
|
||||||
t.Skipf("skipping - external linking not supported")
|
t.Skipf("skipping - external linking not supported")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# go list all should work with GOOS=linux because all packages build on Linux
|
# go list all should work with GOOS=linux because all packages build on Linux
|
||||||
env GOOS=linux
|
env GOOS=linux
|
||||||
|
env GOARCH=amd64
|
||||||
go list all
|
go list all
|
||||||
|
|
||||||
# go list all should work with GOOS=darwin, but it used to fail because
|
# go list all should work with GOOS=darwin, but it used to fail because
|
||||||
|
2
src/cmd/go/testdata/script/tooltags.txt
vendored
2
src/cmd/go/testdata/script/tooltags.txt
vendored
@ -1,3 +1,5 @@
|
|||||||
|
env GOOS=linux
|
||||||
|
|
||||||
env GOARCH=amd64
|
env GOARCH=amd64
|
||||||
env GOAMD64=v3
|
env GOAMD64=v3
|
||||||
go list -f '{{context.ToolTags}}'
|
go list -f '{{context.ToolTags}}'
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"cmd/internal/notsha256"
|
"cmd/internal/notsha256"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
|
||||||
"internal/platform"
|
"internal/platform"
|
||||||
"internal/testenv"
|
"internal/testenv"
|
||||||
"os"
|
"os"
|
||||||
@ -253,7 +252,7 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool,
|
|||||||
func testGoAndCgoDisasm(t *testing.T, printCode bool, printGnuAsm bool) {
|
func testGoAndCgoDisasm(t *testing.T, printCode bool, printGnuAsm bool) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
testDisasm(t, "fmthello.go", printCode, printGnuAsm)
|
testDisasm(t, "fmthello.go", printCode, printGnuAsm)
|
||||||
if build.Default.CgoEnabled {
|
if testenv.HasCGO() {
|
||||||
testDisasm(t, "fmthellocgo.go", printCode, printGnuAsm)
|
testDisasm(t, "fmthellocgo.go", printCode, printGnuAsm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"internal/godebug"
|
"internal/godebug"
|
||||||
"internal/goroot"
|
"internal/goroot"
|
||||||
"internal/goversion"
|
"internal/goversion"
|
||||||
|
"internal/platform"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
@ -345,7 +346,7 @@ func defaultContext() Context {
|
|||||||
default:
|
default:
|
||||||
// cgo must be explicitly enabled for cross compilation builds
|
// cgo must be explicitly enabled for cross compilation builds
|
||||||
if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
|
if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
|
||||||
c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
|
c.CgoEnabled = platform.CgoSupported(c.GOOS, c.GOARCH)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c.CgoEnabled = false
|
c.CgoEnabled = false
|
||||||
|
@ -292,7 +292,7 @@ var depsRules = `
|
|||||||
FMT, internal/goexperiment
|
FMT, internal/goexperiment
|
||||||
< internal/buildcfg;
|
< internal/buildcfg;
|
||||||
|
|
||||||
go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion
|
go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion, internal/platform
|
||||||
< go/build;
|
< go/build;
|
||||||
|
|
||||||
# databases
|
# databases
|
||||||
|
@ -126,6 +126,9 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
platform := goos + "/" + goarch
|
platform := goos + "/" + goarch
|
||||||
|
if _, ok := osArchSupportsCgo[platform]; !ok {
|
||||||
|
return false // platform unrecognized
|
||||||
|
}
|
||||||
|
|
||||||
switch buildmode {
|
switch buildmode {
|
||||||
case "archive":
|
case "archive":
|
||||||
@ -237,3 +240,8 @@ func DefaultPIE(goos, goarch string, isRace bool) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CgoSupported reports whether goos/goarch supports cgo.\n")
|
||||||
|
func CgoSupported(goos, goarch string) bool {
|
||||||
|
return osArchSupportsCgo[goos+"/"+goarch]
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user