{ # UsageNote: to run the emulator # nix -L run .#emulate-android-x86_64 # # UsageNote: to run load gradle into $PATH # nix -L develop description = "Nix flake to develop for Android"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; inputs.flake-utils.url = "github:numtide/flake-utils"; # ExplanationNote: an alternative way to install Android tools, # not sure if it's better than nixpkgs' machinery at anything. # Just here for reference. inputs.android-nixpkgs = { url = "github:tadfisher/android-nixpkgs"; # ExplanationNote: # The main branch follows the "canary" channel of the Android SDK # repository. Use another android-nixpkgs branch to explicitly # track an SDK release channel. # # url = "github:tadfisher/android-nixpkgs/stable"; # url = "github:tadfisher/android-nixpkgs/beta"; # url = "github:tadfisher/android-nixpkgs/preview"; # url = "github:tadfisher/android-nixpkgs/canary"; # ExplanationNote: replace the "nixpkgs" input for the "android-nixpkgs" flake. inputs.nixpkgs.follows = "nixpkgs"; }; outputs = inputs: let systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; in inputs.flake-utils.lib.eachSystem systems ( system: let pkgs = import inputs.nixpkgs { inherit system; config = { android_sdk.accept_license = true; allowUnfreePredicate = pkg: builtins.elem (pkgs.lib.getName pkg) [ # ExplanationNote: android-emulate-app (see below) is unfree by transitivity "android-emulate-app" "android-sdk-build-tools" "android-sdk-cmdline-tools" "android-sdk-emulator" "android-sdk-ndk" "android-sdk-platform-tools" "android-sdk-platforms" "android-sdk-tools" "android-studio-stable" "android-sdk-system-image-${androidPlatformVersion}-google_apis-x86_64" "android-sdk-system-image-${androidPlatformVersion}-google_apis-arm64-v8a" "android-sdk-system-image-${androidPlatformVersion}-google_apis-armeabi-v7a" ]; }; }; androidPlatformVersion = "34"; androidBuildToolsVersion = "34.0.0"; androidCmakeVersion = "3.22.1"; androidSdkArgs = { cmakeVersions = [ androidCmakeVersion ]; platformVersions = [ androidPlatformVersion ]; abiVersions = [ "arm64-v8a" "armeabi-v7a" "x86_64" ]; systemImageTypes = [ "google_apis" #"google_apis_playstore" ]; platformToolsVersion = "34.0.1"; ndkVersions = [ "23.1.7779620" ]; buildToolsVersions = [ androidBuildToolsVersion ]; includeNDK = true; #includeEmulator = true; #includeSystemImages = true; extraLicenses = [ "android-sdk-license" #"android-sdk-preview-license" #"android-googletv-license" #"android-sdk-arm-dbt-license" #"google-gdk-license" #"intel-android-extra-license" #"intel-android-sysimage-license" #"mips-android-sysimage-license" ]; }; androidComposition = pkgs.androidenv.composeAndroidPackages androidSdkArgs; androidEmulateApp = args: pkgs.androidenv.emulateApp ( { name = "android-emulate-app"; app = null; deviceName = "device"; package = ""; # ToDo: set this when the emulator will be working # for emulate-android-armeabi-v7a # or emulate-android-arm64-v8a #app = "."; #package = "chat.simplex.app"; #activity = "chat.simplex.app.MainActivity"; sdkExtraArgs = androidSdkArgs // { emulatorVersion = "35.6.2"; }; platformVersion = androidPlatformVersion; systemImageType = "google_apis"; # ExplanationNote: workaround `-gpu host` not working # on my Vulkan system. androidEmulatorFlags = "-gpu guest"; configOptions = { "hw.keyboard" = "yes"; # FixMe: Not working for me: # WARNING | emuglConfig_get_vulkan_hardware_gpu: Failed to create vulkan instance error code: -9 # See https://issuetracker.google.com/issues/356896486 #"hw.gpu.enabled" = "yes"; }; } // args ); in { packages = rec { default = emulate-android-x86_64; emulate-android-x86_64 = androidEmulateApp { abiVersion = "x86_64"; }; # FailureNote: PANIC: Avd's CPU Architecture 'arm64' is not supported by the QEMU2 emulator on x86_64 host. # ExplanationNote: https://developer.android.com/studio/releases/emulator#support_for_arm_binaries_on_android_9_and_11_system_images # If you were previously unable to use the Android Emulator because # your app depended on ARM binaries, you can now use the Android 9 # x86 system image or any Android 11 system image to run your app – # it is no longer necessary to download a specific system image to # run ARM binaries. These Android 9 and Android 11 system images # support ARM by default and provide dramatically improved # performance when compared to those with full ARM emulation. emulate-android-arm64-v8a = androidEmulateApp { abiVersion = "arm64-v8a"; }; # FailureNote: PANIC: CPU Architecture 'arm' is not supported by the QEMU2 emulator, (the classic engine is deprecated!) # Note: only androidPlatformVersion <= 25 still provide images for this ABI # See nixpkgs/pkgs/development/mobile/androidenv/repo.json emulate-android-armeabi-v7a = androidEmulateApp { abiVersion = "armeabi-v7a"; }; android-sdk = inputs.android-nixpkgs.sdk ( sdkPkgs: with sdkPkgs; [ cmdline-tools-latest build-tools-34-0-0 platform-tools platforms-android-34 emulator ] ); }; devShell = let zipAlignPath = "${androidComposition.androidsdk}/libexec/android-sdk/build-tools/${androidBuildToolsVersion}/zipalign"; in pkgs.mkShell { buildInputs = [ (pkgs.android-studio.withSdk androidComposition.androidsdk) (pkgs.writeShellScriptBin "zipalign" ''exec ${zipAlignPath} "$@"'') androidComposition.androidsdk androidComposition.platform-tools pkgs.gradle pkgs.gradle.jdk ]; shellHook = '' # Note: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT. export ANDROID_SDK_ROOT="${androidComposition.androidsdk}/libexec/android-sdk" export ANDROID_NDK_ROOT="${androidComposition.androidsdk}/libexec/android-sdk/ndk-bundle" export PATH="$(echo "$ANDROID_SDK_ROOT/cmake/${androidCmakeVersion}".*/bin):$PATH" # Use the same androidBuildToolsVersion # and a statically linked aapt2 to workaround a dynamic linking failure. export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=$ANDROID_SDK_ROOT/build-tools/${androidBuildToolsVersion}/aapt2"; ''; }; } ); }