mobile/cmd/gomobile: use NDK r12
Also:
- Replace GCC with Clang. GCC is slated for removal in future NDK
releases.
- Replace the deprecated obsoleted make-standalone-toolchain.sh
script with the new make_standalone_toolchain.py script.
- Add the NDK version to OpenAL tarball name, to avoid name clashes
with previous builds of the same OpenAL version.
- Removed obsolete workaround for a linker problem with NDK r10c.
- Update the URLs and unpack logic for the full NDK mode.
Change-Id: Ifeec6fee624862ba2ff2d4520dab42f800414f7b
Reviewed-on: https://go-review.googlesource.com/24490
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go
index 4c65a65..89395d1 100644
--- a/cmd/gomobile/env.go
+++ b/cmd/gomobile/env.go
@@ -98,11 +98,24 @@
continue
}
+ // Emulate the flags in the clang wrapper scripts generated
+ // by make_standalone_toolchain.py
+ s := strings.SplitN(toolchain.toolPrefix, "-", 3)
+ a, os, env := s[0], s[1], s[2]
+ if a == "arm" {
+ a = "armv7a"
+ }
+ target := strings.Join([]string{a, "none", os, env}, "-")
+ sysroot := filepath.Join(ndk.Root(), toolchain.arch, "sysroot")
+ flags := fmt.Sprintf("-target %s --sysroot %s", target, sysroot)
androidEnv[arch] = []string{
"GOOS=android",
"GOARCH=" + arch,
- "CC=" + toolchain.Path("gcc"),
- "CXX=" + toolchain.Path("g++"),
+ "CC=" + toolchain.Path("clang"),
+ "CXX=" + toolchain.Path("clang++"),
+ "CGO_CFLAGS=" + flags,
+ "CGO_CPPFLAGS=" + flags,
+ "CGO_LDFLAGS=" + flags,
"CGO_ENABLED=1",
}
if arch == "arm" {
diff --git a/cmd/gomobile/hashes.go b/cmd/gomobile/hashes.go
index 0771196..41e8f9e 100644
--- a/cmd/gomobile/hashes.go
+++ b/cmd/gomobile/hashes.go
@@ -7,13 +7,13 @@
// Hashes were computed with 'go run release.go'
var fetchHashes = map[string]string{
- "android-ndk-r11c-darwin-x86_64.zip": "fe2f8986074717240df45f03e93a4436dac2040dc12fecee4853953d584424b3",
- "gomobile-ndk-r11c-darwin-x86_64.tar.gz": "1d563c5c27dcb3643eb3cbd4e44b535aec052c600350d6203374e0100b1d75ff",
- "android-ndk-r11c-linux-x86_64.zip": "ba85dbe4d370e4de567222f73a3e034d85fc3011b3cbd90697f3e8dcace3ad94",
- "gomobile-ndk-r11c-linux-x86_64.tar.gz": "eb0a657e03dad70dce33281414d2fdf38f2b313a8a1a4323d0648e9d16198d74",
- "android-ndk-r11c-windows-x86.zip": "eea7d148cf046baad2b8f3fd8e4a27d3695964079db0da6b9fca08051bb4dccb",
- "gomobile-ndk-r11c-windows-x86.tar.gz": "7f6b53f55993aa0deccace0ab2829ebb0e93d6bf2196a964f63bfde46da95d9e",
- "android-ndk-r11c-windows-x86_64.zip": "55c69f1d5a3602b3f6d6cea280b16938f17d6a4b509af01641d4db1280088d90",
- "gomobile-ndk-r11c-windows-x86_64.tar.gz": "b3e1e17ec6d19b7512e6b5277fccc3a61e4c4b6bab6c4a3874d856c0332a61db",
- "gomobile-openal-soft-1.16.0.1.tar.gz": "84c9361734902df622dd49a8c0cfb0090fd7743a2cbf927a9ae85c4826beb173",
+ "android-ndk-r12-darwin-x86_64.zip": "fe10b64a65f3e818b852862975ea7b5896295cd1301d1acdbeb1294d9592fb19",
+ "gomobile-ndk-r12-darwin-x86_64.tar.gz": "861c5b6d464923f4bac16f47999d838a6a15184b17f5482049e52949dfece44c",
+ "android-ndk-r12-linux-x86_64.zip": "7876e3b99f3596a3215ecf4e9f152d24b82dfdf2bbe7d3a38c423ae6a3edee79",
+ "gomobile-ndk-r12-linux-x86_64.tar.gz": "ffa4b99736b8df22f26027167ab5e6e3d1d74aaf838622009134cd022b9bc9e2",
+ "android-ndk-r12-windows-x86.zip": "72a18b670086601e827f6fe4f49e31239f969138ddc9468800e64d6a4fc5bd81",
+ "gomobile-ndk-r12-windows-x86.tar.gz": "ed201197b87bb1ed830d5ac5cdbccf65b1833d8b338a82804e7d6a3dc8da80cd",
+ "android-ndk-r12-windows-x86_64.zip": "85c5d6d43a04b43cd004771394db37e8f7a7a074ce4c7db7476880cc1a41607f",
+ "gomobile-ndk-r12-windows-x86_64.tar.gz": "f9ccdf1687a41a4dddf221c451f43fb8cd5729d8a40d9c61da3d8c86b352b1b0",
+ "gomobile-openal-soft-1.16.0.1-ndk-r12.tar.gz": "ede844ee14491a45686657998a12ccb591e7958332fb099581018a11697ffbb2",
}
diff --git a/cmd/gomobile/init.go b/cmd/gomobile/init.go
index 94fa759..90ce965 100644
--- a/cmd/gomobile/init.go
+++ b/cmd/gomobile/init.go
@@ -23,15 +23,15 @@
"time"
)
-// useStrippedNDK determines whether the init subcommand fetches the GCC
+// useStrippedNDK determines whether the init subcommand fetches the clang
// toolchain from the original Android NDK, or from the stripped-down NDK
// hosted specifically for the gomobile tool.
//
// There is a significant size different (400MB compared to 30MB).
var useStrippedNDK = true
-const ndkVersion = "ndk-r11c"
-const openALVersion = "openal-soft-1.16.0.1"
+const ndkVersion = "ndk-r12"
+const openALVersion = "openal-soft-1.16.0.1-" + ndkVersion
var (
goos = runtime.GOOS
@@ -399,6 +399,26 @@
resetReadOnlyFlagAll(filepath.Join(tmpdir, "android-"+ndkVersion))
}
+ // Copy the cross compiling clang and clang++ compilers
+ llvmsrc := filepath.Join(tmpdir, fmt.Sprintf(
+ "android-%s/toolchains/llvm/prebuilt", ndkVersion))
+ if goos == "windows" && ndkarch == "x86" {
+ llvmsrc = filepath.Join(llvmsrc, "windows")
+ } else {
+ llvmsrc = filepath.Join(llvmsrc, goos+"-"+ndkarch)
+ }
+ llvmdst := filepath.Join(ndk.Root(), "llvm")
+ llvmbin := filepath.Join(llvmdst, "bin")
+ if err := mkdir(llvmbin); err != nil {
+ return err
+ }
+ if err := move(llvmbin, filepath.Join(llvmsrc, "bin"), "clang", "clang++"); err != nil {
+ return err
+ }
+ if err := move(llvmdst, llvmsrc, "lib64"); err != nil {
+ return err
+ }
+
for arch := range androidEnv {
toolchain := ndk.Toolchain(arch)
dst := filepath.Join(ndk.Root(), toolchain.arch)
@@ -420,35 +440,16 @@
} else {
ndkpath = filepath.Join(ndkpath, goos+"-"+ndkarch)
}
- if err := move(dst, ndkpath, "bin", "lib", "libexec"); err != nil {
+ if err := move(dst, ndkpath, "bin", "lib"); err != nil {
return err
}
- // ndk-r10e arm64 toolchain has a bug in ld.bfd and for aarch64
- // ld.bfd is the default linker. Workaround by switching the
- // default to ld.gold.
- // TODO(hyangah): remove this when using the new version of ndk.
- if toolchain.arch == "arm64" {
- ld := filepath.Join(dst, "bin/aarch64-linux-android-ld")
- ldgold := ld + ".gold"
- if goos == "windows" {
- ld += ".exe"
- ldgold += ".exe"
- }
- if err := rm(ld); err != nil {
- return err
- }
- if err := symlink(ldgold, ld); err != nil {
- return err
- }
- }
-
linkpath := filepath.Join(dst, toolchain.toolPrefix+"/bin")
if err := mkdir(linkpath); err != nil {
return err
}
- for _, name := range []string{"ld", "as", "gcc", "g++"} {
+ for _, name := range []string{"ld", "as"} {
if goos == "windows" {
name += ".exe"
}
@@ -456,6 +457,14 @@
return err
}
}
+ for _, name := range []string{"clang", "clang++"} {
+ if goos == "windows" {
+ name += ".exe"
+ }
+ if err := symlink(filepath.Join(llvmbin, name), filepath.Join(dst, "bin", toolchain.toolPrefix+"-"+name)); err != nil {
+ return err
+ }
+ }
}
return nil
}
@@ -470,35 +479,16 @@
}
func fetchFullNDK() error {
- url := "https://dl.google.com/android/ndk/android-" + ndkVersion + "-" + goos + "-" + ndkarch + "."
- if goos == "windows" {
- url += "exe"
- } else {
- url += "bin"
- }
+ url := "https://dl.google.com/android/repository/android-" + ndkVersion + "-" + goos + "-" + ndkarch + ".zip"
archive, err := fetch(url)
if err != nil {
return err
}
-
- // The self-extracting ndk dist file for Windows terminates
- // with an error (error code 2 - corrupted or incomplete file)
- // but there are no details on what caused this.
- //
- // Strangely, if the file is launched from file browser or
- // unzipped with 7z.exe no error is reported.
- //
- // In general we use the stripped NDK, so this code path
- // is not used, and 7z.exe is not a normal dependency.
var inflate *exec.Cmd
if goos != "windows" {
- // The downloaded archive is executed on linux and os x to unarchive.
- // To do this execute permissions are needed.
- os.Chmod(archive, 0755)
-
- inflate = exec.Command(archive)
+ inflate = exec.Command("unzip", archive)
} else {
- inflate = exec.Command("7z.exe", "x", archive)
+ inflate = exec.Command("unzip.exe", archive)
}
inflate.Dir = tmpdir
return runCmd(inflate)
diff --git a/cmd/gomobile/release.go b/cmd/gomobile/release.go
index 54288b1..6dfac02 100644
--- a/cmd/gomobile/release.go
+++ b/cmd/gomobile/release.go
@@ -28,9 +28,10 @@
"os/exec"
"path/filepath"
"runtime"
+ "strconv"
)
-const ndkVersion = "ndk-r11c"
+const ndkVersion = "ndk-r12"
type version struct {
os string
@@ -46,16 +47,16 @@
type target struct {
arch string
- platform string
+ platform int
gcc string
toolPrefix string
}
var targets = []target{
- {"arm", "android-15", "arm-linux-androideabi-4.9", "arm-linux-androideabi"},
- {"arm64", "android-21", "aarch64-linux-android-4.9", "aarch64-linux-android"},
- {"x86", "android-15", "x86-4.9", "i686-linux-android"},
- {"x86_64", "android-21", "x86_64-4.9", "x86_64-linux-android"},
+ {"arm", 15, "arm-linux-androideabi-4.9", "arm-linux-androideabi"},
+ {"arm64", 21, "aarch64-linux-android-4.9", "aarch64-linux-android"},
+ {"x86", 15, "x86-4.9", "i686-linux-android"},
+ {"x86_64", 21, "x86_64-4.9", "x86_64-linux-android"},
}
var (
@@ -132,16 +133,13 @@
}
buildDir := alTmpDir + "/build/" + abi
toolchain := buildDir + "/toolchain"
- if err := os.MkdirAll(toolchain, 0755); err != nil {
- return err
- }
// standalone ndk toolchains make openal-soft's build config easier.
if err := run(ndkRoot, "env",
- "build/tools/make-standalone-toolchain.sh",
+ "build/tools/make_standalone_toolchain.py",
"--arch="+t.arch,
- "--platform="+t.platform,
+ "--api="+strconv.Itoa(t.platform),
"--install-dir="+toolchain); err != nil {
- return fmt.Errorf("make-standalone-toolchain.sh failed: %v", err)
+ return fmt.Errorf("make_standalone_toolchain.py failed: %v", err)
}
orgPath := os.Getenv("PATH")
@@ -162,7 +160,7 @@
}
// Build the tarball.
- aw := newArchiveWriter("gomobile-openal-soft-1.16.0.1.tar.gz")
+ aw := newArchiveWriter("gomobile-openal-soft-1.16.0.1-" + ndkVersion + ".tar.gz")
defer func() {
err2 := aw.Close()
if err == nil {
@@ -239,7 +237,7 @@
// We preserve the same file layout to make the full NDK interchangable
// with the cut down file.
for _, t := range targets {
- usr := fmt.Sprintf("android-%s/platforms/%s/arch-%s/usr/", ndkVersion, t.platform, t.arch)
+ usr := fmt.Sprintf("android-%s/platforms/android-%d/arch-%s/usr/", ndkVersion, t.platform, t.arch)
gcc := fmt.Sprintf("android-%s/toolchains/%s/prebuilt/", ndkVersion, t.gcc)
if host.os == "windows" && host.arch == "x86" {
@@ -251,7 +249,7 @@
if err := os.MkdirAll(dst+"/"+usr, 0755); err != nil {
return err
}
- if err := os.MkdirAll(dst+"/"+gcc, 0755); err != nil {
+ if err := os.MkdirAll(dst+"/"+gcc+"/bin", 0755); err != nil {
return err
}
@@ -264,9 +262,34 @@
return err
}
- if err := move(dst+"/"+gcc, src+"/"+gcc, "bin", "lib", "libexec", "COPYING", "COPYING.LIB"); err != nil {
+ if err := move(dst+"/"+gcc, src+"/"+gcc, "lib", "COPYING", "COPYING.LIB"); err != nil {
return err
}
+ for _, exe := range []string{"as", "ld"} {
+ if host.os == "windows" {
+ exe += ".exe"
+ }
+ if err := move(dst+"/"+gcc+"/bin", src+"/"+gcc+"/bin", t.toolPrefix+"-"+exe); err != nil {
+ return err
+ }
+ }
+ }
+
+ // Copy the LLVM clang and clang++ compilers
+ llvm := fmt.Sprintf("android-%s/toolchains/llvm/prebuilt/", ndkVersion)
+
+ if host.os == "windows" && host.arch == "x86" {
+ llvm += "windows"
+ } else {
+ llvm += host.os + "-" + host.arch
+ }
+
+ if err := os.MkdirAll(dst+"/"+llvm, 0755); err != nil {
+ return err
+ }
+
+ if err := move(dst+"/"+llvm, src+"/"+llvm, "bin", "lib64", "NOTICE"); err != nil {
+ return err
}
// Build the tarball.