diff options
| author | Bryan C. Mills <bcmills@google.com> | 2023-03-10 14:25:41 -0500 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-04-28 01:33:31 +0000 |
| commit | 71ad46cd2a4eb34befbb21c0a37b5a8092c2b7f5 (patch) | |
| tree | 892776da41d9c7268321f8eb5b3d27f8d71baddd /src/internal | |
| parent | 7bc8aacec185ca80839ef0a4f58b85e482ab769e (diff) | |
| download | go-71ad46cd2a4eb34befbb21c0a37b5a8092c2b7f5.tar.xz | |
internal/testenv: allow 'go build' on android when supported
As of CL 472096, it should work on android/arm64 always (because
internal linking is supported on that platform), and on other android
platforms when a C toolchain is present in the test environment.
Updates #58775.
Change-Id: Ifa38dc69b258b38dcc341979dcbf8cd61265c787
Reviewed-on: https://go-review.googlesource.com/c/go/+/475456
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Changkun Ou <mail@changkun.de>
Diffstat (limited to 'src/internal')
| -rw-r--r-- | src/internal/testenv/testenv.go | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go index 9a649e037c..aeda1f964f 100644 --- a/src/internal/testenv/testenv.go +++ b/src/internal/testenv/testenv.go @@ -45,13 +45,62 @@ func HasGoBuild() bool { // run go build. return false } - switch runtime.GOOS { - case "android", "js", "ios", "wasip1": + + if !HasExec() { + // If we can't exec anything at all, we certainly can't exec 'go build'. return false } + + if platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH, false) { + // We can assume that we always have a complete Go toolchain available. + // However, this platform requires a C linker to build even pure Go + // programs, including tests. Do we have one in the test environment? + // (On Android, for example, the device running the test might not have a + // C toolchain installed.) + // + // If CC is set explicitly, assume that we do. Otherwise, use 'go env CC' + // to determine which toolchain it would use by default. + if os.Getenv("CC") == "" { + if _, err := findCC(); err != nil { + return false + } + } + } + return true } +func findCC() (string, error) { + ccOnce.Do(func() { + goTool, err := findGoTool() + if err != nil { + ccErr = err + return + } + + cmd := exec.Command(goTool, "env", "CC") + out, err := cmd.Output() + out = bytes.TrimSpace(out) + if err != nil { + ccErr = fmt.Errorf("%v: %w", cmd, err) + return + } else if len(out) == 0 { + ccErr = fmt.Errorf("%v: no CC reported", cmd) + return + } + + cc := string(out) + ccPath, ccErr = exec.LookPath(cc) + }) + return ccPath, ccErr +} + +var ( + ccOnce sync.Once + ccPath string + ccErr error +) + // MustHaveGoBuild checks that the current system can build programs with “go build” // and then run them with os.StartProcess or exec.Command. // If not, MustHaveGoBuild calls t.Skip with an explanation. @@ -212,11 +261,15 @@ func GOROOT(t testing.TB) string { // GoTool reports the path to the Go tool. func GoTool() (string, error) { + if !HasGoBuild() { + return "", errors.New("platform cannot run go tool") + } + return findGoTool() +} + +func findGoTool() (string, error) { goToolOnce.Do(func() { goToolPath, goToolErr = func() (string, error) { - if !HasGoBuild() { - return "", errors.New("platform cannot run go tool") - } var exeSuffix string if runtime.GOOS == "windows" { exeSuffix = ".exe" |
