1
Fork 0

ci: Upgrade Android SDK/NDK and refactor to use sdkmanager/avdmanager.

* SDK tools is upgraded to 27.0.0.
   - Refactored to use `sdkmanager`/`avdmanager` instead of the deprecated
     `android` tool.

* The Java version used by Android SDK is downgraded to OpenJDK-8, in order
  to download the SDK through HTTPS.

* NDK is upgrade to r15c.
   - Dropped support for android-9 (2.3 / Gingerbread), the minimal
     supported version is now android-14 (4.0 / Ice Cream Sandwich).
   - Changed the default Android compiler from GCC to clang.
   - For details of change introduced by NDK r15, see
     https://github.com/android-ndk/ndk/wiki/Changelog-r15.
This commit is contained in:
kennytm 2017-10-28 03:14:25 +08:00
parent 2e6a1a9fb4
commit c46b04cbdd
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C
8 changed files with 97 additions and 52 deletions

View file

@ -84,7 +84,7 @@ pub fn find(build: &mut Build) {
if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
cfg.compiler(cc); cfg.compiler(cc);
} else { } else {
set_compiler(&mut cfg, "gcc", target, config, build); set_compiler(&mut cfg, Language::C, target, config, build);
} }
let compiler = cfg.get_compiler(); let compiler = cfg.get_compiler();
@ -112,7 +112,7 @@ pub fn find(build: &mut Build) {
if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
cfg.compiler(cxx); cfg.compiler(cxx);
} else { } else {
set_compiler(&mut cfg, "g++", host, config, build); set_compiler(&mut cfg, Language::CPlusPlus, host, config, build);
} }
let compiler = cfg.get_compiler(); let compiler = cfg.get_compiler();
build.verbose(&format!("CXX_{} = {:?}", host, compiler.path())); build.verbose(&format!("CXX_{} = {:?}", host, compiler.path()));
@ -121,7 +121,7 @@ pub fn find(build: &mut Build) {
} }
fn set_compiler(cfg: &mut cc::Build, fn set_compiler(cfg: &mut cc::Build,
gnu_compiler: &str, compiler: Language,
target: Interned<String>, target: Interned<String>,
config: Option<&Target>, config: Option<&Target>,
build: &Build) { build: &Build) {
@ -132,7 +132,7 @@ fn set_compiler(cfg: &mut cc::Build,
t if t.contains("android") => { t if t.contains("android") => {
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) { if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
let target = target.replace("armv7", "arm"); let target = target.replace("armv7", "arm");
let compiler = format!("{}-{}", target, gnu_compiler); let compiler = format!("{}-{}", target, compiler.clang());
cfg.compiler(ndk.join("bin").join(compiler)); cfg.compiler(ndk.join("bin").join(compiler));
} }
} }
@ -141,6 +141,7 @@ fn set_compiler(cfg: &mut cc::Build,
// which is a gcc version from ports, if this is the case. // which is a gcc version from ports, if this is the case.
t if t.contains("openbsd") => { t if t.contains("openbsd") => {
let c = cfg.get_compiler(); let c = cfg.get_compiler();
let gnu_compiler = compiler.gcc();
if !c.path().ends_with(gnu_compiler) { if !c.path().ends_with(gnu_compiler) {
return return
} }
@ -183,3 +184,29 @@ fn set_compiler(cfg: &mut cc::Build,
_ => {} _ => {}
} }
} }
/// The target programming language for a native compiler.
enum Language {
/// The compiler is targeting C.
C,
/// The compiler is targeting C++.
CPlusPlus,
}
impl Language {
/// Obtains the name of a compiler in the GCC collection.
fn gcc(self) -> &'static str {
match self {
Language::C => "gcc",
Language::CPlusPlus => "g++",
}
}
/// Obtains the name of a compiler in the clang suite.
fn clang(self) -> &'static str {
match self {
Language::C => "clang",
Language::CPlusPlus => "clang++",
}
}
}

View file

