]> Cypherpunks repositories - gostls13.git/commitdiff
internal/testenv: allow 'go build' on android when supported
authorBryan C. Mills <bcmills@google.com>
Fri, 10 Mar 2023 19:25:41 +0000 (14:25 -0500)
committerGopher Robot <gobot@golang.org>
Fri, 28 Apr 2023 01:33:31 +0000 (01:33 +0000)
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>
src/internal/testenv/testenv.go

index 9a649e037cd7af7511124d6f0e17a786369015fb..aeda1f964f71101d270ad39d1be8e942cbbe6ed4 100644 (file)
@@ -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"