diff options
author | Frederik Carlier <frederik.carlier@quamotion.mobi> | 2017-02-07 19:19:31 +0100 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2017-02-07 19:19:31 +0100 |
commit | 05ec3cea1f58eec67f85de09e8869e9239e6c94d (patch) | |
tree | 25b31faf8fb7cb01c7a98869f1fbc9ecfec311eb | |
parent | 49e51a52fac3ee4e0f893b862b759473d3f5f2f6 (diff) | |
download | coreclr-05ec3cea1f58eec67f85de09e8869e9239e6c94d.tar.gz coreclr-05ec3cea1f58eec67f85de09e8869e9239e6c94d.tar.bz2 coreclr-05ec3cea1f58eec67f85de09e8869e9239e6c94d.zip |
Add scripts & docs which support creating an Android toolchain on Linux (#9175)
* Add scripts & docs which support creating an Android toolchain on Linux
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Documentation/building/android.md | 102 | ||||
-rwxr-xr-x | cross/build-android-rootfs.sh | 145 |
3 files changed, 248 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index 702c37daa3..f5d049b3d0 100644 --- a/.gitignore +++ b/.gitignore @@ -298,6 +298,7 @@ Makefile # Cross compilation cross/rootfs/* +cross/android-rootfs/* # add x86 as it is ignored in 'Build results' !cross/x86 diff --git a/Documentation/building/android.md b/Documentation/building/android.md new file mode 100644 index 0000000000..cfb509dc2f --- /dev/null +++ b/Documentation/building/android.md @@ -0,0 +1,102 @@ +Cross Compilation for Android on Linux +====================================== + +Through cross compilation, on Linux it is possible to build CoreCLR for arm64 Android. + +Requirements +------------ + +You'll need to generate a toolchain and a sysroot for Android. There's a script which takes care of the required steps. + +Generating the rootfs +--------------------- + +To generate the rootfs, run the following command in the `coreclr` folder: + +``` +cross/init-android-rootfs.sh +``` + +This will download the NDK and any packages required to compile Android on your system. It's over 1 GB of data, so it may take a while. + + +Cross compiling CoreCLR +----------------------- +Once the rootfs has been generated, it will be possible to cross compile CoreCLR. + +When cross compiling, you need to set both the `CONFIG_DIR` and `ROOTFS_DIR` variables. + +To compile for arm64, run: + +``` +CONFIG_DIR=`realpath cross/android/arm64` ROOTFS_DIR=`realpath cross/android-rootfs/toolchain/arm64/sysroot` ./build.sh cross arm64 skipgenerateversion skipmscorlib cmakeargs -DENABLE_LLDBPLUGIN=0 +``` + +The resulting binaries will be found in `bin/Product/Linux.BuildArch.BuildType/` + +Running the PAL tests on Android +-------------------------------- + +You can run the PAL tests on an Android device. To run the tests, you first copy the PAL tests to your Android phone using +`adb`, and then run them in an interactive Android shell using `adb shell`: + +To copy the PAL tests over to an Android phone: +``` +adb push bin/obj/Linux.arm64.Debug/src/pal/tests/palsuite/ /data/local/tmp/coreclr/src/pal/tests/palsuite +adb push cross/android/toolchain/arm64/sysroot/usr/lib/libuuid.so.1 /data/local/tmp/coreclr/lib +adb push cross/android/toolchain/arm64/sysroot/usr/lib/libintl.so /data/local/tmp/coreclr/lib +adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-support.so /data/local/tmp/coreclr/lib/ +adb push cross/android/toolchain/arm64/sysroot/usr/lib/libandroid-glob.so /data/local/tmp/coreclr/lib/ +adb push src/pal/tests/palsuite/paltestlist.txt /data/local/tmp/coreclr +adb push src/pal/tests/palsuite/runpaltests.sh /data/local/tmp/coreclr/ +``` + +Then, use `adb shell` to launch a shell on Android. Inside that shell, you can launch the PAL tests: +``` +LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib ./runpaltests.sh /data/local/tmp/coreclr/ +``` + +Debugging coreclr on Android +---------------------------- + +You can debug coreclr on Android using a remote lldb server which you run on your Android device. + +First, push the lldb server to Android: + +``` +adb push cross/android/lldb/2.2/android/arm64-v8a/lldb-server /data/local/tmp/ +``` + +Then, launch the lldb server on the Android device. Open a shell using `adb shell` and run: + +``` +adb shell +cd /data/local/tmp +./lldb-server platform --listen *:1234 +``` + +After that, you'll need to forward port 1234 from your Android device to your PC: +``` +adb forward tcp:1234 tcp:1234 +``` + +Finally, install lldb on your PC and connect to the debug server running on your Android device: + +``` +lldb-3.9 +(lldb) platform select remote-android + Platform: remote-android + Connected: no +(lldb) platform connect connect://localhost:1234 + Platform: remote-android + Triple: aarch64-*-linux-android +OS Version: 23.0.0 (3.10.84-perf-gf38969a) + Kernel: #1 SMP PREEMPT Fri Sep 16 11:29:29 2016 + Hostname: localhost + Connected: yes +WorkingDir: /data/local/tmp + +(lldb) target create coreclr/pal/tests/palsuite/file_io/CopyFileA/test4/paltest_copyfilea_test4 +(lldb) env LD_LIBRARY_PATH=/data/local/tmp/coreclr/lib +(lldb) run +``` diff --git a/cross/build-android-rootfs.sh b/cross/build-android-rootfs.sh new file mode 100755 index 0000000000..7627294a26 --- /dev/null +++ b/cross/build-android-rootfs.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash + +usage() +{ + echo "Creates a toolchain and sysroot used for cross-compiling for Android." + echo. + echo "Usage: $0 [BuildArch] [ApiLevel]" + echo. + echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." + echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" + echo. + echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" + echo "by setting the TOOLCHAIN_DIR environment variable" + echo. + echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-r13b directory. If you already have an NDK installation," + echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK." + exit 1 +} + +__ApiLevel=21 # The minimum platform for arm64 is API level 21 +__BuildArch=arm64 +__AndroidArch=aarch64 + +for i in "$@" + do + lowerI="$(echo $i | awk '{print tolower($0)}')" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm64) + __BuildArch=arm64 + __AndroidArch=aarch64 + ;; + *[0-9]) + __ApiLevel=$i + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + ;; + esac +done + +# Obtain the location of the bash script to figure out where the root of the repo is. +__CrossDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +__Android_Cross_Dir="$__CrossDir/android-rootfs" +__NDK_Dir="$__Android_Cross_Dir/android-ndk-r13b" +__libunwind_Dir="$__Android_Cross_Dir/libunwind" +__lldb_Dir="$__Android_Cross_Dir/lldb" +__ToolchainDir="$__Android_Cross_Dir/toolchain/$__BuildArch" + +if [[ -n "$TOOLCHAIN_DIR" ]]; then + __ToolchainDir=$TOOLCHAIN_DIR +fi + +if [[ -n "$NDK_DIR" ]]; then + __NDK_Dir=$NDK_DIR +fi + +echo "Target API level: $__ApiLevel" +echo "Target architecture: $__BuildArch" +echo "NDK location: $__NDK_Dir" +echo "Target Toolchain location: $__ToolchainDir" + +# Download the NDK if required +if [ ! -d $__NDK_Dir ]; then + echo Downloading the NDK into $__NDK_Dir + mkdir -p $__NDK_Dir + wget -nv -nc --show-progress https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip -O $__Android_Cross_Dir/android-ndk-r13b-linux-x86_64.zip + unzip -q $__Android_Cross_Dir/android-ndk-r13b-linux-x86_64.zip -d $__Android_Cross_Dir +fi + +if [ ! -d $__lldb_Dir ]; then + mkdir -p $__lldb_Dir + echo Downloading LLDB into $__lldb_Dir + wget -nv -nc --show-progress https://dl.google.com/android/repository/lldb-2.3.3614996-linux-x86_64.zip -O $__Android_Cross_Dir/lldb-2.3.3614996-linux-x86_64.zip + unzip -q $__Android_Cross_Dir/lldb-2.3.3614996-linux-x86_64.zip -d $__lldb_Dir +fi + +# Create the RootFS for both arm64 as well as aarch +rm -rf $__Android_Cross_Dir/toolchain + +echo Generating the $__BuildArch toolchain +$__NDK_Dir/build/tools/make_standalone_toolchain.py --arch $__BuildArch --api $__ApiLevel --install-dir $__ToolchainDir + +# Install the required packages into the toolchain +rm -rf $__Android_Cross_Dir/deb/ +rm -rf $__Android_Cross_Dir/tmp + +mkdir -p $__Android_Cross_Dir/deb/ +mkdir -p $__Android_Cross_Dir/tmp/$arch/ +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libicu_58.2_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libicu_58.2_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libicu-dev_58.2_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libicu-dev_58.2_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libuuid-dev_1.0.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libuuid-dev_1.0.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libuuid_1.0.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libuuid_1.0.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-glob-dev_0.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-glob-dev_0.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-glob_0.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-glob_0.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-support-dev_13.10_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-support-dev_13.10_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libandroid-support_13.10_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libandroid-support_13.10_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/liblzma-dev_5.2.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/liblzma-dev_5.2.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/liblzma_5.2.3_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/liblzma_5.2.3_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libcurl-dev_7.52.1_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libcurl-dev_7.52.1_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libcurl_7.52.1_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libcurl_7.52.1_$__AndroidArch.deb + +echo Unpacking Termux packages +dpkg -x $__Android_Cross_Dir/deb/libicu_58.2_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libicu-dev_58.2_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libuuid-dev_1.0.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libuuid_1.0.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-glob-dev_0.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-glob_0.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-support-dev_13.10_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libandroid-support_13.10_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/liblzma-dev_5.2.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/liblzma_5.2.3_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libcurl-dev_7.52.1_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libcurl_7.52.1_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ + +cp -R $__Android_Cross_Dir/tmp/$__AndroidArch/data/data/com.termux/files/usr/* $__ToolchainDir/sysroot/usr/ + +# Prepare libunwind +if [ ! -d $__libunwind_Dir ]; then + git clone https://android.googlesource.com/platform/external/libunwind/ $__libunwind_Dir +fi + +cd $__libunwind_Dir +git checkout android-6.0.0_r26 +git checkout -- . +git clean -xfd + +# libunwind is available on Android, but not included in the NDK. +echo Building libunwind +autoreconf --force -v --install 2> /dev/null +./configure CC=$__ToolchainDir/bin/$__AndroidArch-linux-android-clang --with-sysroot=$__ToolchainDir/sysroot --host=x86_64 --target=$__AndroidArch-eabi --disable-coredump --prefix=$__ToolchainDir/sysroot/usr 2> /dev/null +make > /dev/null +make install > /dev/null + +# This header file is missing +cp include/libunwind.h $__ToolchainDir/sysroot/usr/include/ + +echo Now run: +echo CONFIG_DIR=\`realpath cross/android/arm64\` ROOTFS_DIR=\`realpath $__ToolchainDir/sysroot\` ./build.sh cross arm64 skipgenerateversion skipmscorlib cmakeargs -DENABLE_LLDBPLUGIN=0 + |