diff --git a/Dockerfile b/Dockerfile index f0fb95f9a..0dc5a2e1f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,8 +30,3 @@ ENV PATH ${PATH}:/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/b RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none ENV PATH ${PATH}:/root/.cargo/bin - -ENV CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER ${ANDROID_SDK_ROOT}/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi16-clang -ENV CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER ${ANDROID_SDK_ROOT}/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang -ENV CARGO_TARGET_I686_LINUX_ANDROID_LINKER ${ANDROID_SDK_ROOT}/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang -ENV CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER ${ANDROID_SDK_ROOT}/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang diff --git a/README.md b/README.md index 0cfbb150f..b29886453 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ podman build . -t deltachat-android Then, run the image: ``` -podman run -it -v $(pwd):/home/app -w /home/app localhost/deltachat-android +podman run -it --name deltachat -v $(pwd):/home/app -w /home/app localhost/deltachat-android ``` Within the container, install toolchains and build the native library: @@ -58,9 +58,15 @@ If you don't want to use Docker or Podman, proceed to the next section. To setup build environment manually, you can read the `Dockerfile` and mimic what it does. -First, you need to setup Android SDK and Android NDK. Then, open -`ndk-make.sh` in an editor and follow the instructions to set up a rust -build environment. This is needed only once. +First, you need to setup Android SDK and Android NDK. Configure +`ANDROID_NDK_ROOT` environment variable to point to the Android NDK +installation directory. Currently ndk20b is the minimum required version. +Newer versions will likely work, however, are not tested and not used +in official releases, in general, changes on the ndk-version should be +done with care. + +Then, install Rust using [rustup](https://rustup.rs/). Install Rust +toolchains for cross-compilation by executing `scripts/install-toolchains.sh`. After that, call `./ndk-make.sh` in the root directory to build core-rust. Afterwards run the project in Android Studio. The project requires API 25. diff --git a/ndk-make-fast.sh b/ndk-make-fast.sh deleted file mode 100755 index e54b57d77..000000000 --- a/ndk-make-fast.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh - -# If you want to, you can run this script with instead of ndk-make.sh your architecture as an argument -# to speed up compilation by factor 4 (will not work on macOS and might not work for other reasons): -# -# ./ndk-make.sh arm64-v8a -# -# Possible values are armeabi-v7a, arm64-v8a, x86 and x86_64. -# You should be able to find out your architecture by running: -# -# adb shell uname -m -# -# or: -# -# adb shell cat /proc/cpuinfo -# -# The values in the following lines mean the same: -# -# armeabi-v7a, armv7 and arm -# arm64-v8a, aarch64 and arm64 -# x86 and i686 -# (there are no synonyms for x86_64) -# -# -# If you put this in your .bashrc, then you can directly build and deploy DeltaChat from the jni/deltachat-core-rust directory by typing nmake(): -# nmake() {sh -c 'cd ../..; ./ndk-make-fast.sh arm64-v8a && ./gradlew installFatDebug; notify-send "install finished" } - -set -e -echo "starting time: `date`" - -# Check if the argument is a correct architecture: -if test $1 && echo "armeabi-v7a arm64-v8a x86 x86_64" | grep -vwq $1; then - echo "Architecture '$1' not known, possible values are armeabi-v7a, arm64-v8a, x86 and x86_64." - exit -fi - -cd jni -rm -f armeabi-v7a/* -rm -f arm64-v8a/* -rm -f x86/* -rm -f x86_64/* -mkdir -p armeabi-v7a -mkdir -p arm64-v8a -mkdir -p x86 -mkdir -p x86_64 - -cd deltachat-core-rust - -# fix build on MacOS Catalina -unset CPATH - -if test -z $1 || test $1 = armeabi-v7a; then - echo "-- cross compiling to armv7-linux-androideabi (arm) --" - export CFLAGS=-D__ANDROID_API__=16 - TARGET_CC=armv7a-linux-androideabi16-clang \ - cargo +`cat rust-toolchain` build --target armv7-linux-androideabi -p deltachat_ffi - cp target/armv7-linux-androideabi/debug/libdeltachat.a ../armeabi-v7a -fi - -if test -z $1 || test $1 = arm64-v8a; then - echo "-- cross compiling to aarch64-linux-android (arm64) --" - export CFLAGS=-D__ANDROID_API__=21 - TARGET_CC=aarch64-linux-android21-clang \ - cargo +`cat rust-toolchain` build --target aarch64-linux-android -p deltachat_ffi - cp target/aarch64-linux-android/debug/libdeltachat.a ../arm64-v8a -fi - -if test -z $1 || test $1 = x86; then - echo "-- cross compiling to i686-linux-android (x86) --" - export CFLAGS=-D__ANDROID_API__=16 - TARGET_CC=i686-linux-android16-clang \ - cargo +`cat rust-toolchain` build --target i686-linux-android -p deltachat_ffi - cp target/i686-linux-android/debug/libdeltachat.a ../x86 -fi - -if test -z $1 || test $1 = x86_64; then - echo "-- cross compiling to x86_64-linux-android (x86_64) --" - export CFLAGS=-D__ANDROID_API__=21 - TARGET_CC=x86_64-linux-android21-clang \ - cargo +`cat rust-toolchain` build --target x86_64-linux-android -p deltachat_ffi - cp target/x86_64-linux-android/debug/libdeltachat.a ../x86_64 -fi - -echo -- ndk-build -- - -cd .. -# Set the right arch in Application.mk: -oldDotMk="$(cat Application.mk)" - -if test $1; then - sed -i "s/APP_ABI.*/APP_ABI := $1/g" Application.mk -else - # We are compiling for all architectures: - sed -i "s/APP_ABI.*/APP_ABI := armeabi-v7a arm64-v8a x86 x86_64/g" Application.mk -fi - -cd .. -ndk-build - -cd jni -# Restore old Application.mk: -echo "$oldDotMk" > Application.mk - -echo "ending time: `date`" diff --git a/ndk-make.sh b/ndk-make.sh index 481b7a4ce..6522f80eb 100755 --- a/ndk-make.sh +++ b/ndk-make.sh @@ -1,60 +1,61 @@ #!/bin/sh + +# If you want to speed up compilation, you can run this script with your +# architecture as an argument: +# +# ./ndk-make.sh arm64-v8a +# +# Possible values are armeabi-v7a, arm64-v8a, x86 and x86_64. +# You should be able to find out your architecture by running: +# +# adb shell uname -m +# +# or: +# +# adb shell cat /proc/cpuinfo +# +# The values in the following lines mean the same: +# +# armeabi-v7a, armv7 and arm +# arm64-v8a, aarch64 and arm64 +# x86 and i686 +# (there are no synonyms for x86_64) +# +# +# If you put this in your .bashrc, then you can directly build and +# deploy DeltaChat from the jni/deltachat-core-rust directory by +# typing `nmake`: +# +# nmake() {(cd ../..; ./ndk-make.sh arm64-v8a && ./gradlew installFatDebug; notify-send "install finished")} + set -e echo "starting time: `date`" -cd jni/deltachat-core-rust +: "${ANDROID_NDK_ROOT:=$ANDROID_NDK_HOME}" +: "${ANDROID_NDK_ROOT:=$ANDROID_NDK}" +if test ! -z "$ANDROID_NDK_ROOT"; then + echo Setting CARGO_TARGET environment variables. -# to setup the toolchains (from https://medium.com/visly/rust-on-android-19f34a2fb43 ) -# run `scripts/install-toolchains.sh`. -# -# Currently ndk20b is minimum required version -# (newer versions will likely work, however, are not tested and not used in offial releases, -# in general, changes on the ndk-version should be done with care) -# -# after that, add PATH_TO_NDK/toolchains/llvm/prebuilt/HOST/bin to your $PATH -# and add the correct clang-linkers to `~/.cargo/config`: -# ``` -# [target.armv7-linux-androideabi] -# linker = "PATH_TO_NDK/toolchains/llvm/prebuilt/HOST/bin/armv7a-linux-androideabi16-clang" -# [target.aarch64-linux-android] -# linker = "PATH_TO_NDK/toolchains/llvm/prebuilt/HOST/bin/aarch64-linux-android21-clang" -# [target.i686-linux-android] -# linker = "PATH_TO_NDK/toolchains/llvm/prebuilt/HOST/bin/i686-linux-android16-clang" -# [target.x86_64-linux-android] -# linker = "PATH_TO_NDK/toolchains/llvm/prebuilt/HOST/bin/x86_64-linux-android21-clang" -# ``` -# then, the following should work: -# (If you want to speed up compilation, have look at the comment in ndk-make-fast.sh.) + if test -z "$NDK_HOST_TAG"; then + KERNEL="$(uname -s | tr '[:upper:]' '[:lower:]')" + ARCH="$(uname -m)" + NDK_HOST_TAG="$KERNEL-$ARCH" + fi -# fix build on MacOS Catalina -unset CPATH + TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$NDK_HOST_TAG" + export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="$TOOLCHAIN/bin/armv7a-linux-androideabi16-clang" + export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/aarch64-linux-android21-clang" + export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/i686-linux-android16-clang" + export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="$TOOLCHAIN/bin/x86_64-linux-android21-clang" +fi -echo "-- cross compiling to armv7-linux-androideabi (arm) --" -export CFLAGS=-D__ANDROID_API__=16 -RUSTFLAGS="-C lto=on -C embed-bitcode=yes" \ -TARGET_CC=armv7a-linux-androideabi16-clang \ -cargo +`cat rust-toolchain` build --release --target armv7-linux-androideabi -p deltachat_ffi +# Check if the argument is a correct architecture: +if test $1 && echo "armeabi-v7a arm64-v8a x86 x86_64" | grep -vwq $1; then + echo "Architecture '$1' not known, possible values are armeabi-v7a, arm64-v8a, x86 and x86_64." + exit +fi -echo "-- cross compiling to aarch64-linux-android (arm64) --" -export CFLAGS=-D__ANDROID_API__=21 -RUSTFLAGS="-C lto=on -C embed-bitcode=yes" \ -TARGET_CC=aarch64-linux-android21-clang \ -cargo +`cat rust-toolchain` build --release --target aarch64-linux-android -p deltachat_ffi - -echo "-- cross compiling to i686-linux-android (x86) --" -export CFLAGS=-D__ANDROID_API__=16 -RUSTFLAGS="-C lto=on -C embed-bitcode=yes" \ -TARGET_CC=i686-linux-android16-clang \ -cargo +`cat rust-toolchain` build --release --target i686-linux-android -p deltachat_ffi - -echo "-- cross compiling to x86_64-linux-android (x86_64) --" -export CFLAGS=-D__ANDROID_API__=21 -RUSTFLAGS="-C lto=on -C embed-bitcode=yes" \ -TARGET_CC=x86_64-linux-android21-clang \ -cargo +`cat rust-toolchain` build --release --target x86_64-linux-android -p deltachat_ffi - -echo -- copy generated .a files -- -cd .. +cd jni rm -f armeabi-v7a/* rm -f arm64-v8a/* rm -f x86/* @@ -63,12 +64,80 @@ mkdir -p armeabi-v7a mkdir -p arm64-v8a mkdir -p x86 mkdir -p x86_64 -cp deltachat-core-rust/target/armv7-linux-androideabi/release/libdeltachat.a armeabi-v7a -cp deltachat-core-rust/target/aarch64-linux-android/release/libdeltachat.a arm64-v8a -cp deltachat-core-rust/target/i686-linux-android/release/libdeltachat.a x86 -cp deltachat-core-rust/target/x86_64-linux-android/release/libdeltachat.a x86_64 + +cd deltachat-core-rust + +# fix build on MacOS Catalina +unset CPATH + +if test -z $1; then + echo Full build + + export RUSTFLAGS="-C lto=on -C embed-bitcode=yes" + RELEASE="release" + RELEASEFLAG="--release" +else + echo Fast, partial, slow debug build. DO NOT UPLOAD THE APK ANYWHERE. + + RELEASE="debug" + RELEASEFLAG= +fi + +if test -z $1 || test $1 = armeabi-v7a; then + echo "-- cross compiling to armv7-linux-androideabi (arm) --" + export CFLAGS=-D__ANDROID_API__=16 + TARGET_CC=armv7a-linux-androideabi16-clang \ + cargo +`cat rust-toolchain` build $RELEASEFLAG --target armv7-linux-androideabi -p deltachat_ffi + cp target/armv7-linux-androideabi/$RELEASE/libdeltachat.a ../armeabi-v7a +fi + +if test -z $1 || test $1 = arm64-v8a; then + echo "-- cross compiling to aarch64-linux-android (arm64) --" + export CFLAGS=-D__ANDROID_API__=21 + TARGET_CC=aarch64-linux-android21-clang \ + cargo +`cat rust-toolchain` build $RELEASEFLAG --target aarch64-linux-android -p deltachat_ffi + cp target/aarch64-linux-android/$RELEASE/libdeltachat.a ../arm64-v8a +fi + +if test -z $1 || test $1 = x86; then + echo "-- cross compiling to i686-linux-android (x86) --" + export CFLAGS=-D__ANDROID_API__=16 + TARGET_CC=i686-linux-android16-clang \ + cargo +`cat rust-toolchain` build $RELEASEFLAG --target i686-linux-android -p deltachat_ffi + cp target/i686-linux-android/$RELEASE/libdeltachat.a ../x86 +fi + +if test -z $1 || test $1 = x86_64; then + echo "-- cross compiling to x86_64-linux-android (x86_64) --" + export CFLAGS=-D__ANDROID_API__=21 + TARGET_CC=x86_64-linux-android21-clang \ + cargo +`cat rust-toolchain` build $RELEASEFLAG --target x86_64-linux-android -p deltachat_ffi + cp target/x86_64-linux-android/$RELEASE/libdeltachat.a ../x86_64 +fi echo -- ndk-build -- + +cd .. +# Set the right arch in Application.mk: +oldDotMk="$(cat Application.mk)" + +if test $1; then + # Using temporary file because `sed -i` is not portable + TMP=$(mktemp) + sed "s/APP_ABI.*/APP_ABI := $1/g" Application.mk >"$TMP" + mv "$TMP" Application.mk +else + # We are compiling for all architectures: + TMP=$(mktemp) + sed "s/APP_ABI.*/APP_ABI := armeabi-v7a arm64-v8a x86 x86_64/g" Application.mk >"$TMP" + mv "$TMP" Application.mk +fi + cd .. ndk-build + +cd jni +# Restore old Application.mk: +echo "$oldDotMk" > Application.mk + echo "ending time: `date`"