| | |
| | |
| | |
| |
|
| | package scripttest |
| |
|
| | import ( |
| | "cmd/internal/script" |
| | "fmt" |
| | "internal/buildcfg" |
| | "internal/platform" |
| | "internal/testenv" |
| | "runtime" |
| | "strings" |
| | "testing" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | func AddToolChainScriptConditions(t *testing.T, conds map[string]script.Cond, goHostOS, goHostArch string) { |
| | add := func(name string, cond script.Cond) { |
| | if _, ok := conds[name]; ok { |
| | t.Fatalf("condition %q is already registered", name) |
| | } |
| | conds[name] = cond |
| | } |
| |
|
| | lazyBool := func(summary string, f func() bool) script.Cond { |
| | return script.OnceCondition(summary, func() (bool, error) { return f(), nil }) |
| | } |
| |
|
| | add("asan", sysCondition("-asan", platform.ASanSupported, true, goHostOS, goHostArch)) |
| | add("buildmode", script.PrefixCondition("go supports -buildmode=<suffix>", hasBuildmode)) |
| | add("cgo", script.BoolCondition("host CGO_ENABLED", testenv.HasCGO())) |
| | add("cgolinkext", script.Condition("platform requires external linking for cgo", cgoLinkExt)) |
| | add("cross", script.BoolCondition("cmd/go GOOS/GOARCH != GOHOSTOS/GOHOSTARCH", goHostOS != runtime.GOOS || goHostArch != runtime.GOARCH)) |
| | add("fuzz", sysCondition("-fuzz", platform.FuzzSupported, false, goHostOS, goHostArch)) |
| | add("fuzz-instrumented", sysCondition("-fuzz with instrumentation", platform.FuzzInstrumented, false, goHostOS, goHostArch)) |
| | add("GODEBUG", script.PrefixCondition("GODEBUG contains <suffix>", hasGodebug)) |
| | add("GOEXPERIMENT", script.PrefixCondition("GOEXPERIMENT <suffix> is enabled", hasGoexperiment)) |
| | add("go-builder", script.BoolCondition("GO_BUILDER_NAME is non-empty", testenv.Builder() != "")) |
| | add("link", lazyBool("testenv.HasLink()", testenv.HasLink)) |
| | add("msan", sysCondition("-msan", platform.MSanSupported, true, goHostOS, goHostArch)) |
| | add("mustlinkext", script.Condition("platform always requires external linking", mustLinkExt)) |
| | add("pielinkext", script.Condition("platform requires external linking for PIE", pieLinkExt)) |
| | add("race", sysCondition("-race", platform.RaceDetectorSupported, true, goHostOS, goHostArch)) |
| | add("symlink", lazyBool("testenv.HasSymlink()", testenv.HasSymlink)) |
| | } |
| |
|
| | func sysCondition(flag string, f func(goos, goarch string) bool, needsCgo bool, goHostOS, goHostArch string) script.Cond { |
| | return script.Condition( |
| | "GOOS/GOARCH supports "+flag, |
| | func(s *script.State) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | cross := goHostOS != GOOS || goHostArch != GOARCH |
| | return (!needsCgo || (testenv.HasCGO() && !cross)) && f(GOOS, GOARCH), nil |
| | }) |
| | } |
| |
|
| | func hasBuildmode(s *script.State, mode string) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | return platform.BuildModeSupported(runtime.Compiler, mode, GOOS, GOARCH), nil |
| | } |
| |
|
| | func cgoLinkExt(s *script.State) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | return platform.MustLinkExternal(GOOS, GOARCH, true), nil |
| | } |
| |
|
| | func mustLinkExt(s *script.State) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | return platform.MustLinkExternal(GOOS, GOARCH, false), nil |
| | } |
| |
|
| | func pieLinkExt(s *script.State) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | return !platform.InternalLinkPIESupported(GOOS, GOARCH), nil |
| | } |
| |
|
| | func hasGodebug(s *script.State, value string) (bool, error) { |
| | godebug, _ := s.LookupEnv("GODEBUG") |
| | for p := range strings.SplitSeq(godebug, ",") { |
| | if strings.TrimSpace(p) == value { |
| | return true, nil |
| | } |
| | } |
| | return false, nil |
| | } |
| |
|
| | func hasGoexperiment(s *script.State, value string) (bool, error) { |
| | GOOS, _ := s.LookupEnv("GOOS") |
| | GOARCH, _ := s.LookupEnv("GOARCH") |
| | goexp, _ := s.LookupEnv("GOEXPERIMENT") |
| | flags, err := buildcfg.ParseGOEXPERIMENT(GOOS, GOARCH, goexp) |
| | if err != nil { |
| | return false, err |
| | } |
| | for _, exp := range flags.All() { |
| | if value == exp { |
| | return true, nil |
| | } |
| | if strings.TrimPrefix(value, "no") == strings.TrimPrefix(exp, "no") { |
| | return false, nil |
| | } |
| | } |
| | return false, fmt.Errorf("unrecognized GOEXPERIMENT %q", value) |
| | } |
| |
|