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>
This commit is contained in:
Bryan C. Mills 2023-03-10 14:25:41 -05:00 committed by Gopher Robot
parent 7bc8aacec1
commit 71ad46cd2a
1 changed files with 58 additions and 5 deletions

View 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"