{ inputs, system, pkgs, mainLynxBundle, }: let lib = pkgs.lib; config = rec { gradle = pkgs.gradle; androidPlatformVersion = "34"; androidBuildToolsVersion = "34.0.0"; #androidCmakeVersion = "3.22.1"; androidSdkArgs = { #cmakeVersions = [ androidCmakeVersion ]; platformVersions = [ androidPlatformVersion ]; abiVersions = [ #"arm64-v8a" #"armeabi-v7a" "x86_64" ]; buildToolsVersions = [ androidBuildToolsVersion ]; includeNDK = true; includeEmulator = false; includeSystemImages = true; systemImageTypes = [ #"google_apis" "google_apis_playstore" ]; extraLicenses = [ "android-sdk-license" "google-gdk-license" #"android-sdk-preview-license" #"android-googletv-license" #"android-sdk-arm-dbt-license" #"intel-android-extra-license" #"intel-android-sysimage-license" #"mips-android-sysimage-license" ]; }; androidEmulateAppArgs = rec { name = "android-emulate-app"; androidUserHome = null; #androidUserHome = "/var/lib/android"; deviceName = "device-${androidPlatformVersion}"; sdkExtraArgs = androidSdkArgs // { includeEmulator = true; }; platformVersion = androidPlatformVersion; systemImageType = "google_apis_playstore"; # PortabilityNote: workaround `-gpu host` not working # on my Vulkan system. androidEmulatorFlags = "-gpu guest"; configOptions = { "hw.keyboard" = "yes"; #"sdcard.path" = "${androidUserHome}/avd/${deviceName}.sdcard.img"; # 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"; }; }; ANDROID_SDK_ROOT = "${androidComposition.androidsdk}/libexec/android-sdk"; ANDROID_NDK_ROOT = "${androidComposition.androidsdk}/libexec/android-sdk/ndk-bundle"; androidComposition = pkgs.androidenv.composeAndroidPackages config.androidSdkArgs; }; in { inherit config; allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "android-sdk-build-tools" "android-sdk-cmdline-tools" "android-sdk-ndk" "android-sdk-platform-tools" "android-sdk-platforms" "emulator" "android-sdk-tools" "android-studio-stable" "android-emulate-app" "build-tools" "cmake" "cmdline-tools" "ndk" "platform-tools" "platforms" "tools" "android-sdk-emulator" "android-sdk-system-image-${config.androidPlatformVersion}-google_apis_playstore-x86_64" "system-image-${config.androidPlatformVersion}-google_apis_playstore-x86_64" "system-image-${config.androidPlatformVersion}-google_apis-x86_64" "android-sdk-system-image-${config.androidPlatformVersion}-google_apis-x86_64" ]; devShells = { default = { nativeBuildInputs = [ (pkgs.android-studio.withSdk config.androidComposition.androidsdk) config.androidComposition.androidsdk config.androidComposition.platform-tools config.androidComposition.emulator # For mksdcard config.gradle config.gradle.jdk pkgs.just pkgs.apkeep ]; shellHook = '' # ExplanationNote: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT. export ANDROID_SDK_ROOT="${config.ANDROID_SDK_ROOT}" export ANDROID_NDK_ROOT="${config.ANDROID_NDK_ROOT}" export PATH="${ lib.concatStringsSep ":" [ #"$ANDROID_SDK_ROOT/cmake/${config.androidCmakeVersion}/bin" "$ANDROID_SDK_ROOT/build-tools/${config.androidBuildToolsVersion}" "$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/${config.androidBuildToolsVersion}/aapt2"; ''; }; }; packages = rec { default = pkgs.stdenv.mkDerivation (finalAttrs: { pname = "${mainLynxBundle.pname}-apk"; version = mainLynxBundle.version; src = with lib.fileset; toSource rec { root = ./.; fileset = unions [ (fileFilter ( file: lib.any file.hasExt [ "java" "kt" "toml" "xml" ] ) ./app) ./build.gradle ./gradle.properties ./settings.gradle app/build.gradle app/proguard-rules.pro app/src/main/res gradle/libs.versions.toml ]; }; inherit (config) ANDROID_SDK_ROOT ANDROID_NDK_ROOT ; nativeBuildInputs = [ config.gradle pkgs.makeWrapper ]; mitmCache = config.gradle.fetchDeps { pkg = finalAttrs.finalPackage; # MaintenanceNote: nix -L run .#default.update-deps data = ./deps.json; }; passthru = { update-deps = pkgs.writeShellApplication { name = "update-deps.sh"; text = '' exec ${finalAttrs.finalPackage.mitmCache.updateScript} ''; }; }; # this is required for using mitm-cache on Darwin __darwinAllowLocalNetworking = true; gradleFlags = [ "-Dfile.encoding=utf-8" # Use the same androidBuildToolsVersion # and a statically linked aapt2 to workaround a dynamic linking failure. "-Dorg.gradle.project.android.aapt2FromMavenOverride=${config.ANDROID_SDK_ROOT}/build-tools/${config.androidBuildToolsVersion}/aapt2" ]; #gradleBuildTask = "shadowJar"; gradleBuildTask = "assemble"; # MaintenanceToDo: remove this `gradleUpdateScript` # if https://github.com/NixOS/nixpkgs/pull/383115 # is ever merged. gradleUpdateScript = '' runHook preBuild gradle help --write-verification-metadata sha256 ''; # will run the gradleCheckTask (defaults to "test") doCheck = false; preBuild = '' install -Dm440 \ ${mainLynxBundle}/main.lynx.bundle \ app/src/main/assets/main.lynx.bundle ''; installPhase = '' mkdir -p $out ${ if finalAttrs.gradleBuildTask == "bundleRelease" then "cp -RL app/build/outputs/bundle/release/*.aab $out" else "cp -RL app/build/outputs/apk/*/*.apk $out" } ''; meta.sourceProvenance = with lib.sourceTypes; [ fromSource binaryBytecode # mitm cache ]; }); # Run the app into an Android emulator android-emulator-x86_64 = pkgs.androidenv.emulateApp ( config.androidEmulateAppArgs // { abiVersion = "x86_64"; # SecurityToDo: sign the APK # See: https://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle app = "${default}/app-debug.apk"; #app = "${default}/app-release-unsigned.apk"; package = "com.lynx.javaemptyproject"; activity = ".MainActivity"; } ); }; }