mirror of
https://github.com/golang/go
synced 2024-11-25 20:57:57 -07: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/doc/headscan
|
||||
/src/internal/buildcfg/zbootstrap.go
|
||||
/src/internal/platform/zosarch.go
|
||||
/src/runtime/internal/sys/zversion.go
|
||||
/src/unicode/maketables
|
||||
/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{
|
||||
"zdefaultcc.go",
|
||||
}},
|
||||
{"go/build", []string{
|
||||
"zcgo.go",
|
||||
}},
|
||||
{"internal/platform", []string{
|
||||
"zosarch.go",
|
||||
}},
|
||||
{"runtime/internal/sys", []string{
|
||||
"zversion.go",
|
||||
}},
|
||||
{"go/build", []string{
|
||||
"zcgo.go",
|
||||
}},
|
||||
{"time/tzdata", []string{
|
||||
"zzipdata.go",
|
||||
}},
|
||||
@ -650,10 +652,10 @@ var gentab = []struct {
|
||||
nameprefix string
|
||||
gen func(string, string)
|
||||
}{
|
||||
{"zcgo.go", mkzcgo},
|
||||
{"zdefaultcc.go", mkzdefaultcc},
|
||||
{"zosarch.go", mkzosarch},
|
||||
{"zversion.go", mkzversion},
|
||||
{"zcgo.go", mkzcgo},
|
||||
{"zzipdata.go", mktzdata},
|
||||
|
||||
// not generated anymore, but delete the file if we see it
|
||||
@ -1196,6 +1198,7 @@ var cleanlist = []string{
|
||||
"runtime/internal/sys",
|
||||
"cmd/cgo",
|
||||
"cmd/go/internal/cfg",
|
||||
"internal/platform",
|
||||
"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()
|
||||
}
|
||||
|
||||
// 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:
|
||||
//
|
||||
// package build
|
||||
// var cgoEnabled = map[string]bool{}
|
||||
// const defaultCGO_ENABLED = <CGO_ENABLED>
|
||||
//
|
||||
// It is invoked to write go/build/zcgo.go.
|
||||
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
|
||||
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
|
||||
fmt.Fprintln(&buf)
|
||||
fmt.Fprintf(&buf, "package build\n")
|
||||
fmt.Fprintln(&buf)
|
||||
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)
|
||||
}
|
||||
|
24
src/cmd/dist/buildruntime.go
vendored
24
src/cmd/dist/buildruntime.go
vendored
@ -6,6 +6,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -82,3 +83,26 @@ func mkobjabi(file string) {
|
||||
|
||||
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))
|
||||
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.
|
||||
// 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,
|
||||
// while go/build.Default.GOOS/GOARCH are derived from the preference list
|
||||
// (1) environment, (2) runtime constants.
|
||||
//
|
||||
// We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH;
|
||||
// no matter how that happened, go/build.Default will make the
|
||||
// same decision (either the environment variables are set explicitly
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"debug/elf"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"internal/platform"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -355,7 +356,7 @@ func closeBuilders() {
|
||||
}
|
||||
|
||||
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 nil
|
||||
|
@ -283,7 +283,7 @@ func buildModeInit() {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
package main_test
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"internal/testenv"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
@ -32,7 +32,7 @@ func TestNoteReading(t *testing.T) {
|
||||
}
|
||||
|
||||
switch {
|
||||
case !build.Default.CgoEnabled:
|
||||
case !testenv.HasCGO():
|
||||
t.Skipf("skipping - no cgo, so assuming external linking not available")
|
||||
case runtime.GOOS == "plan9":
|
||||
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
|
||||
env GOOS=linux
|
||||
env GOARCH=amd64
|
||||
go list all
|
||||
|
||||
# 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 GOAMD64=v3
|
||||
go list -f '{{context.ToolTags}}'
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"cmd/internal/notsha256"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"internal/platform"
|
||||
"internal/testenv"
|
||||
"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) {
|
||||
t.Parallel()
|
||||
testDisasm(t, "fmthello.go", printCode, printGnuAsm)
|
||||
if build.Default.CgoEnabled {
|
||||
if testenv.HasCGO() {
|
||||
testDisasm(t, "fmthellocgo.go", printCode, printGnuAsm)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"internal/godebug"
|
||||
"internal/goroot"
|
||||
"internal/goversion"
|
||||
"internal/platform"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
@ -345,7 +346,7 @@ func defaultContext() Context {
|
||||
default:
|
||||
// cgo must be explicitly enabled for cross compilation builds
|
||||
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
|
||||
}
|
||||
c.CgoEnabled = false
|
||||
|
@ -292,7 +292,7 @@ var depsRules = `
|
||||
FMT, internal/goexperiment
|
||||
< 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;
|
||||
|
||||
# databases
|
||||
|
@ -126,6 +126,9 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
|
||||
}
|
||||
|
||||
platform := goos + "/" + goarch
|
||||
if _, ok := osArchSupportsCgo[platform]; !ok {
|
||||
return false // platform unrecognized
|
||||
}
|
||||
|
||||
switch buildmode {
|
||||
case "archive":
|
||||
@ -237,3 +240,8 @@ func DefaultPIE(goos, goarch string, isRace bool) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CgoSupported reports whether goos/goarch supports cgo.\n")
|
||||
func CgoSupported(goos, goarch string) bool {
|
||||
return osArchSupportsCgo[goos+"/"+goarch]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user