summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2025-07-17 10:43:54 +0200
committerAlbin <albin@mullvad.net>2025-07-17 10:43:54 +0200
commita7e5d9ff3f840acfd78dee23924c174de741227b (patch)
treed76e97352db94ebe5496beb97724ab07f9046421
parentc9cf9cb22d112efece39cc4e06c1f068600315a3 (diff)
parent4d7a8a72a32b78027ae6a5f6d963d75b79d81850 (diff)
downloadmullvadvpn-a7e5d9ff3f840acfd78dee23924c174de741227b.tar.xz
mullvadvpn-a7e5d9ff3f840acfd78dee23924c174de741227b.zip
Merge branch 'add-macos-devshell-support'
-rw-r--r--.github/workflows/android-reproducible-builds.yml10
-rw-r--r--android/BuildInstructions.md2
-rw-r--r--android/docs/BuildInstructions.macos.md2
-rw-r--r--android/flake.nix34
-rw-r--r--android/nix/env-vars.nix180
5 files changed, 137 insertions, 91 deletions
diff --git a/.github/workflows/android-reproducible-builds.yml b/.github/workflows/android-reproducible-builds.yml
index 9b9eb9504c..db468fdec5 100644
--- a/.github/workflows/android-reproducible-builds.yml
+++ b/.github/workflows/android-reproducible-builds.yml
@@ -138,8 +138,14 @@ jobs:
build-using-nix:
name: Build fdroid variant using nix
- runs-on: ubuntu-24.04
+ runs-on: ${{ matrix.runs-on }}
needs: set-up-env
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - runs-on: ubuntu-latest
+ - runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -162,7 +168,7 @@ jobs:
- name: Upload apks
uses: actions/upload-artifact@v4
with:
- name: apk-nix
+ name: apk-nix-${{ matrix.runs-on }}
path: android/app/build/outputs/apk/ossProd/fdroid/app-oss-prod-fdroid-unsigned.apk
if-no-files-found: error
retention-days: 7
diff --git a/android/BuildInstructions.md b/android/BuildInstructions.md
index a58a993b49..c1051c8521 100644
--- a/android/BuildInstructions.md
+++ b/android/BuildInstructions.md
@@ -178,6 +178,8 @@ Run the following command to build a debug build:
```
## Build using nix devshell
+This is supported on Linux (x86_64) as well as macOS (x86_64 and aarch64).
+
1. Install the nix package manager by following the [official instructions](https://nixos.org/download/).
2. Enable the experimental `nix-command` and `flake` features by following [these instructions](https://nixos.wiki/wiki/flakes).
3. Launch a devshell (in `<repository>/android`) by running:
diff --git a/android/docs/BuildInstructions.macos.md b/android/docs/BuildInstructions.macos.md
index 4ef004d595..0538a2daaf 100644
--- a/android/docs/BuildInstructions.macos.md
+++ b/android/docs/BuildInstructions.macos.md
@@ -3,6 +3,8 @@
This document will guide you to setup your development environment on macOS. It has been
tested on a clean install of macOS Ventura 13.5.1 on a M2 MacBook.
+As an alternative to this guide you can also follow [these nix devshell instructions](../BuildInstructions.md#build-using-nix-devshell).
+
> __*WARNING:*__ This guide will not apply the [wireguard-go patch](https://git.zx2c4.com/wireguard-android/tree/tunnel/tools/libwg-go/goruntime-boottime-over-monotonic.diff)
> as done in Linux build instructions which may affect app performance.
diff --git a/android/flake.nix b/android/flake.nix
index 0d75da2038..8cf0d4a26a 100644
--- a/android/flake.nix
+++ b/android/flake.nix
@@ -31,6 +31,15 @@
overlays = [
(import rust-overlay)
devshell.overlays.default
+ # Fix that disables autoPatchelfHook on macOS.
+ # Should be addressed upstream in nixpkgs.
+ (final: prev: {
+ protoc-gen-grpc-java = prev.protoc-gen-grpc-java.overrideAttrs (old: {
+ nativeBuildInputs =
+ pkgs.lib.remove prev.autoPatchelfHook (old.nativeBuildInputs or [])
+ ++ pkgs.lib.optionals prev.stdenv.isLinux [prev.autoPatchelfHook];
+ });
+ })
];
};
@@ -85,17 +94,20 @@
devShells.default = pkgs.devshell.mkShell {
name = "mullvad-android-devshell";
- packages = [
- android-sdk
- rust-toolchain
- patchedGo_1_21_3
- pkgs.protoc-gen-grpc-java
- pkgs.gcc
- pkgs.gnumake
- pkgs.protobuf
- pkgs.jdk17
- pkgs.python3Full
- ];
+ packages =
+ [
+ android-sdk
+ rust-toolchain
+ patchedGo_1_21_3
+ pkgs.protoc-gen-grpc-java
+ pkgs.gcc
+ pkgs.gnumake
+ pkgs.protobuf
+ pkgs.jdk17
+ pkgs.python3Full
+ ]
+ ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [pkgs.libiconv];
+
env = import ./nix/env-vars.nix {
inherit pkgs android-sdk buildToolsVersion ndkVersion minSdkVersion;
};
diff --git a/android/nix/env-vars.nix b/android/nix/env-vars.nix
index e9f5d6aa62..173db93af3 100644
--- a/android/nix/env-vars.nix
+++ b/android/nix/env-vars.nix
@@ -4,81 +4,105 @@
buildToolsVersion,
ndkVersion,
minSdkVersion,
-}: [
- {
- name = "JAVA_HOME";
- value = "${pkgs.jdk17}";
- }
- {
- name = "PROTOC_GEN_GRPC_JAVA_PLUGIN";
- prefix = "${pkgs.protoc-gen-grpc-java}/bin/protoc-gen-grpc-java";
- }
- {
- name = "GRADLE_OPTS";
- value = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${android-sdk}/share/android-sdk/build-tools/${buildToolsVersion}/aapt2";
- }
- {
- name = "ANDROID_HOME";
- value = "${android-sdk}/share/android-sdk";
- }
- {
- name = "ANDROID_SDK_ROOT";
- value = "${android-sdk}/share/android-sdk";
- }
- {
- name = "ANDROID_NDK_ROOT";
- value = "${android-sdk}/share/android-sdk/ndk/${ndkVersion}";
- }
- {
- name = "NDK_TOOLCHAIN_DIR";
- value = "${android-sdk}/share/android-sdk/ndk/${ndkVersion}/toolchains/llvm/prebuilt/linux-x86_64/bin";
- }
- {
- name = "AR_aarch64_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
- }
- {
- name = "CC_aarch64_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/aarch64-linux-android${minSdkVersion}-clang";
- }
- {
- name = "CARGO_TARGET_aarch64_LINUX_ANDROID_LINKER";
- value = "$NDK_TOOLCHAIN_DIR/aarch64-linux-android${minSdkVersion}-clang";
- }
- {
- name = "AR_armv7_linux_androideabi";
- value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
- }
- {
- name = "CC_armv7_linux_androideabi";
- value = "$NDK_TOOLCHAIN_DIR/armv7-linux-androideabi${minSdkVersion}-clang";
- }
- {
- name = "CARGO_TARGET_armv7_LINUX_ANDROID_LINKER";
- value = "$NDK_TOOLCHAIN_DIR/armv7-linux-androideabi${minSdkVersion}-clang";
- }
- {
- name = "AR_x86_64_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
- }
- {
- name = "CC_x86_64_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/x86_64-linux-android${minSdkVersion}-clang";
- }
- {
- name = "CARGO_TARGET_x86_64_LINUX_ANDROID_LINKER";
- value = "$NDK_TOOLCHAIN_DIR/x86_64-linux-android${minSdkVersion}-clang";
- }
- {
- name = "AR_i686_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
- }
- {
- name = "CC_i686_linux_android";
- value = "$NDK_TOOLCHAIN_DIR/i686-linux-android${minSdkVersion}-clang";
- }
- {
- name = "CARGO_TARGET_i686_LINUX_ANDROID_LINKER";
- value = "$NDK_TOOLCHAIN_DIR/i686-linux-android${minSdkVersion}-clang";
- }
-]
+}: let
+ hostPlatform =
+ # For linux the NDK support is limited to x86_64.
+ if pkgs.stdenv.isLinux && pkgs.stdenv.isx86_64
+ then "linux-x86_64"
+ # For macOS the x86_64 NDK is used for both intel and arm (via rosetta).
+ else if pkgs.stdenv.isDarwin
+ then "darwin-x86_64"
+ else throw "Unsupported OS/architecture combination: ${pkgs.stdenv.hostPlatform.system}";
+in
+ [
+ {
+ name = "JAVA_HOME";
+ value = "${pkgs.jdk17}";
+ }
+ {
+ name = "PROTOC_GEN_GRPC_JAVA_PLUGIN";
+ prefix = "${pkgs.protoc-gen-grpc-java}/bin/protoc-gen-grpc-java";
+ }
+ {
+ name = "GRADLE_OPTS";
+ value = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${android-sdk}/share/android-sdk/build-tools/${buildToolsVersion}/aapt2";
+ }
+ {
+ name = "ANDROID_HOME";
+ value = "${android-sdk}/share/android-sdk";
+ }
+ {
+ name = "ANDROID_SDK_ROOT";
+ value = "${android-sdk}/share/android-sdk";
+ }
+ {
+ name = "ANDROID_NDK_ROOT";
+ value = "${android-sdk}/share/android-sdk/ndk/${ndkVersion}";
+ }
+ {
+ name = "NDK_TOOLCHAIN_DIR";
+ value = "${android-sdk}/share/android-sdk/ndk/${ndkVersion}/toolchains/llvm/prebuilt/${hostPlatform}/bin";
+ }
+ {
+ name = "AR_aarch64_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
+ }
+ {
+ name = "CC_aarch64_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/aarch64-linux-android${minSdkVersion}-clang";
+ }
+ {
+ name = "CARGO_TARGET_aarch64_LINUX_ANDROID_LINKER";
+ value = "$NDK_TOOLCHAIN_DIR/aarch64-linux-android${minSdkVersion}-clang";
+ }
+ {
+ name = "AR_armv7_linux_androideabi";
+ value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
+ }
+ {
+ name = "CC_armv7_linux_androideabi";
+ value = "$NDK_TOOLCHAIN_DIR/armv7-linux-androideabi${minSdkVersion}-clang";
+ }
+ {
+ name = "CARGO_TARGET_armv7_LINUX_ANDROID_LINKER";
+ value = "$NDK_TOOLCHAIN_DIR/armv7-linux-androideabi${minSdkVersion}-clang";
+ }
+ {
+ name = "AR_x86_64_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
+ }
+ {
+ name = "CC_x86_64_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/x86_64-linux-android${minSdkVersion}-clang";
+ }
+ {
+ name = "CARGO_TARGET_x86_64_LINUX_ANDROID_LINKER";
+ value = "$NDK_TOOLCHAIN_DIR/x86_64-linux-android${minSdkVersion}-clang";
+ }
+ {
+ name = "AR_i686_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/llvm-ar";
+ }
+ {
+ name = "CC_i686_linux_android";
+ value = "$NDK_TOOLCHAIN_DIR/i686-linux-android${minSdkVersion}-clang";
+ }
+ {
+ name = "CARGO_TARGET_i686_LINUX_ANDROID_LINKER";
+ value = "$NDK_TOOLCHAIN_DIR/i686-linux-android${minSdkVersion}-clang";
+ }
+ ]
+ ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
+ {
+ name = "LIBRARY_PATH";
+ value = "${pkgs.libiconv}/lib";
+ }
+ {
+ name = "CPATH";
+ value = "${pkgs.libiconv}/include";
+ }
+ {
+ name = "RUSTFLAGS";
+ value = "-L${pkgs.libiconv}/lib";
+ }
+ ]