cmd/gomobile: refactor android*Env to handle more architectures

This does not change the tool's behavior.

The global ndkConfig 'ndk' holds info on all supported architectures
with the latest Go and gomobile tools (tip), and provides Root and
Toolchain methods that returns the current NDK installation directory
and the toolchain info depending on the GOPATH and the current go
version.

The global androidEnv is a map from arch name to the env vars.

ndkccpath is replaced by ndk.Root.

For golang/go#10743

Change-Id: I70d8e7b3e9979836112eb82d50c468df4f4ab43f
Reviewed-on: https://go-review.googlesource.com/17720
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Hyang-Ah Hana Kim 2015-12-10 15:52:40 -05:00
parent 3abfce6c04
commit 0a84d43930
8 changed files with 99 additions and 35 deletions

View File

@ -28,7 +28,7 @@ func goAndroidBind(pkgs []*build.Package) error {
// https://golang.org/issue/13234.
androidArgs = []string{"-gcflags=-shared", "-ldflags=-shared"}
}
typesPkgs, err := loadExportData(pkgs, androidArmEnv, androidArgs...)
typesPkgs, err := loadExportData(pkgs, androidEnv["arm"], androidArgs...)
if err != nil {
return err
}
@ -56,7 +56,7 @@ func goAndroidBind(pkgs []*build.Package) error {
err = goBuild(
mainFile,
androidArmEnv,
androidEnv["arm"],
"-buildmode=c-shared",
"-o="+filepath.Join(androidDir, "src/main/jniLibs/armeabi-v7a/libgojni.so"),
)

View File

@ -101,7 +101,7 @@ func TestBindAndroid(t *testing.T) {
var bindAndroidTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
WORK=$WORK
GOOS=android GOARCH=arm GOARM=7 CC=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-gcc CXX=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-g++ CGO_ENABLED=1 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="" -x golang.org/x/mobile/asset
GOOS=android GOARCH=arm CC=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-gcc CXX=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-g++ CGO_ENABLED=1 GOARM=7 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="" -x golang.org/x/mobile/asset
rm -r -f "$WORK/fakegopath"
mkdir -p $WORK/fakegopath/pkg
cp $GOMOBILE/pkg_android_arm/golang.org/x/mobile/asset.a $WORK/fakegopath/pkg/android_arm/golang.org/x/mobile/asset.a
@ -109,7 +109,7 @@ mkdir -p $WORK/fakegopath/pkg/android_arm/golang.org/x/mobile
mkdir -p $WORK/go_asset
gobind -lang=go -outdir=$WORK/go_asset golang.org/x/mobile/asset
mkdir -p $WORK/androidlib
GOOS=android GOARCH=arm GOARM=7 CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 go build -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="" -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/armeabi-v7a/libgojni.so $WORK/androidlib/main.go
GOOS=android GOARCH=arm CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 GOARM=7 go build -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="" -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/armeabi-v7a/libgojni.so $WORK/androidlib/main.go
mkdir -p $WORK/android/src/main/java/{{.JavaPkgDir}}
{{.GobindJavaCmd}} -outdir=$WORK/android/src/main/java/{{.JavaPkgDir}} golang.org/x/mobile/asset
mkdir -p $WORK/android/src/main/java/go

View File

@ -96,7 +96,7 @@ func runBuild(cmd *command) (err error) {
switch buildTarget {
case "android":
if pkg.Name != "main" {
return goBuild(pkg.ImportPath, androidArmEnv)
return goBuild(pkg.ImportPath, androidEnv["arm"])
}
nmpkgs, err = goAndroidBuild(pkg)
if err != nil {

View File

@ -52,11 +52,13 @@ func goAndroidBuild(pkg *build.Package) (map[string]bool, error) {
return nil, fmt.Errorf("error parsing %s: %v", manifestPath, err)
}
}
libPath := filepath.Join(tmpdir, "lib"+libName+".so")
toolchain := ndk.Toolchain("arm")
libPath := filepath.Join(tmpdir, "lib"+libName+".so")
err = goBuild(
pkg.ImportPath,
androidArmEnv,
androidEnv["arm"],
"-buildmode=c-shared",
"-o", libPath,
)
@ -64,7 +66,7 @@ func goAndroidBuild(pkg *build.Package) (map[string]bool, error) {
return nil, err
}
nmpkgs, err := extractPkgs(androidArmNM, libPath)
nmpkgs, err := extractPkgs(toolchain.Path("nm"), libPath)
if err != nil {
return nil, err
}
@ -155,7 +157,7 @@ func goAndroidBuild(pkg *build.Package) (map[string]bool, error) {
if nmpkgs["golang.org/x/mobile/exp/audio/al"] {
dst := "lib/armeabi/libopenal.so"
src := filepath.Join(ndkccpath, "openal/"+dst)
src := filepath.Join(ndk.Root(), "openal/"+dst)
if err := apkwWriteFile(dst, src); err != nil {
return nil, err
}

View File

@ -98,5 +98,5 @@ func TestAndroidBuild(t *testing.T) {
var androidBuildTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
WORK=$WORK
GOOS=android GOARCH=arm GOARM=7 CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 go build -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="tag1" -x -buildmode=c-shared -o $WORK/libbasic.so golang.org/x/mobile/example/basic
GOOS=android GOARCH=arm CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 GOARM=7 go build -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -tags="tag1" -x -buildmode=c-shared -o $WORK/libbasic.so golang.org/x/mobile/example/basic
`))

View File

@ -16,9 +16,9 @@ import (
var (
cwd string
gomobilepath string // $GOPATH/pkg/gomobile
ndkccpath string // $GOPATH/pkg/gomobile/android-{{.NDK}}
androidArmEnv []string
androidEnv map[string][]string // android arch -> []string
darwinArmEnv []string
darwinArm64Env []string
darwin386Env []string
@ -92,23 +92,23 @@ func envInit() (err error) {
// Setup the cross-compiler environments.
// TODO(crawshaw): Remove ndkccpath global.
ndkccpath = filepath.Join(gomobilepath, "android-"+ndkVersion)
ndkccbin := filepath.Join(ndkccpath, "arm", "bin")
androidEnv = make(map[string][]string)
for arch, toolchain := range ndk {
if goVersion < toolchain.minGoVer {
continue
}
exe := ""
if goos == "windows" {
exe = ".exe"
androidEnv[arch] = []string{
"GOOS=android",
"GOARCH=" + arch,
"CC=" + toolchain.Path("gcc"),
"CXX=" + toolchain.Path("g++"),
"CGO_ENABLED=1",
}
if arch == "arm" {
androidEnv[arch] = append(androidEnv[arch], "GOARM=7")
}
}
androidArmEnv = []string{
"GOOS=android",
"GOARCH=arm",
"GOARM=7",
"CC=" + filepath.Join(ndkccbin, "arm-linux-androideabi-gcc"+exe),
"CXX=" + filepath.Join(ndkccbin, "arm-linux-androideabi-g++"+exe),
"CGO_ENABLED=1",
}
androidArmNM = filepath.Join(ndkccbin, "arm-linux-androideabi-nm"+exe)
if runtime.GOOS != "darwin" {
return nil
@ -250,3 +250,64 @@ func getenv(env []string, key string) string {
func pkgdir(env []string) string {
return gomobilepath + "/pkg_" + getenv(env, "GOOS") + "_" + getenv(env, "GOARCH")
}
type ndkToolchain struct {
arch string
abi string
platform string
gcc string
toolPrefix string
minGoVer goToolVersion
}
func (tc *ndkToolchain) Path(toolName string) string {
if goos == "windows" {
toolName += ".exe"
}
return filepath.Join(ndk.Root(), tc.arch, "bin", tc.toolPrefix+"-"+toolName)
}
type ndkConfig map[string]ndkToolchain // map: GOOS->androidConfig.
func (nc ndkConfig) Root() string {
return filepath.Join(gomobilepath, "android-"+ndkVersion)
}
func (nc ndkConfig) Toolchain(arch string) ndkToolchain {
tc, ok := nc[arch]
if !ok || tc.minGoVer > goVersion {
panic(`unsupported architecture: ` + arch)
}
return tc
}
// TODO: share this with release.go
var ndk = ndkConfig{
"arm": {
arch: "arm",
abi: "armeabi-v7a",
platform: "android-15",
gcc: "arm-linux-androideabi-4.8",
toolPrefix: "arm-linux-androideabi",
minGoVer: go1_5,
},
/*
"386": {
arch: "x86",
abi: "x86",
platform: "android-15",
gcc: "x86-4.8",
toolPrefix: "i686-linux-android",
minGoVer: go1_6,
},
"amd64": {
arch: "x86_64",
abi: "x86_64",
platform: "android-21",
gcc: "x86_64-4.9",
toolPrefix: "x86_64-linux-android",
minGoVer: go1_6,
},
*/
}

View File

@ -81,14 +81,14 @@ func runInit(cmd *command) error {
return fmt.Errorf("GOPATH is not set")
}
gomobilepath = filepath.Join(gopaths[0], "pkg/gomobile")
ndkccpath = filepath.Join(gopaths[0], "pkg/gomobile/android-"+ndkVersion)
verpath := filepath.Join(gopaths[0], "pkg/gomobile/version")
verpath := filepath.Join(gomobilepath, "version")
if buildX || buildN {
fmt.Fprintln(xout, "GOMOBILE="+gomobilepath)
}
removeGomobilepkg()
if err := mkdir(ndkccpath); err != nil {
if err := mkdir(ndk.Root()); err != nil {
return err
}
@ -146,7 +146,7 @@ func runInit(cmd *command) error {
// https://golang.org/issue/13234.
androidArgs = []string{"-gcflags=-shared", "-ldflags=-shared"}
}
if err := installStd(androidArmEnv, androidArgs...); err != nil {
if err := installStd(androidEnv["arm"], androidArgs...); err != nil {
return err
}
if err := installDarwin(); err != nil {
@ -309,12 +309,13 @@ func fetchOpenAL() error {
if goos == "windows" {
resetReadOnlyFlagAll(filepath.Join(tmpdir, "openal"))
}
dst := filepath.Join(ndkccpath, "arm", "sysroot", "usr", "include")
ndkroot := ndk.Root()
dst := filepath.Join(ndkroot, "arm", "sysroot", "usr", "include")
src := filepath.Join(tmpdir, "openal", "include")
if err := move(dst, src, "AL"); err != nil {
return err
}
libDst := filepath.Join(ndkccpath, "openal")
libDst := filepath.Join(ndkroot, "openal")
libSrc := filepath.Join(tmpdir, "openal")
if err := mkdir(libDst); err != nil {
return nil
@ -388,7 +389,7 @@ func fetchNDK() error {
resetReadOnlyFlagAll(filepath.Join(tmpdir, "android-"+ndkVersion))
}
dst := filepath.Join(ndkccpath, "arm")
dst := filepath.Join(ndk.Root(), "arm")
dstSysroot := filepath.Join(dst, "sysroot/usr")
if err := mkdir(dstSysroot); err != nil {
return err

View File

@ -132,7 +132,7 @@ mv $WORK/openal/lib $GOMOBILE/android-{{.NDK}}/openal/lib{{if eq .GOOS "darwin"}
go install -p={{.NumCPU}} -x golang.org/x/mobile/gl
go install -p={{.NumCPU}} -x golang.org/x/mobile/app
go install -p={{.NumCPU}} -x golang.org/x/mobile/exp/app/debug{{end}}
GOOS=android GOARCH=arm GOARM=7 CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -x std
GOOS=android GOARCH=arm CC=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-gcc{{.EXE}} CXX=$GOMOBILE/android-{{.NDK}}/arm/bin/arm-linux-androideabi-g++{{.EXE}} CGO_ENABLED=1 GOARM=7 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_android_arm -x std
{{if eq .GOOS "darwin"}}GOOS=darwin GOARCH=arm GOARM=7 CC=clang-iphoneos CXX=clang-iphoneos CGO_CFLAGS=-isysroot=iphoneos -arch armv7 CGO_LDFLAGS=-isysroot=iphoneos -arch armv7 CGO_ENABLED=1 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_darwin_arm -x std
GOOS=darwin GOARCH=arm64 CC=clang-iphoneos CXX=clang-iphoneos CGO_CFLAGS=-isysroot=iphoneos -arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -arch arm64 CGO_ENABLED=1 go install -p={{.NumCPU}} -pkgdir=$GOMOBILE/pkg_darwin_arm64 -x std
GOOS=darwin GOARCH=amd64 CC=clang-iphonesimulator CXX=clang-iphonesimulator CGO_CFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=6.1 -arch x86_64 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=6.1 -arch x86_64 CGO_ENABLED=1 go install -p={{.NumCPU}} -tags=ios -pkgdir=$GOMOBILE/pkg_darwin_amd64 -x std