lol

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.

+62 -25
+48 -25
pkgs/development/mobile/androidenv/compose-android-packages.nix
··· 13 13 let 14 14 # Coerces a string to an int. 15 15 coerceInt = val: if lib.isInt val then val else lib.toIntBase10 val; 16 + 17 + # Parses a single version, substituting "latest" with the latest version. 18 + parseVersion = 19 + repo: key: version: 20 + if version == "latest" then repo.latest.${key} else version; 21 + 22 + # Parses a list of versions, substituting "latest" with the latest version. 23 + parseVersions = 24 + repo: key: versions: 25 + lib.unique (map (parseVersion repo key) versions); 16 26 in 17 27 { 18 28 repoJson ? ./repo.json, ··· 74 84 else 75 85 lib.importJSON repoJson 76 86 ), 77 - cmdLineToolsVersion ? repo.latest.cmdline-tools, 78 - toolsVersion ? repo.latest.tools, 79 - platformToolsVersion ? repo.latest.platform-tools, 80 - buildToolsVersions ? [ repo.latest.build-tools ], 87 + cmdLineToolsVersion ? "latest", 88 + toolsVersion ? "latest", 89 + platformToolsVersion ? "latest", 90 + buildToolsVersions ? [ "latest" ], 81 91 includeEmulator ? false, 82 - emulatorVersion ? repo.latest.emulator, 92 + emulatorVersion ? "latest", 83 93 minPlatformVersion ? null, 84 - maxPlatformVersion ? coerceInt repo.latest.platforms, 94 + maxPlatformVersion ? "latest", 85 95 numLatestPlatformVersions ? 1, 86 96 platformVersions ? 87 97 if minPlatformVersion != null && maxPlatformVersion != null then 88 98 let 89 - minPlatformVersionInt = coerceInt minPlatformVersion; 90 - maxPlatformVersionInt = coerceInt maxPlatformVersion; 99 + minPlatformVersionInt = coerceInt (parseVersion repo "platforms" minPlatformVersion); 100 + maxPlatformVersionInt = coerceInt (parseVersion repo "platforms" maxPlatformVersion); 91 101 in 92 102 lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) ( 93 103 lib.max minPlatformVersionInt maxPlatformVersionInt 94 104 ) 95 105 else 96 106 let 97 - minPlatformVersionInt = if minPlatformVersion == null then 1 else coerceInt minPlatformVersion; 107 + minPlatformVersionInt = 108 + if minPlatformVersion == null then 109 + 1 110 + else 111 + coerceInt (parseVersion repo "platforms" minPlatformVersion); 98 112 latestPlatformVersionInt = lib.max minPlatformVersionInt (coerceInt repo.latest.platforms); 99 113 firstPlatformVersionInt = lib.max minPlatformVersionInt ( 100 114 latestPlatformVersionInt - (lib.max 1 numLatestPlatformVersions) + 1 ··· 115 129 ], 116 130 # cmake has precompiles on x86_64 and Darwin platforms. Default to true there for compatibility. 117 131 includeCmake ? stdenv.hostPlatform.isx86_64 || stdenv.hostPlatform.isDarwin, 118 - cmakeVersions ? [ repo.latest.cmake ], 132 + cmakeVersions ? [ "latest" ], 119 133 includeNDK ? false, 120 - ndkVersion ? repo.latest.ndk, 134 + ndkVersion ? "latest", 121 135 ndkVersions ? [ ndkVersion ], 122 136 useGoogleAPIs ? false, 123 137 useGoogleTVAddOns ? false, ··· 126 140 }: 127 141 128 142 let 143 + # Resolve all the platform versions. 144 + platformVersions' = map coerceInt (parseVersions repo "platforms" platformVersions); 145 + 129 146 # Determine the Android os identifier from Nix's system identifier 130 147 os = 131 148 { ··· 420 437 arch 421 438 meta 422 439 ; 423 - package = checkVersion allArchives.packages "platform-tools" platformToolsVersion; 440 + package = checkVersion allArchives.packages "platform-tools" ( 441 + parseVersion repo "platform-tools" platformToolsVersion 442 + ); 424 443 }; 425 444 426 445 tools = callPackage ./tools.nix { ··· 430 449 arch 431 450 meta 432 451 ; 433 - package = checkVersion allArchives.packages "tools" toolsVersion; 452 + package = checkVersion allArchives.packages "tools" (parseVersion repo "tools" toolsVersion); 434 453 435 454 postInstall = '' 436 455 ${linkPlugin { ··· 464 483 }} 465 484 ''; 466 485 } 467 - ) buildToolsVersions; 486 + ) (parseVersions repo "build-tools" buildToolsVersions); 468 487 469 488 emulator = callPackage ./emulator.nix { 470 489 inherit ··· 473 492 arch 474 493 meta 475 494 ; 476 - package = checkVersion allArchives.packages "emulator" emulatorVersion; 495 + package = checkVersion allArchives.packages "emulator" ( 496 + parseVersion repo "emulator" emulatorVersion 497 + ); 477 498 478 499 postInstall = '' 479 500 ${linkSystemImages { ··· 483 504 ''; 484 505 }; 485 506 486 - inherit platformVersions; 507 + platformVersions = platformVersions'; 487 508 488 509 platforms = map ( 489 510 version: 490 511 deployAndroidPackage { 491 512 package = checkVersion allArchives.packages "platforms" version; 492 513 } 493 - ) platformVersions; 514 + ) platformVersions'; 494 515 495 516 sources = map ( 496 517 version: 497 518 deployAndroidPackage { 498 519 package = checkVersion allArchives.packages "sources" version; 499 520 } 500 - ) platformVersions; 521 + ) platformVersions'; 501 522 502 523 system-images = lib.flatten ( 503 524 map ( ··· 538 559 patchesInstructions = instructions; 539 560 }) 540 561 ) systemImageTypes 541 - ) platformVersions 562 + ) platformVersions' 542 563 ); 543 564 544 565 cmake = map ( ··· 552 573 ; 553 574 package = checkVersion allArchives.packages "cmake" version; 554 575 } 555 - ) cmakeVersions; 576 + ) (parseVersions repo "cmake" cmakeVersions); 556 577 557 578 # All NDK bundles. 558 579 ndk-bundles = ··· 576 597 version: 577 598 let 578 599 package = makeNdkBundle ( 579 - allArchives.packages.ndk-bundle.${ndkVersion} or allArchives.packages.ndk.${ndkVersion} 600 + allArchives.packages.ndk-bundle.${version} or allArchives.packages.ndk.${version} 580 601 ); 581 602 in 582 603 lib.optional (shouldLink includeNDK [ package ]) package 583 - ) ndkVersions 604 + ) (parseVersions repo "ndk" ndkVersions) 584 605 ); 585 606 586 607 # The "default" NDK bundle. ··· 592 613 deployAndroidPackage { 593 614 package = (checkVersion allArchives "addons" version).google_apis; 594 615 } 595 - ) (lib.filter (hasVersion allArchives "addons") platformVersions); 616 + ) (lib.filter (hasVersion allArchives "addons") platformVersions'); 596 617 597 618 # Makes a Google TV addons bundle from supported versions. 598 619 google-tv-addons = map ( ··· 600 621 deployAndroidPackage { 601 622 package = (checkVersion allArchives "addons" version).google_tv_addon; 602 623 } 603 - ) (lib.filter (hasVersion allArchives "addons") platformVersions); 624 + ) (lib.filter (hasVersion allArchives "addons") platformVersions'); 604 625 605 - cmdline-tools-package = checkVersion allArchives.packages "cmdline-tools" cmdLineToolsVersion; 626 + cmdline-tools-package = checkVersion allArchives.packages "cmdline-tools" ( 627 + parseVersion repo "cmdline-tools" cmdLineToolsVersion 628 + ); 606 629 607 630 # This derivation deploys the tools package and symlinks all the desired 608 631 # plugins that we want to use. If the license isn't accepted, prints all the licenses
+14
pkgs/development/mobile/androidenv/examples/shell.nix
··· 45 45 # The head unit only works on these platforms 46 46 includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin; 47 47 48 + ndkVersions = [ 49 + "23.1.7779620" 50 + "25.1.8937393" 51 + "26.1.10909125" 52 + "latest" 53 + ]; 54 + 48 55 androidComposition = androidEnv.composeAndroidPackages { 49 56 includeSources = true; 50 57 includeSystemImages = false; 51 58 includeEmulator = "if-supported"; 52 59 includeNDK = "if-supported"; 60 + inherit ndkVersions; 53 61 useGoogleAPIs = true; 54 62 useGoogleTVAddOns = true; 55 63 ··· 190 198 exit 1 191 199 fi 192 200 done 201 + 202 + num_ndk_packages="$(echo "$installed_packages_section" | grep '^ndk;' | wc -l)" 203 + if [ $num_ndk_packages -ne ${toString (pkgs.lib.length ndkVersions)} ]; then 204 + echo "Invalid NDK package count: $num_ndk_packages" 205 + exit 1 206 + fi 193 207 194 208 touch "$out" 195 209 '';