diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-07-18 14:46:17 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-07-18 14:46:17 -0300 |
| commit | 227fc1d94d84ec3665965f5e94abcae1537f7462 (patch) | |
| tree | 16b938a024f1aba6523baa1dd8df2088c32205f0 | |
| parent | eab8d714e048bd93b34c768044e2b7282151d703 (diff) | |
| parent | d1632fd044054542cbb4b65928f9a14f3a51dcd2 (diff) | |
| download | mullvadvpn-227fc1d94d84ec3665965f5e94abcae1537f7462.tar.xz mullvadvpn-227fc1d94d84ec3665965f5e94abcae1537f7462.zip | |
Merge branch 'multiple-android-architectures'
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | README.md | 70 | ||||
| -rw-r--r-- | android/build.gradle | 44 | ||||
| -rw-r--r-- | android/proguard-rules.pro | 4 | ||||
| -rwxr-xr-x | build-apk.sh | 76 |
5 files changed, 163 insertions, 33 deletions
diff --git a/.gitignore b/.gitignore index f96460a318..85e2308d15 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,7 @@ /dist-assets/openvpn /dist-assets/openvpn.exe /windows/**/bin/ +/android/keystore.properties +/android/local.properties **/.vs/ *.bak @@ -96,12 +96,30 @@ unzip android-ndk-r20-linux-x86_64.zip --platform=android-21 \ --arch=arm64 \ --install-dir=$PWD/toolchains/android21-aarch64 +./android-ndk-r20/build/tools/make-standalone-toolchain.sh \ + --platform=android-21 \ + --arch=arm \ + --install-dir=$PWD/toolchains/android21-armv7 +./android-ndk-r20/build/tools/make-standalone-toolchain.sh \ + --platform=android-21 \ + --arch=x86_64 \ + --install-dir=$PWD/toolchains/android21-x86_64 +./android-ndk-r20/build/tools/make-standalone-toolchain.sh \ + --platform=android-21 \ + --arch=x86 \ + --install-dir=$PWD/toolchains/android21-i686 ``` Set up the required environment variables: ``` export AR_aarch64_linux_android="$PWD/toolchains/android21-aarch64/bin/aarch64-linux-android-ar" +export AR_armv7_linux_androideabi="$PWD/toolchains/android21-armv7/bin/arm-linux-androideabi-ar" +export AR_x86_64_linux_android="$PWD/toolchains/android21-x86_64/bin/x86_64-linux-android-ar" +export AR_i686_linux_android="$PWD/toolchains/android21-i686/bin/i686-linux-android-ar" export CC_aarch64_linux_android="$PWD/toolchains/android21-aarch64/bin/aarch64-linux-android21-clang" +export CC_armv7_linux_androideabi="$PWD/toolchains/android21-armv7/bin/armv7a-linux-androideabi21-clang" +export CC_x86_64_linux_android="$PWD/toolchains/android21-x86_64/bin/x86_64-linux-android21-clang" +export CC_i686_linux_android="$PWD/toolchains/android21-i686/bin/i686-linux-android21-clang" export ANDROID_HOME="$PWD" ``` @@ -111,7 +129,7 @@ These steps has to be done **after** you have installed Rust in the section belo ##### Install the Rust Android target ```bash -rustup target add aarch64-linux-android +rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android ``` ##### Set up cargo to use the correct linker and archiver @@ -123,7 +141,40 @@ Add to `~/.cargo/config`: ``` [target.aarch64-linux-android] ar = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar" -linker = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang" +linker = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang" + +[target.armv7-linux-androideabi] +ar = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar" +linker = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang" + +[target.x86_64-linux-android] +ar = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android-ar" +linker = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang" + +[target.i686-linux-android] +ar = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android-ar" +linker = "/opt/android/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang" +``` + +#### Signing the release APK + +In order to build release APKs, they need to be signed. First, a signing key must be generated and +stored in a keystore file. In the example below, the keystore file will be +`/home/user/app-keys.jks` and will contain a key called `release`. + +``` +keytool -genkey -v -keystore /home/user/app-keys.jks -alias release -keyalg RSA -keysize 4096 -validity 10000 +``` + +Fill in the requested information to generate the key and the keystore file. Suppose the file was +protected by a password `keystore-password` and the key with a password `key-password`. This +information should then be added to the `android/keystore.properties` file: + +``` +keyAlias = release +keyPassword = key-password +storeFile = /home/user/app-keys.jks +storePassword = keystore-password ``` ### All platforms @@ -250,22 +301,17 @@ to do that before starting the GUI. ## Building the Android app -Build the Rust daemon with: -```bash -. env.sh "aarch64-linux-android" -cargo build --target aarch64-linux-android --release -``` - -Packaging the APK: +Running the `build-apk.sh` script will build the necessary Rust daemon for all supported ABIs and +build the final APK. You may pass a `--dev-build` to build the Rust daemon and the UI in debug mode +and sign the APK with automatically generated debug keys. ```bash -cd android/ -./gradlew assembleRelease +./build-apk.sh ``` If the above fails with an error related to compression, try allowing more memory to the JVM: ```bash echo "org.gradle.jvmargs=-Xmx4608M" >> ~/.gradle/gradle.properties -./gradlew --stop +./android/gradlew --stop ``` diff --git a/android/build.gradle b/android/build.gradle index e6b15979fb..4ee2ce7bd3 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,6 +8,13 @@ def repoRootPath = projectDir.absoluteFile.parentFile.absolutePath def extraAssetsDirectory = "$project.buildDir/extraAssets" def extraJniDirectory = "$project.buildDir/extraJni" +def keystorePropertiesFile = file('keystore.properties') +def keystoreProperties = new Properties() + +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + android { compileSdkVersion 28 buildToolsVersion '28.0.3' @@ -20,10 +27,22 @@ android { versionName "2019.1" } - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + if (keystorePropertiesFile.exists()) { + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + signingConfig signingConfigs.release + } } } @@ -43,11 +62,6 @@ android { variant.mergeAssetsProvider.configure { dependsOn copyApiRootCertificate } - - variant.ndkCompileProvider.configure { - dependsOn copyMullvadJni - dependsOn copyWireguardGo - } } } @@ -95,18 +109,6 @@ task format(type: FormatTask, group: 'formatting') { lint.dependsOn lintKotlin -task copyMullvadJni(type: Copy) { - from "$repoRootPath/target/aarch64-linux-android/debug" - include 'libmullvad_jni.so' - into "$extraJniDirectory/arm64-v8a" -} - -task copyWireguardGo(type: Copy) { - from "$repoRootPath/dist-assets/binaries/aarch64-linux-android" - include 'libwg.so' - into "$extraJniDirectory/arm64-v8a" -} - task copyApiRootCertificate(type: Copy) { from "$repoRootPath/dist-assets" include "api_root_ca.pem" diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro index f6a2ef15e0..a50d295303 100644 --- a/android/proguard-rules.pro +++ b/android/proguard-rules.pro @@ -1 +1,5 @@ -dontwarn org.joda.convert.** + +-keep class net.mullvad.mullvadvpn.model.** { *; } +-keep class net.mullvad.mullvadvpn.MullvadDaemon { *; } +-keep class net.mullvad.mullvadvpn.MullvadVpnService { *; } diff --git a/build-apk.sh b/build-apk.sh new file mode 100755 index 0000000000..e69c57c563 --- /dev/null +++ b/build-apk.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +set -e + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd "$SCRIPT_DIR" + +PRODUCT_VERSION="$(node -p "require('$SCRIPT_DIR/gui/package.json').version" | sed -Ee 's/\.0//g')" + +if [[ "${1:-""}" == "--dev-build" ]]; then + BUILD_TYPE="debug" + GRADLE_TASK="assembleDebug" + APK_SUFFIX="-debug" + CARGO_FLAGS="" +else + BUILD_TYPE="release" + GRADLE_TASK="assembleRelease" + APK_SUFFIX="" + CARGO_FLAGS="--release" + + if [ ! -f "$SCRIPT_DIR/android/keystore.properties" ]; then + echo "ERROR: No keystore.properties file found" >&2 + echo " Please configure the signing keys as described in the README" >&2 + exit 1 + fi +fi + +if [[ "$BUILD_TYPE" == "debug" || "$(git describe)" != "$PRODUCT_VERSION" ]]; then + GIT_COMMIT="$(git rev-parse --short HEAD)" + APK_VERSION="${PRODUCT_VERSION}-dev-${GIT_COMMIT}" +else + APK_VERSION="$PRODUCT_VERSION" +fi + +ARCHITECTURES="aarch64 armv7 x86_64 i686" + +cd "$SCRIPT_DIR/android" +./gradlew --console plain clean +mkdir -p "${SCRIPT_DIR}/android/build/extraJni" + +cd "$SCRIPT_DIR" + +for ARCHITECTURE in $ARCHITECTURES; do + case "$ARCHITECTURE" in + "x86_64") + TARGET="x86_64-linux-android" + ABI="x86_64" + ;; + "i686") + TARGET="i686-linux-android" + ABI="x86" + ;; + "aarch64") + TARGET="aarch64-linux-android" + ABI="arm64-v8a" + ;; + "armv7") + TARGET="armv7-linux-androideabi" + ABI="armeabi-v7a" + ;; + esac + + . env.sh "$TARGET" + cargo build $CARGO_FLAGS --target "$TARGET" --package mullvad-jni + + cp -a "$SCRIPT_DIR/dist-assets/binaries/$TARGET" "$SCRIPT_DIR/android/build/extraJni/$ABI" + cp "$SCRIPT_DIR/target/$TARGET/$BUILD_TYPE/libmullvad_jni.so" "$SCRIPT_DIR/android/build/extraJni/$ABI/" +done + +cd "$SCRIPT_DIR/android" +./gradlew --console plain "$GRADLE_TASK" + +GENERATED_APK="$SCRIPT_DIR/android/build/outputs/apk/$BUILD_TYPE/android-$BUILD_TYPE.apk" + +mkdir -p ../dist +cp "$GENERATED_APK" "$SCRIPT_DIR/dist/MullvadVPN-${APK_VERSION}${APK_SUFFIX}.apk" |
