diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go index 369264da76..ec498bbcd7 100644 --- a/src/cmd/go/script_test.go +++ b/src/cmd/go/script_test.go @@ -30,6 +30,7 @@ import ( "cmd/go/internal/robustio" "cmd/go/internal/txtar" "cmd/go/internal/work" + "cmd/internal/sys" ) // TestScript runs the tests in testdata/script/*.txt. @@ -303,6 +304,11 @@ Script: } break } + if strings.HasPrefix(cond.tag, "buildmode:") { + value := strings.TrimPrefix(cond.tag, "buildmode:") + ok = sys.BuildModeSupported(runtime.Compiler, value, runtime.GOOS, runtime.GOARCH) + break + } if !imports.KnownArch[cond.tag] && !imports.KnownOS[cond.tag] && cond.tag != "gc" && cond.tag != "gccgo" { ts.fatalf("unknown condition %q", cond.tag) } diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README index 511d747129..2782a09707 100644 --- a/src/cmd/go/testdata/script/README +++ b/src/cmd/go/testdata/script/README @@ -79,6 +79,7 @@ should only run when the condition is satisfied. The available conditions are: - [symlink] for testenv.HasSymlink() - [exec:prog] for whether prog is available for execution (found by exec.LookPath) - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable + - [buildmode:value] for whether -buildmode=value is supported A condition can be negated: [!short] means to run the rest of the line when testing.Short() is false. Multiple conditions may be given for a single diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go index 4162858ac1..78aa825a78 100644 --- a/src/cmd/internal/sys/supported.go +++ b/src/cmd/internal/sys/supported.go @@ -43,3 +43,76 @@ func MustLinkExternal(goos, goarch string) bool { } return false } + +// BuildModeSupported reports whether goos/goarch supports the given build mode +// using the given compiler. +func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + // This function mirrors the logic in cmd/go/internal/work.buildModeInit. + // + // TODO(bcmills): Refactor buildModeInit to use this function so that the two + // don't get out of sync. + + if compiler == "gccgo" { + return true + } + + platform := goos + "/" + goarch + + switch buildmode { + case "archive": + return true + + case "c-archive": + // TODO(bcmills): This seems dubious. + // Do we really support c-archive mode on js/wasm‽ + return platform != "linux/ppc64" + + case "c-shared": + switch platform { + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", "darwin/386", + "windows/amd64", "windows/386": + return true + } + return false + + case "default": + return true + + case "exe": + return true + + case "pie": + switch platform { + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", + "aix/ppc64": + return true + } + return false + + case "shared": + switch platform { + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": + return true + } + return false + + case "plugin": + switch platform { + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/arm", "android/arm64", "android/386", + "darwin/amd64", + "freebsd/amd64": + return true + } + return false + + default: + return false + } +}