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 = [
"34"
"35"
"latest"
];
systemImageTypes = [ "google_apis_playstore" ];
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`.
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:

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