aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2023-03-10 14:25:41 -0500
committerGopher Robot <gobot@golang.org>2023-04-28 01:33:31 +0000
commit71ad46cd2a4eb34befbb21c0a37b5a8092c2b7f5 (patch)
tree892776da41d9c7268321f8eb5b3d27f8d71baddd /src
parent7bc8aacec185ca80839ef0a4f58b85e482ab769e (diff)
downloadgo-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')
-rw-r--r--src/internal/testenv/testenv.go63
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"