@ -5,21 +5,27 @@ RUN sh /scripts/android-base-apt-get.sh
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9 download_and_make_toolchain android-ndk-r15c-linux-x86_64.zip arm 14
# Note:
# Do not upgrade to `openjdk-9-jre-headless`, as it will cause certificate error
# when installing the Android SDK (see PR #45193). This is unfortunate, but
# every search result suggested either disabling HTTPS or replacing JDK 9 by
# JDK 8 as the solution (e.g. https://stackoverflow.com/q/41421340). :|
RUN dpkg --add-architecture i386 && \ RUN dpkg --add-architecture i386 && \
apt-get update && \ apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
libgl1-mesa-glx \ libgl1-mesa-glx \
libpulse0 \ libpulse0 \
libstdc++6:i386 \ libstdc++6:i386 \
openjdk-9-jre-headless \ openjdk-8-jre-headless \
tzdata tzdata
COPY scripts/android-sdk.sh /scripts/ COPY scripts/android-sdk.sh /scripts/
RUN . /scripts/android-sdk.sh && \ RUN . /scripts/android-sdk.sh && \
download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18 download_and_create_avd 4333796 armeabi-v7a 18
ENV PATH=$PATH:/android/sdk/emulator
ENV PATH=$PATH:/android/sdk/tools ENV PATH=$PATH:/android/sdk/tools
ENV PATH=$PATH:/android/sdk/platform-tools ENV PATH=$PATH:/android/sdk/platform-tools
@ -27,7 +33,7 @@ ENV TARGETS=arm-linux-androideabi
ENV RUST_CONFIGURE_ARGS \ ENV RUST_CONFIGURE_ARGS \
--target=$TARGETS \ --target=$TARGETS \
--arm-linux-androideabi-ndk=/android/ndk/arm-9 --arm-linux-androideabi-ndk=/android/ndk/arm-14
ENV SCRIPT python2.7 ../x.py test --target $TARGETS ENV SCRIPT python2.7 ../x.py test --target $TARGETS

View file

@ -5,7 +5,7 @@ RUN sh /scripts/android-base-apt-get.sh
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21 download_and_make_toolchain android-ndk-r15c-linux-x86_64.zip arm64 21
ENV PATH=$PATH:/android/ndk/arm64-21/bin ENV PATH=$PATH:/android/ndk/arm64-21/bin

View file

@ -5,17 +5,17 @@ RUN sh /scripts/android-base-apt-get.sh
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_ndk android-ndk-r13b-linux-x86_64.zip && \ download_ndk android-ndk-r15c-linux-x86_64.zip && \
make_standalone_toolchain arm 9 && \ make_standalone_toolchain arm 14 && \
make_standalone_toolchain arm 21 && \ make_standalone_toolchain arm 21 && \
remove_ndk remove_ndk
RUN chmod 777 /android/ndk && \ RUN chmod 777 /android/ndk && \
ln -s /android/ndk/arm-21 /android/ndk/arm ln -s /android/ndk/arm-21 /android/ndk/arm
ENV PATH=$PATH:/android/ndk/arm-9/bin ENV PATH=$PATH:/android/ndk/arm-14/bin
ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/arm-14/sysroot/usr/
ENV HOSTS=armv7-linux-androideabi ENV HOSTS=armv7-linux-androideabi
@ -27,18 +27,18 @@ ENV RUST_CONFIGURE_ARGS \
--enable-extended \ --enable-extended \
--enable-cargo-openssl-static --enable-cargo-openssl-static
# We support api level 9, but api level 21 is required to build llvm. To # We support api level 14, but api level 21 is required to build llvm. To
# overcome this problem we use a ndk with api level 21 to build llvm and then # overcome this problem we use a ndk with api level 21 to build llvm and then
# switch to a ndk with api level 9 to complete the build. When the linker is # switch to a ndk with api level 14 to complete the build. When the linker is
# invoked there are missing symbols (like sigsetempty, not available with api # invoked there are missing symbols (like sigsetempty, not available with api
# level 9), the default linker behavior is to generate an error, to allow the # level 14), the default linker behavior is to generate an error, to allow the
# build to finish we use --warn-unresolved-symbols. Note that the missing # build to finish we use --warn-unresolved-symbols. Note that the missing
# symbols does not affect std, only the compiler (llvm) and cargo (openssl). # symbols does not affect std, only the compiler (llvm) and cargo (openssl).
ENV SCRIPT \ ENV SCRIPT \
python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
(export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
rm /android/ndk/arm && \ rm /android/ndk/arm && \
ln -s /android/ndk/arm-9 /android/ndk/arm && \ ln -s /android/ndk/arm-14 /android/ndk/arm && \
python2.7 ../x.py dist --host $HOSTS --target $HOSTS) python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
COPY scripts/sccache.sh /scripts/ COPY scripts/sccache.sh /scripts/

