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
# Coerces a string to an int.
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
{
repoJson ? ./repo.json,
@ -74,27 +84,31 @@ in
else
lib.importJSON repoJson
),
cmdLineToolsVersion ? repo.latest.cmdline-tools,
toolsVersion ? repo.latest.tools,
platformToolsVersion ? repo.latest.platform-tools,
buildToolsVersions ? [ repo.latest.build-tools ],
cmdLineToolsVersion ? "latest",
toolsVersion ? "latest",
platformToolsVersion ? "latest",
buildToolsVersions ? [ "latest" ],
includeEmulator ? false,
emulatorVersion ? repo.latest.emulator,
emulatorVersion ? "latest",
minPlatformVersion ? null,
maxPlatformVersion ? coerceInt repo.latest.platforms,
maxPlatformVersion ? "latest",
numLatestPlatformVersions ? 1,
platformVersions ?
if minPlatformVersion != null && maxPlatformVersion != null then
let
minPlatformVersionInt = coerceInt minPlatformVersion;
maxPlatformVersionInt = coerceInt maxPlatformVersion;
minPlatformVersionInt = coerceInt (parseVersion repo "platforms" minPlatformVersion);
maxPlatformVersionInt = coerceInt (parseVersion repo "platforms" maxPlatformVersion);
in
lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) (
lib.max minPlatformVersionInt maxPlatformVersionInt
)
else
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);
firstPlatformVersionInt = lib.max minPlatformVersionInt (
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.
includeCmake ? stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isDarwin,
cmakeVersions ? [ repo.latest.cmake ],
cmakeVersions ? [ "latest" ],
includeNDK ? false,
ndkVersion ? repo.latest.ndk,
ndkVersion ? "latest",
ndkVersions ? [ ndkVersion ],
useGoogleAPIs ? false,
useGoogleTVAddOns ? false,
@ -126,6 +140,9 @@ in
}:
let
# Resolve all the platform versions.
platformVersions' = map coerceInt (parseVersions repo "platforms" platformVersions);
# Determine the Android os identifier from Nix's system identifier
os =
{
@ -420,7 +437,9 @@ lib.recurseIntoAttrs rec {
arch
meta
;
package = checkVersion allArchives.packages "platform-tools" platformToolsVersion;
package = checkVersion allArchives.packages "platform-tools" (
parseVersion repo "platform-tools" platformToolsVersion
);
};
tools = callPackage ./tools.nix {
@ -430,7 +449,7 @@ lib.recurseIntoAttrs rec {
arch
meta
;
package = checkVersion allArchives.packages "tools" toolsVersion;
package = checkVersion allArchives.packages "tools" (parseVersion repo "tools" toolsVersion);
postInstall = ''
${linkPlugin {
@ -464,7 +483,7 @@ lib.recurseIntoAttrs rec {
}}
'';
}
) buildToolsVersions;
) (parseVersions repo "build-tools" buildToolsVersions);
emulator = callPackage ./emulator.nix {
inherit
@ -473,7 +492,9 @@ lib.recurseIntoAttrs rec {
arch
meta
;
package = checkVersion allArchives.packages "emulator" emulatorVersion;
package = checkVersion allArchives.packages "emulator" (
parseVersion repo "emulator" emulatorVersion
);
postInstall = ''
${linkSystemImages {
@ -483,21 +504,21 @@ lib.recurseIntoAttrs rec {
'';
};
inherit platformVersions;
platformVersions = platformVersions';
platforms = map (
version:
deployAndroidPackage {
package = checkVersion allArchives.packages "platforms" version;
}
) platformVersions;
) platformVersions';
sources = map (
version:
deployAndroidPackage {
package = checkVersion allArchives.packages "sources" version;
}
) platformVersions;
) platformVersions';
system-images = lib.flatten (
map (
@ -538,7 +559,7 @@ lib.recurseIntoAttrs rec {
patchesInstructions = instructions;
})
) systemImageTypes
) platformVersions
) platformVersions'
);
cmake = map (
@ -552,7 +573,7 @@ lib.recurseIntoAttrs rec {
;
package = checkVersion allArchives.packages "cmake" version;
}
) cmakeVersions;
) (parseVersions repo "cmake" cmakeVersions);
# All NDK bundles.
ndk-bundles =
@ -576,11 +597,11 @@ lib.recurseIntoAttrs rec {
version:
let
package = makeNdkBundle (
allArchives.packages.ndk-bundle.${ndkVersion} or allArchives.packages.ndk.${ndkVersion}
allArchives.packages.ndk-bundle.${version} or allArchives.packages.ndk.${version}
);
in
lib.optional (shouldLink includeNDK [ package ]) package
) ndkVersions
) (parseVersions repo "ndk" ndkVersions)
);
# The "default" NDK bundle.
@ -592,7 +613,7 @@ lib.recurseIntoAttrs rec {
deployAndroidPackage {
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.
google-tv-addons = map (
@ -600,9 +621,11 @@ lib.recurseIntoAttrs rec {
deployAndroidPackage {
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
# 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
includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin;
ndkVersions = [
"23.1.7779620"
"25.1.8937393"
"26.1.10909125"
"latest"
];
androidComposition = androidEnv.composeAndroidPackages {
includeSources = true;
includeSystemImages = false;
includeEmulator = "if-supported";
includeNDK = "if-supported";
inherit ndkVersions;
useGoogleAPIs = true;
useGoogleTVAddOns = true;
@ -191,6 +199,12 @@ pkgs.mkShell rec {
fi
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"
'';
};