androidenv: support linking "latest" version of all plugins

As noted in #379534, the NDK linking broke during refactoring. Add a test
for that, and support linking the latest for all platform plugins that
take at least one version.
This commit is contained in:
Morgan Jones 2025-04-27 15:27:48 -07:00
parent dac36fa94c
commit f97ca76b10
No known key found for this signature in database
GPG key ID: 5C3EB94D198F1491
2 changed files with 62 additions and 25 deletions

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"
''; '';
}; };