From 5bb550dbf03946578344897753dbec5d836b348a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ty=C3=A1s=20Mustoha?= Date: Thu, 18 Aug 2016 12:44:13 -0500 Subject: [PATCH] Update to use the new Android library build rules. --- components/servo/build.rs | 38 +++++++++++++++++++++++++++------- components/servo/fake-ld.sh | 26 +++++++++++++++++++---- python/servo/build_commands.py | 32 ++++++++++++++++++++++++++++ python/tidy/servo_tidy/tidy.py | 2 +- support/android/openssl.sh | 2 +- 5 files changed, 87 insertions(+), 13 deletions(-) diff --git a/components/servo/build.rs b/components/servo/build.rs index 701b1eacc0b..1b7f48a987b 100644 --- a/components/servo/build.rs +++ b/components/servo/build.rs @@ -17,22 +17,46 @@ fn main() { fn android_main() { // Get the NDK path from NDK_HOME env. - let ndk_path = env::var("NDK_HOME").ok().expect("Please set the NDK_HOME environment variable"); + let ndk_path = env::var("ANDROID_NDK").ok().expect("Please set the ANDROID_NDK environment variable"); let ndk_path = Path::new(&ndk_path); - // Get the standalone NDK path from NDK_STANDALONE env. - let standalone_path = env::var("NDK_STANDALONE").ok().expect("Please set the NDK_STANDALONE environment variable"); - let standalone_path = Path::new(&standalone_path); + // Build up the path to the NDK compilers + // Options for host are: "linux-x86_64" "linux-x86" "darwin-x86_64" "darwin-x86" + // per: https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html - // Get the standalone NDK path from NDK_STANDALONE env. + let host = env::var("HOST").unwrap(); + let google_host = match host.as_ref() { + "i686-unknown-linux-gnu" => "linux-x86", + "x86_64-apple-darwin" => "darwin-x86_64", + "x86_64-unknown-linux-gnu" => "linux-x86_64", + _ => panic!("Unknown support android cross-compile host: {}", host) + }; + + let toolchain_path = ndk_path.join("toolchains").join("arm-linux-androideabi-4.9").join("prebuilt"). + join(google_host); + println!("toolchain path is: {}", toolchain_path.to_str().unwrap()); + + let target = env::var("TARGET").unwrap(); + let arch = if target.contains("arm") { + "arch-arm" + } else if target.contains("x86") { + "arch-x86" + } else if target.contains("mips") { + "arch-mips" + } else { + panic!("Invalid target architecture {}", target); + }; + + // Get the output directory. let out_dir = env::var("OUT_DIR").ok().expect("Cargo should have set the OUT_DIR environment variable"); let directory = Path::new(&out_dir); // compiling android_native_app_glue.c - if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-gcc")) + if Command::new(toolchain_path.join("bin").join("arm-linux-androideabi-gcc")) .arg(ndk_path.join("sources").join("android").join("native_app_glue").join("android_native_app_glue.c")) .arg("-c") .arg("-o").arg(directory.join("android_native_app_glue.o")) + .arg("--sysroot").arg(ndk_path.join("platforms").join("android-18").join(arch)) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .status().unwrap().code().unwrap() != 0 @@ -42,7 +66,7 @@ fn android_main() { } // compiling libandroid_native_app_glue.a - if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-ar")) + if Command::new(toolchain_path.join("bin").join("arm-linux-androideabi-ar")) .arg("rcs") .arg(directory.join("libandroid_native_app_glue.a")) .arg(directory.join("android_native_app_glue.o")) diff --git a/components/servo/fake-ld.sh b/components/servo/fake-ld.sh index d0dd042dbf4..642f1ae0d0d 100755 --- a/components/servo/fake-ld.sh +++ b/components/servo/fake-ld.sh @@ -9,7 +9,25 @@ set -o nounset set -o pipefail TARGET_DIR="${OUT_DIR}/../../.." -arm-linux-androideabi-gcc "${@}" \ - "${LDFLAGS-}" -lc -shared \ - -o "${TARGET_DIR}/libservo.so" -touch "${TARGET_DIR}/servo" + +export _ANDROID_ARCH=arch-arm +export ANDROID_SYSROOT="${ANDROID_NDK}/platforms/android-18/${_ANDROID_ARCH}" +export _ANDROID_EABI=arm-linux-androideabi-4.9 +ANDROID_TOOLCHAIN="" +for host in "linux-x86_64" "linux-x86" "darwin-x86_64" "darwin-x86"; do + if [[ -d "${ANDROID_NDK}/toolchains/${_ANDROID_EABI}/prebuilt/${host}/bin" ]]; then + ANDROID_TOOLCHAIN="${ANDROID_NDK}/toolchains/${_ANDROID_EABI}/prebuilt/${host}/bin" + break + fi +done + +ANDROID_CPU_ARCH_DIR=armeabi +ANDROID_CXX_LIBS="${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${ANDROID_CPU_ARCH_DIR}" + +echo "toolchain: ${ANDROID_TOOLCHAIN}" +echo "libs dir: ${ANDROID_CXX_LIBS}" +echo "sysroot: ${ANDROID_SYSROOT}" + +"${ANDROID_TOOLCHAIN}/arm-linux-androideabi-gcc" \ + --sysroot="${ANDROID_SYSROOT}" -L "${ANDROID_CXX_LIBS}" "${@}" -lc++ \ + -o "${TARGET_DIR}/libservo.so" -shared && touch "${TARGET_DIR}/servo" diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py index 47dad148ddb..8f05c3e3376 100644 --- a/python/servo/build_commands.py +++ b/python/servo/build_commands.py @@ -12,6 +12,7 @@ from __future__ import print_function, unicode_literals import datetime import os import os.path as path +import platform import sys import shutil @@ -233,6 +234,7 @@ class MachCommands(CommandBase): os.makedirs(openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.makefile"), openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir) + env["ANDROID_NDK_ROOT"] = env["ANDROID_NDK"] with cd(openssl_dir): status = call( make_cmd + ["-f", "openssl.makefile"], @@ -244,6 +246,36 @@ class MachCommands(CommandBase): env['OPENSSL_LIB_DIR'] = openssl_dir env['OPENSSL_INCLUDE_DIR'] = path.join(openssl_dir, "include") env['OPENSSL_STATIC'] = 'TRUE' + # Android builds also require having the gcc bits on the PATH and various INCLUDE + # path munging if you do not want to install a standalone NDK. See: + # https://dxr.mozilla.org/mozilla-central/source/build/autoconf/android.m4#139-161 + os_type = platform.system().lower() + if os_type not in ["linux", "darwin"]: + raise Exception("Android cross builds are only supported on Linux and macOS.") + cpu_type = platform.machine().lower() + host_suffix = "unknown" + if cpu_type in ["i386", "i486", "i686", "i768", "x86"]: + host_suffix = "x86" + elif cpu_type in ["x86_64", "x86-64", "x64", "amd64"]: + host_suffix = "x86_64" + host = os_type + "-" + host_suffix + env['PATH'] = path.join( + env['ANDROID_NDK'], "toolchains", "arm-linux-androideabi-4.9", "prebuilt", host, "bin" + ) + ':' + env['PATH'] + env['ANDROID_SYSROOT'] = path.join(env['ANDROID_NDK'], "platforms", "android-18", "arch-arm") + support_include = path.join(env['ANDROID_NDK'], "sources", "android", "support", "include") + cxx_include = path.join( + env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++", "libcxx", "include") + cxxabi_include = path.join( + env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++abi", "libcxxabi", "include") + env['CFLAGS'] = ' '.join([ + "--sysroot", env['ANDROID_SYSROOT'], + "-I" + support_include]) + env['CXXFLAGS'] = ' '.join([ + "--sysroot", env['ANDROID_SYSROOT'], + "-I" + support_include, + "-I" + cxx_include, + "-I" + cxxabi_include]) cargo_binary = "cargo" + BIN_SUFFIX diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py index 195ca639139..1dcbd4896d1 100644 --- a/python/tidy/servo_tidy/tidy.py +++ b/python/tidy/servo_tidy/tidy.py @@ -47,7 +47,7 @@ FILE_PATTERNS_TO_CHECK = ["*.rs", "*.rc", "*.cpp", "*.c", "*.toml", "*.webidl", "*.json", "*.html"] # File patterns that are ignored for all tidy and lint checks. -FILE_PATTERNS_TO_IGNORE = ["*.#*", "*.pyc"] +FILE_PATTERNS_TO_IGNORE = ["*.#*", "*.pyc", "fake-ld.sh"] SPEC_BASE_PATH = "components/script/dom/" diff --git a/support/android/openssl.sh b/support/android/openssl.sh index c03d077b2ba..7968115c887 100755 --- a/support/android/openssl.sh +++ b/support/android/openssl.sh @@ -22,7 +22,7 @@ _ANDROID_NDK="android-ndk-r9" # list in $ANDROID_NDK_ROOT/toolchains. This value is always used. # _ANDROID_EABI="x86-4.6" # _ANDROID_EABI="arm-linux-androideabi-4.6" -_ANDROID_EABI="arm-linux-androideabi-4.8" +_ANDROID_EABI="arm-linux-androideabi-4.9" # Set _ANDROID_ARCH to the architecture you are building for. # This value is always used.