androidenv: support linking "latest" version of all plugins (fixing NDK linking) (#402391)

This commit is contained in:
Atemu 2025-04-28 13:52:13 +02:00 committed by GitHub
commit a0db7f802e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 65 additions and 26 deletions

View file

@ -50,6 +50,7 @@ let
platformVersions = [ platformVersions = [
"34" "34"
"35" "35"
"latest"
]; ];
systemImageTypes = [ "google_apis_playstore" ]; systemImageTypes = [ "google_apis_playstore" ];
abiVersions = [ abiVersions = [
@ -130,7 +131,8 @@ For each requested system image we can specify the following options:
be included. Defaults to `armeabi-v7a` and `arm64-v8a`. be included. Defaults to `armeabi-v7a` and `arm64-v8a`.
Most of the function arguments have reasonable default settings, preferring the latest Most of the function arguments have reasonable default settings, preferring the latest
versions of tools when possible. versions of tools when possible. You can additionally specify "latest" for any plugin version
that you do not care about, and just want the latest of.
You can specify license names: You can specify license names:

View file

@ -13,6 +13,16 @@
let let
# Coerces a string to an int. # Coerces a string to an int.
coerceInt = val: if lib.isInt val then val else lib.toIntBase10 val; coerceInt = val: if lib.isInt val then val else lib.toIntBase10 val;
# Parses a single version, substituting "latest" with the latest version.
parseVersion =
repo: key: version:
if version == "latest" then repo.latest.${key} else version;
# Parses a list of versions, substituting "latest" with the latest version.
parseVersions =
repo: key: versions:
lib.unique (map (parseVersion repo key) versions);
in in
{ {
repoJson ? ./repo.json, repoJson ? ./repo.json,
@ -74,27 +84,31 @@ in
else else
lib.importJSON repoJson lib.importJSON repoJson
), ),
cmdLineToolsVersion ? repo.latest.cmdline-tools, cmdLineToolsVersion ? "latest",
toolsVersion ? repo.latest.tools, toolsVersion ? "latest",
platformToolsVersion ? repo.latest.platform-tools, platformToolsVersion ? "latest",
buildToolsVersions ? [ repo.latest.build-tools ], buildToolsVersions ? [ "latest" ],
includeEmulator ? false, includeEmulator ? false,
emulatorVersion ? repo.latest.emulator, emulatorVersion ? "latest",
minPlatformVersion ? null, minPlatformVersion ? null,
maxPlatformVersion ? coerceInt repo.latest.platforms, maxPlatformVersion ? "latest",
numLatestPlatformVersions ? 1, numLatestPlatformVersions ? 1,
platformVersions ? platformVersions ?
if minPlatformVersion != null && maxPlatformVersion != null then if minPlatformVersion != null && maxPlatformVersion != null then
let let
minPlatformVersionInt = coerceInt minPlatformVersion; minPlatformVersionInt = coerceInt (parseVersion repo "platforms" minPlatformVersion);
maxPlatformVersionInt = coerceInt maxPlatformVersion; maxPlatformVersionInt = coerceInt (parseVersion repo "platforms" maxPlatformVersion);
in in
lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) ( lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) (
lib.max minPlatformVersionInt maxPlatformVersionInt lib.max minPlatformVersionInt maxPlatformVersionInt
) )
else else
let let
minPlatformVersionInt = if minPlatformVersion == null then 1 else coerceInt minPlatformVersion; minPlatformVersionInt =
if minPlatformVersion == null then
1
else
coerceInt (parseVersion repo "platforms" minPlatformVersion);
latestPlatformVersionInt = lib.max minPlatformVersionInt (coerceInt repo.latest.platforms); latestPlatformVersionInt = lib.max minPlatformVersionInt (coerceInt repo.latest.platforms);
firstPlatformVersionInt = lib.max minPlatformVersionInt ( firstPlatformVersionInt = lib.max minPlatformVersionInt (
latestPlatformVersionInt - (lib.max 1 numLatestPlatformVersions) + 1 latestPlatformVersionInt - (lib.max 1 numLatestPlatformVersions) + 1
@ -115,9 +129,9 @@ in
], ],
# cmake has precompiles on x86_64 and Darwin platforms. Default to true there for compatibility. # cmake has precompiles on x86_64 and Darwin platforms. Default to true there for compatibility.
includeCmake ? stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isDarwin, includeCmake ? stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isDarwin,
cmakeVersions ? [ repo.latest.cmake ], cmakeVersions ? [ "latest" ],
includeNDK ? false, includeNDK ? false,
ndkVersion ? repo.latest.ndk, ndkVersion ? "latest",
ndkVersions ? [ ndkVersion ], ndkVersions ? [ ndkVersion ],
useGoogleAPIs ? false, useGoogleAPIs ? false,
useGoogleTVAddOns ? false, useGoogleTVAddOns ? false,
@ -126,6 +140,9 @@ in
}: }:
let let
# Resolve all the platform versions.
platformVersions' = map coerceInt (parseVersions repo "platforms" platformVersions);
# Determine the Android os identifier from Nix's system identifier # Determine the Android os identifier from Nix's system identifier
os = os =
{ {
@ -420,7 +437,9 @@ lib.recurseIntoAttrs rec {
arch arch
meta meta
; ;
package = checkVersion allArchives.packages "platform-tools" platformToolsVersion; package = checkVersion allArchives.packages "platform-tools" (
parseVersion repo "platform-tools" platformToolsVersion
);
}; };
tools = callPackage ./tools.nix { tools = callPackage ./tools.nix {
@ -430,7 +449,7 @@ lib.recurseIntoAttrs rec {
arch arch
meta meta
; ;
package = checkVersion allArchives.packages "tools" toolsVersion; package = checkVersion allArchives.packages "tools" (parseVersion repo "tools" toolsVersion);
postInstall = '' postInstall = ''
${linkPlugin { ${linkPlugin {
@ -464,7 +483,7 @@ lib.recurseIntoAttrs rec {
}} }}
''; '';
} }
) buildToolsVersions; ) (parseVersions repo "build-tools" buildToolsVersions);
emulator = callPackage ./emulator.nix { emulator = callPackage ./emulator.nix {
inherit inherit
@ -473,7 +492,9 @@ lib.recurseIntoAttrs rec {
arch arch
meta meta
; ;
package = checkVersion allArchives.packages "emulator" emulatorVersion; package = checkVersion allArchives.packages "emulator" (
parseVersion repo "emulator" emulatorVersion
);
postInstall = '' postInstall = ''
${linkSystemImages { ${linkSystemImages {
@ -483,21 +504,21 @@ lib.recurseIntoAttrs rec {
''; '';
}; };
inherit platformVersions; platformVersions = platformVersions';
platforms = map ( platforms = map (
version: version:
deployAndroidPackage { deployAndroidPackage {
package = checkVersion allArchives.packages "platforms" version; package = checkVersion allArchives.packages "platforms" version;
} }
) platformVersions; ) platformVersions';
sources = map ( sources = map (
version: version:
deployAndroidPackage { deployAndroidPackage {
package = checkVersion allArchives.packages "sources" version; package = checkVersion allArchives.packages "sources" version;
} }
) platformVersions; ) platformVersions';
system-images = lib.flatten ( system-images = lib.flatten (
map ( map (
@ -538,7 +559,7 @@ lib.recurseIntoAttrs rec {
patchesInstructions = instructions; patchesInstructions = instructions;
}) })
) systemImageTypes ) systemImageTypes
) platformVersions ) platformVersions'
); );
cmake = map ( cmake = map (
@ -552,7 +573,7 @@ lib.recurseIntoAttrs rec {
; ;
package = checkVersion allArchives.packages "cmake" version; package = checkVersion allArchives.packages "cmake" version;
} }
) cmakeVersions; ) (parseVersions repo "cmake" cmakeVersions);
# All NDK bundles. # All NDK bundles.
ndk-bundles = ndk-bundles =
@ -576,11 +597,11 @@ lib.recurseIntoAttrs rec {
version: version:
let let
package = makeNdkBundle ( package = makeNdkBundle (
allArchives.packages.ndk-bundle.${ndkVersion} or allArchives.packages.ndk.${ndkVersion} allArchives.packages.ndk-bundle.${version} or allArchives.packages.ndk.${version}
); );
in in
lib.optional (shouldLink includeNDK [ package ]) package lib.optional (shouldLink includeNDK [ package ]) package
) ndkVersions ) (parseVersions repo "ndk" ndkVersions)
); );
# The "default" NDK bundle. # The "default" NDK bundle.
@ -592,7 +613,7 @@ lib.recurseIntoAttrs rec {
deployAndroidPackage { deployAndroidPackage {
package = (checkVersion allArchives "addons" version).google_apis; package = (checkVersion allArchives "addons" version).google_apis;
} }
) (lib.filter (hasVersion allArchives "addons") platformVersions); ) (lib.filter (hasVersion allArchives "addons") platformVersions');
# Makes a Google TV addons bundle from supported versions. # Makes a Google TV addons bundle from supported versions.
google-tv-addons = map ( google-tv-addons = map (
@ -600,9 +621,11 @@ lib.recurseIntoAttrs rec {
deployAndroidPackage { deployAndroidPackage {
package = (checkVersion allArchives "addons" version).google_tv_addon; package = (checkVersion allArchives "addons" version).google_tv_addon;
} }
) (lib.filter (hasVersion allArchives "addons") platformVersions); ) (lib.filter (hasVersion allArchives "addons") platformVersions');
cmdline-tools-package = checkVersion allArchives.packages "cmdline-tools" cmdLineToolsVersion; cmdline-tools-package = checkVersion allArchives.packages "cmdline-tools" (
parseVersion repo "cmdline-tools" cmdLineToolsVersion
);
# This derivation deploys the tools package and symlinks all the desired # This derivation deploys the tools package and symlinks all the desired
# plugins that we want to use. If the license isn't accepted, prints all the licenses # plugins that we want to use. If the license isn't accepted, prints all the licenses

View file

@ -45,11 +45,19 @@ let
# The head unit only works on these platforms # The head unit only works on these platforms
includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin; includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin;
ndkVersions = [
"23.1.7779620"
"25.1.8937393"
"26.1.10909125"
"latest"
];
androidComposition = androidEnv.composeAndroidPackages { androidComposition = androidEnv.composeAndroidPackages {
includeSources = true; includeSources = true;
includeSystemImages = false; includeSystemImages = false;
includeEmulator = "if-supported"; includeEmulator = "if-supported";
includeNDK = "if-supported"; includeNDK = "if-supported";
inherit ndkVersions;
useGoogleAPIs = true; useGoogleAPIs = true;
useGoogleTVAddOns = true; useGoogleTVAddOns = true;
@ -191,6 +199,12 @@ pkgs.mkShell rec {
fi fi
done done
num_ndk_packages="$(echo "$installed_packages_section" | grep '^ndk;' | wc -l)"
if [ $num_ndk_packages -ne ${toString (pkgs.lib.length ndkVersions)} ]; then
echo "Invalid NDK package count: $num_ndk_packages"
exit 1
fi
touch "$out" touch "$out"
''; '';
}; };