View file

@ -5,17 +5,17 @@ RUN sh /scripts/android-base-apt-get.sh
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_ndk android-ndk-r13b-linux-x86_64.zip && \ download_ndk android-ndk-r15c-linux-x86_64.zip && \
make_standalone_toolchain x86 9 && \ make_standalone_toolchain x86 14 && \
make_standalone_toolchain x86 21 && \ make_standalone_toolchain x86 21 && \
remove_ndk remove_ndk
RUN chmod 777 /android/ndk && \ RUN chmod 777 /android/ndk && \
ln -s /android/ndk/x86-21 /android/ndk/x86 ln -s /android/ndk/x86-21 /android/ndk/x86
ENV PATH=$PATH:/android/ndk/x86-9/bin ENV PATH=$PATH:/android/ndk/x86-14/bin
ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/ ENV DEP_Z_ROOT=/android/ndk/x86-14/sysroot/usr/
ENV HOSTS=i686-linux-android ENV HOSTS=i686-linux-android
@ -27,18 +27,18 @@ ENV RUST_CONFIGURE_ARGS \
--enable-extended \ --enable-extended \
--enable-cargo-openssl-static --enable-cargo-openssl-static
# We support api level 9, but api level 21 is required to build llvm. To # We support api level 14, but api level 21 is required to build llvm. To
# overcome this problem we use a ndk with api level 21 to build llvm and then # overcome this problem we use a ndk with api level 21 to build llvm and then
# switch to a ndk with api level 9 to complete the build. When the linker is # switch to a ndk with api level 14 to complete the build. When the linker is
# invoked there are missing symbols (like sigsetempty, not available with api # invoked there are missing symbols (like sigsetempty, not available with api
# level 9), the default linker behavior is to generate an error, to allow the # level 14), the default linker behavior is to generate an error, to allow the
# build to finish we use --warn-unresolved-symbols. Note that the missing # build to finish we use --warn-unresolved-symbols. Note that the missing
# symbols does not affect std, only the compiler (llvm) and cargo (openssl). # symbols does not affect std, only the compiler (llvm) and cargo (openssl).
ENV SCRIPT \ ENV SCRIPT \
python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \
(export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \
rm /android/ndk/x86 && \ rm /android/ndk/x86 && \
ln -s /android/ndk/x86-9 /android/ndk/x86 && \ ln -s /android/ndk/x86-14 /android/ndk/x86 && \
python2.7 ../x.py dist --host $HOSTS --target $HOSTS) python2.7 ../x.py dist --host $HOSTS --target $HOSTS)
COPY scripts/sccache.sh /scripts/ COPY scripts/sccache.sh /scripts/

View file

@ -5,7 +5,7 @@ RUN sh /scripts/android-base-apt-get.sh
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21 download_and_make_toolchain android-ndk-r15c-linux-x86_64.zip x86_64 21
ENV PATH=$PATH:/android/ndk/x86_64-21/bin ENV PATH=$PATH:/android/ndk/x86_64-21/bin

View file

