171 lines
5.8 KiB
Nix
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;
|
|
};
|
|
});
|
|
}
|
|
);
|
|
};
|
|
}
|