diff --git a/.travis.yml b/.travis.yml index 3af2de3e3..b7f043af3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,11 @@ matrix: - env: TARGET=x86_64-unknown-linux-musl STD=1 OPENSSL=0.5.5 RUN=1 DEPLOY=1 # Android - - env: TARGET=aarch64-linux-android CPP=1 STD=1 OPENSSL=0.5.5 - - env: TARGET=arm-linux-androideabi CPP=1 STD=1 OPENSSL=0.5.5 - - env: TARGET=armv7-linux-androideabi CPP=1 STD=1 OPENSSL=0.5.5 - - env: TARGET=i686-linux-android CPP=1 STD=1 OPENSSL=0.5.5 - - env: TARGET=x86_64-linux-android CPP=1 STD=1 OPENSSL=0.5.5 + - env: TARGET=aarch64-linux-android CPP=1 STD=1 OPENSSL=0.5.5 RUN=1 + - env: TARGET=arm-linux-androideabi CPP=1 STD=1 OPENSSL=0.5.5 RUN=1 + - env: TARGET=armv7-linux-androideabi CPP=1 STD=1 OPENSSL=0.5.5 RUN=1 + - env: TARGET=i686-linux-android CPP=1 STD=1 OPENSSL=0.5.5 RUN=1 + - env: TARGET=x86_64-linux-android CPP=1 STD=1 OPENSSL=0.5.5 RUN=1 # OSX - env: TARGET=i686-apple-darwin DYLIB=1 STD=1 RUN=1 diff --git a/README.md b/README.md index ed4426baf..f0a29d869 100644 --- a/README.md +++ b/README.md @@ -189,16 +189,16 @@ worst, "hang" (never terminate). | Target | libc | GCC | OpenSSL | C++ | QEMU | `test` | |--------------------------------------|--------|---------|---------|:---:|-------|:------:| -| `aarch64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | | +| `aarch64-linux-android` [5] | N/A | 4.9 | 1.0.2k | ✓ | N/A | ✓ | | `aarch64-unknown-linux-gnu` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ | -| `arm-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | | +| `arm-linux-androideabi` [5] | N/A | 4.9 | 1.0.2k | ✓ | N/A | ✓ | | `arm-unknown-linux-gnueabi` | 2.19 | 4.8.2 | 1.0.2k | ✓ | 2.8.0 | ✓ | | `arm-unknown-linux-musleabi` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ | -| `armv7-linux-androideabi` | N/A | 4.9 | 1.0.2k | ✓ | N/A | | +| `armv7-linux-androideabi` [5] | N/A | 4.9 | 1.0.2k | ✓ | N/A | ✓ | | `armv7-unknown-linux-gnueabihf` | 2.15 | 4.6.2 | 1.0.2k | ✓ | 2.8.0 | ✓ | | `armv7-unknown-linux-musleabihf` | 1.1.15 | 5.3.1 | N/A | | 2.8.0 | ✓ | | `asmjs-unknown-emscripten` [4] | 1.1.15 | 1.37.13 | N/A | ✓ | N/A | ✓ | -| `i686-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | | +| `i686-linux-android` [5] | N/A | 4.9 | 1.0.2k | ✓ | N/A | ✓ | | `i686-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ | | `i686-unknown-freebsd` [1] | 10.2 | 5.3.0 | 1.0.2k | | N/A | | | `i686-unknown-linux-gnu` | 2.15 | 4.6.2 | 1.0.2k | ✓ | N/A | ✓ | @@ -218,7 +218,7 @@ worst, "hang" (never terminate). | `thumbv7em-none-eabihf` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | | | `thumbv7m-none-eabi` [3] | 2.2.0 | 5.3.1 | N/A | | N/A | | | `wasm32-unknown-emscripten` [4] | 1.1.15 | 1.37.13 | N/A | ✓ | N/A | ✓ | -| `x86_64-linux-android` | N/A | 4.9 | 1.0.2k | ✓ | N/A | | +| `x86_64-linux-android` [5] | N/A | 4.9 | 1.0.2k | ✓ | N/A | ✓ | | `x86_64-pc-windows-gnu` | N/A | 6.2.0 | N/A | ✓ | N/A | ✓ | | `x86_64-sun-solaris` [1] | 2.11 | 5.3.0 | 1.0.2k | | N/A | | | `x86_64-unknown-dragonfly` [1] [2] | 4.6.0 | 5.3.0 | 1.0.2k | | N/A | ✓ | @@ -237,6 +237,12 @@ where libc was extracted. [4] libc = musl, gcc = emcc; Some projects that use libc may fail due to wrong definitions (will be fixed by https://github.com/rust-lang/libc/pull/610) +[5] Only works with native tests, that is, tests that do not depends on the + Android Runtime. For i686 some tests may fails with the error `assertion + failed: signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR`, see + [issue #140](https://github.com/japaric/cross/issues/140) for more + information. + ## Debugging ### QEMU_STRACE (v0.1.9+) diff --git a/docker/aarch64-linux-android/Dockerfile b/docker/aarch64-linux-android/Dockerfile index 2ba40d1df..ae246a658 100644 --- a/docker/aarch64-linux-android/Dockerfile +++ b/docker/aarch64-linux-android/Dockerfile @@ -12,6 +12,9 @@ RUN apt-get update && \ COPY xargo.sh / RUN bash /xargo.sh +COPY qemu.sh / +RUN bash /qemu.sh aarch64 android + COPY android-ndk.sh / RUN bash /android-ndk.sh arm64 21 ENV PATH=$PATH:/android-ndk/bin @@ -19,9 +22,13 @@ ENV PATH=$PATH:/android-ndk/bin COPY openssl.sh / RUN bash /openssl.sh linux-generic64 aarch64-linux-android- -mandroid -fomit-frame-pointer +COPY android-system.sh / +RUN bash /android-system.sh arm64 + # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android-gcc \ + CARGO_TARGET_AARCH64_LINUX_ANDROID_RUNNER=qemu-aarch64 \ CC_aarch64_linux_android=aarch64-linux-android-gcc \ CXX_aarch64_linux_android=aarch64-linux-android-g++ \ DEP_Z_ROOT=/android-ndk/sysroot/usr/ \ @@ -30,4 +37,7 @@ ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android-gcc \ OPENSSL_INCLUDE_DIR=/openssl/include \ OPENSSL_LIB_DIR=/openssl/lib \ RUST_TEST_THREADS=1 \ - HOME=/tmp/ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_ROOT=/system \ + ANDROID_DATA=/ diff --git a/docker/android-system.sh b/docker/android-system.sh new file mode 100644 index 000000000..08facb07d --- /dev/null +++ b/docker/android-system.sh @@ -0,0 +1,102 @@ +set -ex + +main() { + local arch=$1 + local td=$(mktemp -d) + pushd $td + + local dependencies=( + ca-certificates + curl + gcc-multilib + git + g++-multilib + make + python + ) + + # fake java and javac, it is not necessary for what we build, but the build + # script ask for it + cat << EOF > /usr/bin/java +#!/bin/bash +echo "java version \"1.7.0\"" +echo "OpenJDK Runtime Environment (IcedTea 2.6.9)" +echo "OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)" +EOF + + cat << EOF > /usr/bin/javac +#!/bin/bash +echo "javac 1.7.0" +EOF + + chmod +x /usr/bin/java + chmod +x /usr/bin/javac + + # more faking + export ANDROID_JAVA_HOME=/tmp + mkdir /tmp/lib/ + touch /tmp/lib/tools.jar + + apt-get update + local purge_list=(default-jre) + for dep in ${dependencies[@]}; do + if ! dpkg -L $dep; then + apt-get install --no-install-recommends -y $dep + purge_list+=( $dep ) + fi + done + + curl -O https://storage.googleapis.com/git-repo-downloads/repo + chmod +x repo + + # this is the minimum set of modules that are need to build bionic + # this was created by trial and error + ./repo init -u https://android.googlesource.com/platform/manifest -b android-5.0.0_r1 + ./repo sync bionic + ./repo sync build + ./repo sync external/compiler-rt + ./repo sync external/jemalloc + ./repo sync external/libcxx + ./repo sync external/libcxxabi + ./repo sync external/stlport + ./repo sync prebuilts/clang/linux-x86/host/3.5 + ./repo sync system/core + case $arch in + arm) + ./repo sync prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8 + ;; + arm64) + ./repo sync prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8 + ./repo sync prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 + ;; + x86) + ./repo sync prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8 + ;; + x86_64) + ./repo sync prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8 + ;; + esac + + # avoid build tests + rm bionic/linker/tests/Android.mk bionic/tests/Android.mk + + source build/envsetup.sh + lunch aosp_$arch-user + mmma bionic/ + + if [ $arch = "arm" ]; then + mv out/target/product/generic/system/ / + else + mv out/target/product/generic_$arch/system/ / + fi + + # clean up + apt-get purge --auto-remove -y ${purge_list[@]} + + popd + + rm -rf $td + rm $0 +} + +main "${@}" diff --git a/docker/arm-linux-androideabi/Dockerfile b/docker/arm-linux-androideabi/Dockerfile index 141a89721..18b1c1929 100644 --- a/docker/arm-linux-androideabi/Dockerfile +++ b/docker/arm-linux-androideabi/Dockerfile @@ -12,6 +12,9 @@ RUN apt-get update && \ COPY xargo.sh / RUN bash /xargo.sh +COPY qemu.sh / +RUN bash /qemu.sh arm android + COPY android-ndk.sh / RUN bash /android-ndk.sh arm 21 ENV PATH=$PATH:/android-ndk/bin @@ -19,9 +22,13 @@ ENV PATH=$PATH:/android-ndk/bin COPY openssl.sh / RUN bash /openssl.sh android arm-linux-androideabi- +COPY android-system.sh / +RUN bash /android-system.sh arm + # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \ + CARGO_TARGET_ARM_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ CC_arm_linux_androideabi=arm-linux-androideabi-gcc \ CXX_arm_linux_androideabi=arm-linux-androideabi-g++ \ DEP_Z_ROOT=/android-ndk/sysroot/usr/ \ @@ -30,4 +37,7 @@ ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \ OPENSSL_INCLUDE_DIR=/openssl/include \ OPENSSL_LIB_DIR=/openssl/lib \ RUST_TEST_THREADS=1 \ - HOME=/tmp/ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_ROOT=/system \ + ANDROID_DATA=/ diff --git a/docker/armv7-linux-androideabi/Dockerfile b/docker/armv7-linux-androideabi/Dockerfile index 535910add..037552f82 100644 --- a/docker/armv7-linux-androideabi/Dockerfile +++ b/docker/armv7-linux-androideabi/Dockerfile @@ -12,6 +12,9 @@ RUN apt-get update && \ COPY xargo.sh / RUN bash /xargo.sh +COPY qemu.sh / +RUN bash /qemu.sh arm android + COPY android-ndk.sh / RUN bash /android-ndk.sh arm 21 ENV PATH=$PATH:/android-ndk/bin @@ -19,9 +22,13 @@ ENV PATH=$PATH:/android-ndk/bin COPY openssl.sh / RUN bash /openssl.sh android-armv7 arm-linux-androideabi- +COPY android-system.sh / +RUN bash /android-system.sh arm + # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT ENV CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \ + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUNNER=qemu-arm \ CC_armv7_linux_androideabi=arm-linux-androideabi-gcc \ CXX_armv7_linux_androideabi=arm-linux-androideabi-g++ \ DEP_Z_ROOT=/android-ndk/sysroot/usr/ \ @@ -30,4 +37,7 @@ ENV CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \ OPENSSL_INCLUDE_DIR=/openssl/include \ OPENSSL_LIB_DIR=/openssl/lib \ RUST_TEST_THREADS=1 \ - HOME=/tmp/ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_ROOT=/system \ + ANDROID_DATA=/ diff --git a/docker/i686-linux-android/Dockerfile b/docker/i686-linux-android/Dockerfile index d1f15fa2a..34e5d6e4a 100644 --- a/docker/i686-linux-android/Dockerfile +++ b/docker/i686-linux-android/Dockerfile @@ -12,16 +12,31 @@ RUN apt-get update && \ COPY xargo.sh / RUN bash /xargo.sh +# We could supposedly directly run i686 binaries like we do for x86_64, but +# doing so generates an assertion failure: +# ... assertion failed: signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR +# ... src/libstd/sys/unix/mod.rs +# fatal runtime error: failed to initiate panic, error 5 +# +# Running with qemu works as expected +COPY qemu.sh / +RUN bash /qemu.sh i386 android + COPY android-ndk.sh / RUN bash /android-ndk.sh x86 21 ENV PATH=$PATH:/android-ndk/bin +# Build with no-asm to make openssl linked binaries position-independent (PIE) COPY openssl.sh / -RUN bash /openssl.sh android-x86 i686-linux-android- +RUN bash /openssl.sh android-x86 i686-linux-android- no-asm + +COPY android-system.sh / +RUN bash /android-system.sh x86 # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT ENV CARGO_TARGET_I686_LINUX_ANDROID_LINKER=i686-linux-android-gcc \ + CARGO_TARGET_I686_LINUX_ANDROID_RUNNER=qemu-i386 \ CC_i686_linux_android=i686-linux-android-gcc \ CXX_i686_linux_android=i686-linux-android-g++ \ DEP_Z_ROOT=/android-ndk/sysroot/usr/ \ @@ -30,4 +45,7 @@ ENV CARGO_TARGET_I686_LINUX_ANDROID_LINKER=i686-linux-android-gcc \ OPENSSL_INCLUDE_DIR=/openssl/include \ OPENSSL_LIB_DIR=/openssl/lib \ RUST_TEST_THREADS=1 \ - HOME=/tmp/ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_ROOT=/system \ + ANDROID_DATA=/ diff --git a/docker/qemu.sh b/docker/qemu.sh index b3ae1211e..453043c55 100644 --- a/docker/qemu.sh +++ b/docker/qemu.sh @@ -1,9 +1,10 @@ set -ex main() { - local version=2.9.0 + local version=2.10.0 local arch=$1 \ + os=$2 \ td=$(mktemp -d) local dependencies=( @@ -15,6 +16,7 @@ main() { libglib2.0-dev libtool make + patch pkg-config zlib1g-dev ) @@ -32,6 +34,78 @@ main() { curl -L http://wiki.qemu-project.org/download/qemu-$version.tar.bz2 | \ tar --strip-components=1 -xj + + # Allow qemu to run android (bionic libc) binaries + # https://lists.nongnu.org/archive/html/qemu-trivial/2017-10/msg00025.html + # https://lists.nongnu.org/archive/html/qemu-trivial/2017-10/msg00023.html + if [[ "$os" == "android" ]]; then + patch -p1 <<'EOF' +diff -ur qemu-2.10.0/linux-user/elfload.c qemu-2.10.0.new/linux-user/elfload.c +--- qemu-2.10.0/linux-user/elfload.c 2017-09-27 11:27:13.866595788 -0300 ++++ qemu-2.10.0.new/linux-user/elfload.c 2017-09-27 11:58:30.662613425 -0300 +@@ -1354,7 +1354,7 @@ + ~(abi_ulong)(TARGET_ELF_EXEC_PAGESIZE-1)) + #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) + +-#define DLINFO_ITEMS 14 ++#define DLINFO_ITEMS 15 + + static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) + { +@@ -1782,6 +1782,7 @@ + NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); + NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); + NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes); ++ NEW_AUX_ENT(AT_SECURE, (abi_ulong) (getuid() != geteuid() || getgid() != getegid())); + + #ifdef ELF_HWCAP2 + NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2); +diff -ur qemu-2.10.0/linux-user/ioctls.h qemu-2.10.0.new/linux-user/ioctls.h +--- qemu-2.10.0/linux-user/ioctls.h 2017-09-27 11:27:13.858595669 -0300 ++++ qemu-2.10.0.new/linux-user/ioctls.h 2017-09-27 11:43:40.613299859 -0300 +@@ -173,6 +173,11 @@ + IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval))) + IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec))) + ++ IOCTL(RNDGETENTCNT, IOC_R, MK_PTR(TYPE_INT)) ++ IOCTL(RNDADDTOENTCNT, IOC_W, MK_PTR(TYPE_INT)) ++ IOCTL(RNDZAPENTCNT, 0, TYPE_NULL) ++ IOCTL(RNDCLEARPOOL, 0, TYPE_NULL) ++ + IOCTL(CDROMPAUSE, 0, TYPE_NULL) + IOCTL(CDROMSTART, 0, TYPE_NULL) + IOCTL(CDROMSTOP, 0, TYPE_NULL) +diff -ur qemu-2.10.0/linux-user/syscall.c qemu-2.10.0.new/linux-user/syscall.c +--- qemu-2.10.0/linux-user/syscall.c 2017-09-27 11:27:13.862595729 -0300 ++++ qemu-2.10.0.new/linux-user/syscall.c 2017-09-27 11:44:26.133987660 -0300 +@@ -59,6 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, + #include + #include + #include ++#include + #include "qemu-common.h" + #ifdef CONFIG_TIMERFD + #include +diff -ur qemu-2.10.0/linux-user/syscall_defs.h qemu-2.10.0.new/linux-user/syscall_defs.h +--- qemu-2.10.0/linux-user/syscall_defs.h 2017-09-27 11:27:13.862595729 -0300 ++++ qemu-2.10.0.new/linux-user/syscall_defs.h 2017-09-27 11:46:09.303545817 -0300 +@@ -1060,6 +1060,13 @@ struct target_pollfd { + + #define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ + ++/* From */ ++ ++#define TARGET_RNDGETENTCNT TARGET_IOR('R', 0x00, int) ++#define TARGET_RNDADDTOENTCNT TARGET_IOW('R', 0x01, int) ++#define TARGET_RNDZAPENTCNT TARGET_IO('R', 0x04) ++#define TARGET_RNDCLEARPOOL TARGET_IO('R', 0x06) ++ + /* From */ + + #define TARGET_BLKROSET TARGET_IO(0x12,93) /* set device read-only (0 = read-write) */ +EOF + fi + ./configure \ --disable-kvm \ --disable-vnc \ diff --git a/docker/x86_64-linux-android/Dockerfile b/docker/x86_64-linux-android/Dockerfile index 738eeefc9..d29c328ce 100644 --- a/docker/x86_64-linux-android/Dockerfile +++ b/docker/x86_64-linux-android/Dockerfile @@ -19,6 +19,9 @@ ENV PATH=$PATH:/android-ndk/bin COPY openssl.sh / RUN bash /openssl.sh linux-x86_64 x86_64-linux-android- -mandroid -fomit-frame-pointer +COPY android-system.sh / +RUN bash /android-system.sh x86_64 + # Libz is distributed in the android ndk, but for some unknown reason it is not # found in the build process of some crates, so we explicit set the DEP_Z_ROOT ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-gcc \ @@ -29,5 +32,7 @@ ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER=x86_64-linux-android-gcc \ OPENSSL_DIR=/openssl \ OPENSSL_INCLUDE_DIR=/openssl/include \ OPENSSL_LIB_DIR=/openssl/lib \ - RUST_TEST_THREADS=1 \ - HOME=/tmp/ + HOME=/tmp/ \ + TMPDIR=/tmp/ \ + ANDROID_ROOT=/system \ + ANDROID_DATA=/