build: support newer Android NDK versions
- Update build.rs to support recent NDK (19 or later) build instruction.
- You can still get previous NDK support using `--features ndk-old-gcc`.
- build_android_ndk19.sh is an example script to build using NDK >= 19.
- travis: android build will try both way.
diff --git a/.travis.yml b/.travis.yml
index c6dbc49..9ad50bc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -120,7 +120,8 @@
language: android
dist: trusty
env:
- NDK_VER=r13b
+ NDK_VER_OLD=r13b
+ NDK_VER=r21
CMAKE_VER=3.6.4111459
android:
components:
@@ -136,17 +137,29 @@
# Additional Android components
- echo y | sdkmanager "cmake;$CMAKE_VER"
- export PATH=$ANDROID_HOME/cmake/$CMAKE_VER/bin/:$PATH
- # NDK download and install
+ script:
+ #
+ # Old NDK. Here we use 13b
+ #
- NDK_URL=https://dl.google.com/android/repository/android-ndk-%s-linux-x86_64.zip
- - curl -ondk.zip -q $(printf $NDK_URL $NDK_VER)
+ - curl -ondk.zip -q $(printf $NDK_URL $NDK_VER_OLD)
- unzip -q ndk.zip -d $HOME
- - export ANDROID_NDK_HOME=$HOME/android-ndk-$NDK_VER
+ - export ANDROID_NDK_HOME=$HOME/android-ndk-$NDK_VER_OLD
# Setup android toolchain
- export TOOLCHAIN_DIR=$(pwd)/toolchain
- mkdir -p $TOOLCHAIN_DIR
- tools/setup_android.sh
- script:
- - tools/build_android.sh --verbose
+ - tools/build_android.sh --verbose --features ndk-old-gcc
+ - rm -fr $TOOLCHAIN_DIR && rm -f .cargo/config
+ #
+ # NDK 19 or higher. Here we use 21 (long term support)
+ #
+ - curl -ondk.zip -q $(printf $NDK_URL $NDK_VER)
+ - unzip -q ndk.zip -d $HOME
+ - export ANDROID_NDK_HOME=$HOME/android-ndk-$NDK_VER
+ - cargo install cargo-ndk
+ - cargo clean
+ - tools/build_android_ndk19.sh --verbose
- name: "NGINX"
language: rust
rust: stable
diff --git a/Cargo.toml b/Cargo.toml
index a1e815e..b4ca6ec 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,6 +43,9 @@
# Equivalent to "--cfg fuzzing", but can also be checked in build.rs.
fuzzing = []
+# For building with Android NDK < 18 and GCC.
+ndk-old-gcc = []
+
[package.metadata.docs.rs]
default-features = false
diff --git a/README.md b/README.md
index 6955b21..1b7d328 100644
--- a/README.md
+++ b/README.md
@@ -250,20 +250,53 @@
To build quiche for Android, you need the following:
-- Install Android NDK (13b or higher), using Android Studio or directly.
-- Set `ANDROID_NDK_HOME` environment variable to NDK path, e.g. using bash:
+- Install the [Android NDK] (13b or higher), using Android Studio or directly.
+- Set `ANDROID_NDK_HOME` environment variable to NDK path, e.g.
```bash
$ export ANDROID_NDK_HOME=/usr/local/share/android-ndk
```
-- Install the Rust toolchain for Android architectures:
+- Install the Rust toolchain for Android architectures needed:
```bash
- $ rustup target add aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android
+ $ rustup target add aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android x86_64-linux-android
```
-Then, to prepare the cross-compiling toolchain, run the following command:
+Note that the minimum API level is 21 for all target architectures.
+
+Depending on the NDK version used, you can take one of the following procedures:
+
+[Android NDK]: https://developer.android.com/ndk
+
+#### NDK version >= 19
+
+For NDK version 19 or higher (21 recommended), you can build in a simpler
+way using [cargo-ndk]. You need to install [cargo-ndk] first.
+
+```bash
+ $ cargo install cargo-ndk
+```
+
+You can build the quiche library using the following procedure. Note that
+`--target` and `--android-platform` are mandatory.
+
+```bash
+ $ cargo ndk --target aarch64-linux-android --android-platform 21 -- build
+```
+
+See [build_android_ndk19.sh] for more information.
+
+Note that building with NDK version 18 appears to be broken.
+
+[cargo-ndk]: https://docs.rs/crate/cargo-ndk
+[build_android_ndk19.sh]: https://github.com/cloudflare/quiche/blob/master/tools/build_android_ndk19.sh
+
+#### NDK version < 18
+
+If you need to use NDK version < 18 (gcc), you can build quiche in the following way.
+
+To prepare the cross-compiling toolchain, run the following command:
```bash
$ tools/setup_android.sh
@@ -271,13 +304,12 @@
It will create a standalone toolchain for arm64/arm/x86 architectures under the
`$TOOLCHAIN_DIR/arch` directory. If you didn't set `TOOLCHAIN_DIR` environment
-variable, the current directory will be used. Note that the minimum API level is
-21 for all target architectures.
+variable, the current directory will be used.
After it run successfully, run the following script to build libquiche:
```bash
- $ tools/build_android.sh
+ $ tools/build_android.sh --features ndk-old-gcc
```
It will build binaries for aarch64, armv7 and i686. You can pass parameters to
@@ -285,7 +317,7 @@
with verbose logs, do the following:
```bash
- $ tools/build_android.sh --release -vv
+ $ tools/build_android.sh --features ndk-old-gcc --release -vv
```
### Building for iOS
diff --git a/src/build.rs b/src/build.rs
index bd7872e..b76fba4 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -1,41 +1,31 @@
// Additional parameters for Android build of BoringSSL.
-const CMAKE_PARAMS_ANDROID: &[(&str, &[(&str, &str)])] = &[
- ("aarch64", &[
- ("ANDROID_TOOLCHAIN_NAME", "aarch64-linux-android-4.9"),
- ("ANDROID_NATIVE_API_LEVEL", "21"),
- (
- "CMAKE_TOOLCHAIN_FILE",
- "${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake",
- ),
- ("ANDROID_STL", "c++_shared"),
- ]),
- ("arm", &[
- ("ANDROID_TOOLCHAIN_NAME", "arm-linux-androideabi-4.9"),
- ("ANDROID_NATIVE_API_LEVEL", "21"),
- (
- "CMAKE_TOOLCHAIN_FILE",
- "${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake",
- ),
- ("ANDROID_STL", "c++_shared"),
- ]),
- ("x86", &[
- ("ANDROID_TOOLCHAIN_NAME", "x86-linux-android-4.9"),
- ("ANDROID_NATIVE_API_LEVEL", "21"),
- (
- "CMAKE_TOOLCHAIN_FILE",
- "${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake",
- ),
- ("ANDROID_STL", "c++_shared"),
- ]),
- ("x86_64", &[
- ("ANDROID_TOOLCHAIN_NAME", "x86_64-linux-android-4.9"),
- ("ANDROID_NATIVE_API_LEVEL", "21"),
- (
- "CMAKE_TOOLCHAIN_FILE",
- "${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake",
- ),
- ("ANDROID_STL", "c++_shared"),
- ]),
+//
+// Android NDK < 18 with GCC.
+const CMAKE_PARAMS_ANDROID_NDK_OLD_GCC: &[(&str, &[(&str, &str)])] = &[
+ ("aarch64", &[(
+ "ANDROID_TOOLCHAIN_NAME",
+ "aarch64-linux-android-4.9",
+ )]),
+ ("arm", &[(
+ "ANDROID_TOOLCHAIN_NAME",
+ "arm-linux-androideabi-4.9",
+ )]),
+ ("x86", &[(
+ "ANDROID_TOOLCHAIN_NAME",
+ "x86-linux-android-4.9",
+ )]),
+ ("x86_64", &[(
+ "ANDROID_TOOLCHAIN_NAME",
+ "x86_64-linux-android-4.9",
+ )]),
+];
+
+// Android NDK >= 19.
+const CMAKE_PARAMS_ANDROID_NDK: &[(&str, &[(&str, &str)])] = &[
+ ("aarch64", &[("ANDROID_ABI", "arm64-v8a")]),
+ ("arm", &[("ANDROID_ABI", "armeabi-v7a")]),
+ ("x86", &[("ANDROID_ABI", "x86")]),
+ ("x86_64", &[("ANDROID_ABI", "x86_64")]),
];
const CMAKE_PARAMS_IOS: &[(&str, &[(&str, &str)])] = &[
@@ -87,19 +77,32 @@
// Add platform-specific parameters.
return match os.as_ref() {
"android" => {
+ let mut cmake_params_android = CMAKE_PARAMS_ANDROID_NDK;
+ if cfg!(feature = "ndk-old-gcc") {
+ cmake_params_android = CMAKE_PARAMS_ANDROID_NDK_OLD_GCC;
+ }
+
// We need ANDROID_NDK_HOME to be set properly.
let android_ndk_home = std::env::var("ANDROID_NDK_HOME")
.expect("Please set ANDROID_NDK_HOME for Android build");
- for (android_arch, params) in CMAKE_PARAMS_ANDROID {
+ let android_ndk_home = std::path::Path::new(&android_ndk_home);
+ for (android_arch, params) in cmake_params_android {
if *android_arch == arch {
for (name, value) in *params {
- let value = value
- .replace("${ANDROID_NDK_HOME}", &android_ndk_home);
eprintln!("android arch={} add {}={}", arch, name, value);
boringssl_cmake.define(name, value);
}
}
}
+ let toolchain_file =
+ android_ndk_home.join("build/cmake/android.toolchain.cmake");
+ let toolchain_file = toolchain_file.to_str().unwrap();
+ eprintln!("android toolchain={}", toolchain_file);
+ boringssl_cmake.define("CMAKE_TOOLCHAIN_FILE", toolchain_file);
+
+ // 21 is the minimum level tested. You can give higher value.
+ boringssl_cmake.define("ANDROID_NATIVE_API_LEVEL", "21");
+ boringssl_cmake.define("ANDROID_STL", "c++_shared");
boringssl_cmake
},
diff --git a/tools/build_android_ndk19.sh b/tools/build_android_ndk19.sh
new file mode 100755
index 0000000..aff1dec
--- /dev/null
+++ b/tools/build_android_ndk19.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Build quiche for Android NDK 19 or higher
+#
+# ANDROID_NDK_HOME : android ndk location
+# TOOLCHAIN_DIR : where create a toolchain (optional)
+#
+set -eu
+
+# Change this value if you need a different API level
+# 21 is the minimum API tested
+API_LEVEL=21
+
+if [ ! -d "${ANDROID_NDK_HOME-}" ]; then
+ ANDROID_NDK_HOME=/usr/local/share/android-ndk
+fi
+
+if [ ! -d "${TOOLCHAIN_DIR-}" ]; then
+ TOOLCHAIN_DIR=$(pwd)
+fi
+
+echo "> building quiche for android API $API_LEVEL..."
+
+for target in \
+ aarch64-linux-android \
+ armv7-linux-androideabi \
+ i686-linux-android
+do
+ echo "> buliding $target..."
+ cargo ndk --target $target --android-platform $API_LEVEL -- build $*
+done
diff --git a/tools/setup_android.sh b/tools/setup_android.sh
index c8eda8f..8ca4868 100755
--- a/tools/setup_android.sh
+++ b/tools/setup_android.sh
@@ -7,6 +7,10 @@
#
set -eu
+# Change this value if you need a different API level
+# 21 is the minimum API tested
+API_LEVEL=21
+
if [ ! -d "${ANDROID_NDK_HOME-}" ]; then
ANDROID_NDK_HOME=/usr/local/share/android-ndk
fi
@@ -31,9 +35,9 @@
echo "> Toolchain Directory: ${TOOLCHAIN_DIR}"
mkdir -p ${TOOLCHAIN_DIR}/arch
-make_standalone_toolchain arm64 21
-make_standalone_toolchain arm 21
-make_standalone_toolchain x86 21
+make_standalone_toolchain arm64 $API_LEVEL
+make_standalone_toolchain arm $API_LEVEL
+make_standalone_toolchain x86 $API_LEVEL
CARGO_CONFIG=cargo-config.toml
sed 's@$TOOLCHAIN_DIR@'"${TOOLCHAIN_DIR}"'@g' > $CARGO_CONFIG <<CARGO_CONFIG_EOF