Files

171 lines
5.8 KiB
Nix

{
description = "Moonlight game streaming client for Android devShell + hermetic debug-APK build";
inputs = {
fleet.url = "git+https://git.oleks.space/oleks/fleet-pins";
nixpkgs.follows = "fleet/nixpkgs-projects";
};
outputs =
{
self,
fleet,
nixpkgs,
}:
let
# Android builds run on Linux hosts; the SDK is x86_64/aarch64-linux only.
systems = [
"x86_64-linux"
"aarch64-linux"
];
forAllSystems =
f:
nixpkgs.lib.genAttrs systems (
system:
f (
import nixpkgs {
inherit system;
config = {
allowUnfree = true; # Android SDK components are unfree
android_sdk.accept_license = true;
};
}
)
);
# Pinned to match app/build.gradle exactly.
ndkVersion = "27.0.12077973";
buildToolsVersion = "34.0.0";
platformVersion = "34";
in
{
# Compose the Android SDK once per system, reused by devShell + package.
legacyPackages = forAllSystems (pkgs: {
androidComposition = pkgs.androidenv.composeAndroidPackages {
platformVersions = [ platformVersion ];
buildToolsVersions = [ buildToolsVersion ];
includeNDK = true;
ndkVersions = [ ndkVersion ];
includeEmulator = false;
includeSystemImages = false;
includeSources = false;
};
});
# `nix develop` — JDK 17 + Android SDK/NDK + gradle, ready for `./gradlew`.
devShells = forAllSystems (
pkgs:
let
androidSdk = self.legacyPackages.${pkgs.system}.androidComposition.androidsdk;
sdkRoot = "${androidSdk}/libexec/android-sdk";
in
{
default = pkgs.mkShell {
packages = [
pkgs.jdk17
pkgs.gradle
androidSdk
# adb/fastboot — for sideloading the built APK to a device or an
# Android TV (Chromecast with Google TV) over the network.
pkgs.android-tools
];
ANDROID_HOME = sdkRoot;
ANDROID_SDK_ROOT = sdkRoot;
ANDROID_NDK_ROOT = "${sdkRoot}/ndk/${ndkVersion}";
JAVA_HOME = pkgs.jdk17.home;
# AGP downloads aapt2 from Maven; that prebuilt won't run on NixOS.
# Point it at the SDK's patched aapt2 instead.
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${sdkRoot}/build-tools/${buildToolsVersion}/aapt2";
shellHook = ''
echo "Android SDK: $ANDROID_HOME"
echo "NDK: $ANDROID_NDK_ROOT"
echo "Build the nonRoot debug APK with: ./gradlew assembleNonRootDebug"
'';
};
}
);
# `nix build` — hermetic, offline debug APK build via gradle's mitm-cache.
packages = forAllSystems (
pkgs:
let
androidSdk = self.legacyPackages.${pkgs.system}.androidComposition.androidsdk;
sdkRoot = "${androidSdk}/libexec/android-sdk";
in
{
default = self.packages.${pkgs.system}.moonlight-android;
moonlight-android = pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "moonlight-android";
version = "12.1";
# The repo, including the moonlight-common-c + enet submodules that must
# already be checked out (git submodule update --init --recursive).
src = ./.;
nativeBuildInputs = [
pkgs.gradle
pkgs.jdk17
androidSdk
];
# Offline Maven dependency cache. Regenerate deps.json with:
# nix build .#moonlight-android.mitmCache.updateScript && ./result
mitmCache = pkgs.gradle.fetchDeps {
inherit (finalAttrs) pname;
pkg = finalAttrs.finalPackage;
data = ./deps.json;
};
gradleBuildTask = "assembleNonRootDebug";
ANDROID_HOME = sdkRoot;
ANDROID_SDK_ROOT = sdkRoot;
ANDROID_NDK_ROOT = "${sdkRoot}/ndk/${ndkVersion}";
gradleFlags = [
"-Dorg.gradle.java.home=${pkgs.jdk17.home}"
# Use the SDK's runnable aapt2 instead of the Maven prebuilt.
"-Pandroid.aapt2FromMavenOverride=${sdkRoot}/build-tools/${buildToolsVersion}/aapt2"
# Skip resolving androidTest/test classpaths during dependency capture
# (AGP variant ambiguity on the self-referenced app project).
"--init-script"
"nix-deps-fixup.gradle"
];
postPatch = ''
# Tell Gradle where the SDK lives without relying on env detection.
echo "sdk.dir=${sdkRoot}" > local.properties
'';
# The debug build type auto-signs with a debug keystore that lands in
# $HOME/.android; the build sandbox's HOME is read-only, so redirect it.
preBuild = ''
export ANDROID_USER_HOME="$NIX_BUILD_TOP/.android"
export HOME="$NIX_BUILD_TOP/home"
mkdir -p "$ANDROID_USER_HOME" "$HOME"
'';
doCheck = false;
installPhase = ''
runHook preInstall
mkdir -p "$out"
find app/build/outputs/apk -name '*.apk' -exec cp -v {} "$out/" \;
runHook postInstall
'';
meta = {
description = "Moonlight game streaming client for Android (nonRoot debug APK)";
homepage = "https://github.com/moonlight-stream/moonlight-android";
license = pkgs.lib.licenses.gpl3Only;
platforms = systems;
};
});
}
);
};
}