androidenv: support if-supported for include* options

This lets us stop hardcoding platforms and start filtering for which
archives have sources, which is the most accurate way to do it.

Tested on x86_64-linux, aarch64-linux, and aarch64-darwin.

+2 -2
pkgs/development/mobile/androidenv/build-tools.nix
···
-
{deployAndroidPackage, lib, stdenv, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall, meta}:
+
{deployAndroidPackage, lib, stdenv, package, os, arch, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall, meta}:
deployAndroidPackage {
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") [ pkgs.glibc pkgs.zlib pkgs.ncurses5 pkgs.libcxx ]
+2 -2
pkgs/development/mobile/androidenv/cmake.nix
···
-
{deployAndroidPackage, lib, package, os, autoPatchelfHook, pkgs, stdenv, meta}:
+
{deployAndroidPackage, lib, package, os, arch, autoPatchelfHook, pkgs, stdenv, meta}:
deployAndroidPackage {
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") [ pkgs.stdenv.cc.libc pkgs.stdenv.cc.cc pkgs.ncurses5 ];
patchInstructions = lib.optionalString (os == "linux") ''
+2 -1
pkgs/development/mobile/androidenv/cmdline-tools.nix
···
autoPatchelfHook,
makeWrapper,
os,
+
arch,
pkgs,
stdenv,
postInstall,
···
deployAndroidPackage {
name = "androidsdk";
-
inherit package os;
+
inherit package os arch;
nativeBuildInputs = [
makeWrapper
] ++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
+64 -41
pkgs/development/mobile/androidenv/compose-android-packages.nix
···
, includeSystemImages ? false
, systemImageTypes ? [ "google_apis" "google_apis_playstore" ]
, abiVersions ? [ "x86" "x86_64" "armeabi-v7a" "arm64-v8a" ]
+
# 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 ]
, includeNDK ? false
, ndkVersion ? repo.latest.ndk
···
let
isTargetOs = if builtins.hasAttr "os" archive then
archive.os == os || archive.os == "all" else true;
-
isTargetArc = if builtins.hasAttr "arch" archive then
+
isTargetArch = if builtins.hasAttr "arch" archive then
archive.arch == arch || archive.arch == "all" else true;
in
-
isTargetOs && isTargetArc
+
isTargetOs && isTargetArch
) value;
in
-
lib.warnIf (builtins.length validArchives == 0)
-
"No valid archives for ${lib.concatMapStringsSep "." (x: ''"${x}"'') path} for os=${os}, arch=${arch}"
-
(lib.optionals (builtins.length validArchives > 0)
-
(lib.last (map (archive:
-
(fetchurl { inherit (archive) url sha1; })
-
) validArchives)))
+
lib.optionals (builtins.length validArchives > 0)
+
(lib.last (map (archive:
+
(fetchurl { inherit (archive) url sha1; })
+
) validArchives))
else value
)
attrSet;
···
in
lib.recurseIntoAttrs rec {
deployAndroidPackages = callPackage ./deploy-androidpackages.nix {
-
inherit stdenv lib mkLicenses meta;
+
inherit stdenv lib mkLicenses meta os arch;
};
deployAndroidPackage = ({package, buildInputs ? [], patchInstructions ? "", meta ? {}, ...}@args:
let
-
extraParams = removeAttrs args [ "package" "os" "buildInputs" "patchInstructions" ];
+
extraParams = removeAttrs args [ "package" "os" "arch" "buildInputs" "patchInstructions" ];
in
deployAndroidPackages ({
inherit buildInputs;
···
'';
platform-tools = callPackage ./platform-tools.nix {
-
inherit deployAndroidPackage os meta;
+
inherit deployAndroidPackage os arch meta;
package = check-version packages "platform-tools" platformToolsVersion;
};
tools = callPackage ./tools.nix {
-
inherit deployAndroidPackage os meta;
+
inherit deployAndroidPackage os arch meta;
package = check-version packages "tools" toolsVersion;
postInstall = ''
···
build-tools = map (version:
callPackage ./build-tools.nix {
-
inherit deployAndroidPackage os meta;
+
inherit deployAndroidPackage os arch meta;
package = check-version packages "build-tools" version;
postInstall = ''
···
}
) buildToolsVersions;
-
emulator = lib.optionals includeEmulator (callPackage ./emulator.nix {
-
inherit deployAndroidPackage os meta;
-
package = check-version packages "emulator" emulatorVersion;
+
emulator =
+
callPackage ./emulator.nix {
+
inherit deployAndroidPackage os arch meta;
+
package = check-version packages "emulator" emulatorVersion;
-
postInstall = ''
-
${linkSystemImages { images = system-images; check = includeSystemImages; }}
-
'';
-
});
+
postInstall = ''
+
${linkSystemImages { images = system-images; check = includeSystemImages; }}
+
'';
+
};
platforms = map (version:
deployAndroidPackage {
···
cmake = map (version:
callPackage ./cmake.nix {
-
inherit deployAndroidPackage os meta;
+
inherit deployAndroidPackage os arch meta;
package = check-version packages "cmake" version;
}
) cmakeVersions;
+
# Returns true if we should link the specified plugins.
+
shouldLink = check: packages:
+
assert builtins.isList packages;
+
if check == true then
+
true
+
else if check == false then
+
false
+
else if check == null || check == "if-supported" then
+
let
+
hasSrc = package: package.src != null && (builtins.isList package.src -> builtins.length package.src > 0);
+
in
+
packages != [] && lib.all hasSrc packages
+
else
+
throw "Invalid argument ${toString check}; use true, false, or null/if-supported";
+
# Creates a NDK bundle.
-
makeNdkBundle = ndkVersion:
+
makeNdkBundle = package:
callPackage ./ndk-bundle {
-
inherit deployAndroidPackage os platform-tools meta;
-
package = packages.ndk-bundle.${ndkVersion} or packages.ndk.${ndkVersion};
+
inherit deployAndroidPackage os arch platform-tools meta package;
};
# All NDK bundles.
-
ndk-bundles = lib.optionals includeNDK (map makeNdkBundle ndkVersions);
+
ndk-bundles = lib.flatten (
+
map (version:
+
let
+
package = makeNdkBundle (packages.ndk-bundle.${ndkVersion} or packages.ndk.${ndkVersion});
+
in
+
lib.optional (shouldLink includeNDK [package]) package
+
) ndkVersions
+
);
# The "default" NDK bundle.
-
ndk-bundle = if includeNDK then lib.findFirst (x: x != null) null ndk-bundles else null;
+
ndk-bundle = if ndk-bundles == [] then null else lib.head ndk-bundles;
+
# Makes a Google API bundle.
google-apis = map (version:
deployAndroidPackage {
package = (check-version addons "addons" version).google_apis;
}
-
) (builtins.filter (platformVersion: platformVersion < "26") platformVersions); # API level 26 and higher include Google APIs by default
+
) (builtins.filter (platformVersion: lib.versionOlder platformVersion "26") platformVersions); # API level 26 and higher include Google APIs by default
google-tv-addons = map (version:
deployAndroidPackage {
···
) platformVersions;
# Function that automatically links all plugins for which multiple versions can coexist
-
linkPlugins = {name, plugins}:
-
lib.optionalString (plugins != []) ''
+
linkPlugins = {name, plugins, check ? true}:
+
lib.optionalString (shouldLink check plugins) ''
mkdir -p ${name}
${lib.concatMapStrings (plugin: ''
ln -s ${plugin}/libexec/android-sdk/${name}/* ${name}
···
'';
# Function that automatically links all NDK plugins.
-
linkNdkPlugins = {name, plugins, rootName ? name}:
-
lib.optionalString (plugins != []) ''
+
linkNdkPlugins = {name, plugins, rootName ? name, check ? true}:
+
lib.optionalString (shouldLink check plugins) ''
mkdir -p ${rootName}
${lib.concatMapStrings (plugin: ''
ln -s ${plugin}/libexec/android-sdk/${name} ${rootName}/${plugin.version}
···
# Function that automatically links the default NDK plugin.
linkNdkPlugin = {name, plugin, check}:
-
lib.optionalString check ''
+
lib.optionalString (shouldLink check [plugin]) ''
ln -s ${plugin}/libexec/android-sdk/${name} ${name}
'';
# Function that automatically links a plugin for which only one version exists
linkPlugin = {name, plugin, check ? true}:
-
lib.optionalString check ''
+
lib.optionalString (shouldLink check [plugin]) ''
ln -s ${plugin}/libexec/android-sdk/${name} ${name}
'';
-
linkSystemImages = { images, check }: lib.optionalString check ''
+
linkSystemImages = { images, check }: lib.optionalString (shouldLink check images) ''
mkdir -p system-images
${lib.concatMapStrings (system-image: ''
apiVersion=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*))
···
# Links all plugins related to a requested platform
linkPlatformPlugins = {name, plugins, check}:
-
lib.optionalString check ''
+
lib.optionalString (shouldLink check plugins) ''
mkdir -p ${name}
${lib.concatMapStrings (plugin: ''
ln -s ${plugin}/libexec/android-sdk/${name}/* ${name}
···
by an environment variable for a single invocation of the nix tools.
$ export NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE=1
'' else callPackage ./cmdline-tools.nix {
-
inherit deployAndroidPackage os meta;
+
inherit deployAndroidPackage os arch meta;
package = cmdline-tools-package;
···
${linkPlugin { name = "emulator"; plugin = emulator; check = includeEmulator; }}
${linkPlugins { name = "platforms"; plugins = platforms; }}
${linkPlatformPlugins { name = "sources"; plugins = sources; check = includeSources; }}
-
${linkPlugins { name = "cmake"; plugins = cmake; }}
-
${linkNdkPlugins { name = "ndk-bundle"; rootName = "ndk"; plugins = ndk-bundles; }}
+
${linkPlugins { name = "cmake"; plugins = cmake; check = includeCmake; }}
+
${linkNdkPlugins { name = "ndk-bundle"; rootName = "ndk"; plugins = ndk-bundles; check = includeNDK; }}
${linkNdkPlugin { name = "ndk-bundle"; plugin = ndk-bundle; check = includeNDK; }}
${linkSystemImages { images = system-images; check = includeSystemImages; }}
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleAPIs; }}
-
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleTVAddOns; }}
+
${linkPlatformPlugins { name = "add-ons"; plugins = google-tv-addons; check = useGoogleTVAddOns; }}
# Link extras
${lib.concatMapStrings (identifier:
···
package = addons.extras.${identifier};
path = package.path;
extras = callPackage ./extras.nix {
-
inherit deployAndroidPackage package os meta;
+
inherit deployAndroidPackage package os arch meta;
};
in
''
···
ln -s $i $out/bin
done
-
${lib.optionalString includeEmulator ''
+
${lib.optionalString (shouldLink includeEmulator [emulator]) ''
for i in ${emulator}/bin/*; do
ln -s $i $out/bin
done
+3 -9
pkgs/development/mobile/androidenv/default.nix
···
"34"
"35"
];
-
includeEmulator =
-
with pkgs.stdenv.hostPlatform;
-
system == "x86_64-linux" || system == "x86_64-darwin" || system == "aarch64-darwin";
-
includeSystemImages =
-
with pkgs.stdenv.hostPlatform;
-
system == "x86_64-linux" || system == "x86_64-darwin" || system == "aarch64-darwin";
-
includeNDK =
-
with pkgs.stdenv.hostPlatform;
-
system == "x86_64-linux" || system == "x86_64-darwin" || system == "aarch64-darwin";
+
includeEmulator = "if-supported";
+
includeSystemImages = "if-supported";
+
includeNDK = "if-supported";
};
test-suite = pkgs.callPackage ./test-suite.nix {
+16 -4
pkgs/development/mobile/androidenv/deploy-androidpackages.nix
···
-
{stdenv, lib, unzip, mkLicenses, meta}:
+
{stdenv, lib, unzip, mkLicenses, os, arch, meta}:
{packages, nativeBuildInputs ? [], buildInputs ? [], patchesInstructions ? {}, ...}@args:
let
···
inherit buildInputs;
pname = "android-sdk-${lib.concatMapStringsSep "-" (package: package.name) sortedPackages}";
version = lib.concatMapStringsSep "-" (package: package.revision) sortedPackages;
-
src = map (package: package.archives) packages;
+
src = lib.flatten (map (package: package.archives) packages);
+
inherit os arch;
nativeBuildInputs = [ unzip ] ++ nativeBuildInputs;
preferLocalBuild = true;
unpackPhase = ''
+
runHook preUnpack
+
if [ -z "$src" ]; then
+
echo "$pname did not have any sources available for os=$os, arch=$arch." >&2
+
echo "Are packages available for this architecture?" >&2
+
exit 1
+
fi
buildDir=$PWD
i=0
for srcArchive in $src; do
···
cd "$extractedZip"
unpackFile "$srcArchive"
done
+
runHook postUnpack
'';
-
installPhase = lib.concatStrings (lib.imap0 (i: package: ''
+
installPhase = ''
+
runHook preInstall
+
'' + lib.concatStrings (lib.imap0 (i: package: ''
cd $buildDir/extractedzip-${toString i}
# Most Android Zip packages have a root folder, but some don't. We unpack
···
${mkXmlPackage package}
EOF
fi
-
'') packages);
+
'') packages) + ''
+
runHook postInstall
+
'';
# Some executables that have been patched with patchelf may not work any longer after they have been stripped.
dontStrip = true;
+2 -2
pkgs/development/mobile/androidenv/emulator.nix
···
-
{ deployAndroidPackage, lib, stdenv, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall, meta }:
+
{ deployAndroidPackage, lib, stdenv, package, os, arch, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall, meta }:
deployAndroidPackage {
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") (with pkgs; [
+9 -5
pkgs/development/mobile/androidenv/examples/shell-with-emulator.nix
···
inherit config pkgs licenseAccepted;
};
+
emulatorSupported = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin;
+
sdkArgs = {
includeSystemImages = true;
-
includeEmulator = true;
+
includeEmulator = "if-supported";
# Accepting more licenses declaratively:
extraLicenses = [
···
packages=(
"build-tools" "cmdline-tools" \
-
"emulator" "platform-tools" "platforms;android-35" \
+
"platform-tools" "platforms;android-35" \
"system-images;android-35;google_apis;x86_64"
)
+
${pkgs.lib.optionalString emulatorSupported ''packages+=("emulator")''}
for package in "''${packages[@]}"; do
if [[ ! $installed_packages_section =~ "$package" ]]; then
···
jdk
];
}
-
''
+
(pkgs.lib.optionalString emulatorSupported ''
export ANDROID_USER_HOME=$PWD/.android
mkdir -p $ANDROID_USER_HOME
···
fi
avdmanager delete avd -n testAVD || true
-
touch "$out"
-
'';
+
'' + ''
+
touch $out
+
'');
};
}
+7 -3
pkgs/development/mobile/androidenv/examples/shell.nix
···
inherit config pkgs licenseAccepted;
};
+
# The head unit only works on these platforms
+
includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin;
+
androidComposition = androidEnv.composeAndroidPackages {
includeSources = true;
includeSystemImages = true;
-
includeEmulator = true;
-
includeNDK = true;
+
includeEmulator = "if-supported";
+
includeNDK = "if-supported";
useGoogleAPIs = true;
platformVersions = [ "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" ];
···
includeExtras = [
"extras;google;gcm"
+
] ++ pkgs.lib.optionals includeAuto [
"extras;google;auto"
];
···
"system-images;android-34;google_apis;x86_64" \
"system-images;android-35;google_apis;x86_64" \
"extras;google;gcm"
-
"extras;google;auto"
)
+
${pkgs.lib.optionalString includeAuto ''packages+=("extras;google;auto")''}
for package in "''${packages[@]}"; do
if [[ ! $installed_packages_section =~ "$package" ]]; then
+2 -1
pkgs/development/mobile/androidenv/extras.nix
···
lib,
package,
os,
+
arch,
autoPatchelfHook,
makeWrapper,
pkgs,
···
}:
deployAndroidPackage {
-
inherit package os;
+
inherit package os arch;
nativeBuildInputs = [ makeWrapper ] ++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") (
with pkgs;
+2 -2
pkgs/development/mobile/androidenv/ndk-bundle/default.nix
···
{ stdenv, lib, pkgs, pkgsHostHost, makeWrapper, autoPatchelfHook
-
, deployAndroidPackage, package, os, platform-tools, meta
+
, deployAndroidPackage, package, os, arch, platform-tools, meta
}:
let
···
]) + ":${platform-tools}/platform-tools";
in
deployAndroidPackage rec {
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
autoPatchelfIgnoreMissingDeps = [ "*" ];
+2 -1
pkgs/development/mobile/androidenv/patcher.nix
···
lib,
package,
os,
+
arch,
autoPatchelfHook,
stdenv,
}:
deployAndroidPackage {
-
inherit package os;
+
inherit package os arch;
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
patchInstructions = lib.optionalString (os == "linux") ''
autoPatchelf $packageBaseDir/bin
+2 -2
pkgs/development/mobile/androidenv/platform-tools.nix
···
-
{deployAndroidPackage, lib, package, os, autoPatchelfHook, pkgs, meta}:
+
{deployAndroidPackage, lib, package, os, arch, autoPatchelfHook, pkgs, meta}:
deployAndroidPackage {
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") [ pkgs.glibc (lib.getLib pkgs.stdenv.cc.cc) pkgs.zlib pkgs.ncurses5 ];
+2 -2
pkgs/development/mobile/androidenv/tools.nix
···
-
{deployAndroidPackage, lib, stdenv, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgsi686Linux, postInstall, meta}:
+
{deployAndroidPackage, lib, stdenv, package, os, arch, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall, meta}:
deployAndroidPackage {
name = "androidsdk-tools";
-
inherit package;
+
inherit package os arch;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optional (os == "linux") (