@ -6,9 +6,9 @@ RUN sh /scripts/android-base-apt-get.sh
# ndk # ndk
COPY scripts/android-ndk.sh /scripts/ COPY scripts/android-ndk.sh /scripts/
RUN . /scripts/android-ndk.sh && \ RUN . /scripts/android-ndk.sh && \
download_ndk android-ndk-r13b-linux-x86_64.zip && \ download_ndk android-ndk-r15c-linux-x86_64.zip && \
make_standalone_toolchain arm 9 && \ make_standalone_toolchain arm 14 && \
make_standalone_toolchain x86 9 && \ make_standalone_toolchain x86 14 && \
make_standalone_toolchain arm64 21 && \ make_standalone_toolchain arm64 21 && \
make_standalone_toolchain x86_64 21 && \ make_standalone_toolchain x86_64 21 && \
remove_ndk remove_ndk
@ -23,9 +23,9 @@ ENV TARGETS=$TARGETS,x86_64-linux-android
ENV RUST_CONFIGURE_ARGS \ ENV RUST_CONFIGURE_ARGS \
--target=$TARGETS \ --target=$TARGETS \
--enable-extended \ --enable-extended \
--arm-linux-androideabi-ndk=/android/ndk/arm-9 \ --arm-linux-androideabi-ndk=/android/ndk/arm-14 \
--armv7-linux-androideabi-ndk=/android/ndk/arm-9 \ --armv7-linux-androideabi-ndk=/android/ndk/arm-14 \
--i686-linux-android-ndk=/android/ndk/x86-9 \ --i686-linux-android-ndk=/android/ndk/x86-14 \
--aarch64-linux-android-ndk=/android/ndk/arm64-21 \ --aarch64-linux-android-ndk=/android/ndk/arm64-21 \
--x86_64-linux-android-ndk=/android/ndk/x86_64-21 --x86_64-linux-android-ndk=/android/ndk/x86_64-21

View file

@ -10,40 +10,40 @@
set -ex set -ex
URL=https://dl.google.com/android/repository export ANDROID_HOME=/android/sdk
PATH=$PATH:"${ANDROID_HOME}/tools/bin"
download_sdk() { download_sdk() {
mkdir -p /android/sdk mkdir -p /android
cd /android/sdk curl -fo sdk.zip "https://dl.google.com/android/repository/sdk-tools-linux-$1.zip"
curl -fO $URL/$1 unzip -q sdk.zip -d "$ANDROID_HOME"
unzip -q $1 rm -f sdk.zip
rm -rf $1
} }
download_sysimage() { download_sysimage() {
# See https://developer.android.com/studio/tools/help/android.html
abi=$1 abi=$1
api=$2 api=$2
filter="platform-tools,android-$api" # See https://developer.android.com/studio/command-line/sdkmanager.html for
filter="$filter,sys-img-$abi-android-$api" # usage of `sdkmanager`.
#
# Keep printing yes to accept the licenses # The output from sdkmanager is so noisy that it will occupy all of the 4 MB
while true; do echo yes; sleep 10; done | \ # log extremely quickly. Thus we must silence all output.
/android/sdk/tools/android update sdk -a --no-ui \ yes | sdkmanager --licenses > /dev/null
--filter "$filter" --no-https sdkmanager platform-tools emulator \
"platforms;android-$api" \
"system-images;android-$api;default;$abi" > /dev/null
} }
create_avd() { create_avd() {
# See https://developer.android.com/studio/tools/help/android.html
abi=$1 abi=$1
api=$2 api=$2
echo no | \ # See https://developer.android.com/studio/command-line/avdmanager.html for
/android/sdk/tools/android create avd \ # usage of `avdmanager`.
--name $abi-$api \ echo no | avdmanager create avd \
--target android-$api \ -n "$abi-$api" \
--abi $abi -k "system-images;android-$api;default;$abi"
} }
download_and_create_avd() { download_and_create_avd() {
@ -51,3 +51,15 @@ download_and_create_avd() {
download_sysimage $2 $3 download_sysimage $2 $3
create_avd $2 $3 create_avd $2 $3
} }
# Usage:
#
# setup_android_sdk 4333796 armeabi-v7a 18
#
# 4333796 =>
# SDK tool version.
# Copy from https://developer.android.com/studio/index.html#command-tools
# armeabi-v7a =>
# System image ABI
# 18 =>
# Android API Level (18 = Android 4.3 = Jelly Bean MR2)