3
0
Fork 0
forked from mirrors/nixpkgs

Merge pull request #208793 from hadilq/androidenv/cmdline-tools-and-patcher

androidenv: Implement cmdline-tools and patcher
This commit is contained in:
Artturi 2023-01-29 18:11:41 +02:00 committed by GitHub
commit c2e37a404c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 234 additions and 169 deletions

View file

@ -13,6 +13,7 @@ with import <nixpkgs> {};
let
androidComposition = androidenv.composeAndroidPackages {
cmdLineToolsVersion = "8.0";
toolsVersion = "26.1.1";
platformToolsVersion = "30.0.5";
buildToolsVersions = [ "30.0.3" ];
@ -42,7 +43,10 @@ exceptions are the tools, platform-tools and build-tools sub packages.
The following parameters are supported:
* `toolsVersion`, specifies the version of the tools package to use
* `cmdLineToolsVersion `, specifies the version of the `cmdline-tools` package to use
* `toolsVersion`, specifies the version of the `tools` package. Notice `tools` is
obsolete, and currently only `26.1.1` is available, so there's not a lot of
options here, however, you can set it as `null` if you don't want it.
* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
* `buildToolsVersions` specifies the versions of the `build-tools` plugins to
use.

View file

@ -4,3 +4,12 @@
2. `./mkrepo.sh`
3. Check the `repo.json` diff for new stable versions of `tools`, `platform-tools`, `build-tools`, `emulator` and/or `ndk`
4. Update the relevant argument defaults in `compose-android-packages.nix`
# How to run tests
You may need to make yourself familiar with [tests](https://nixos.org/manual/nixpkgs/stable/#var-meta-tests), and [Writing larger package tests](https://nixos.org/manual/nixpkgs/stable/#ssec-package-tests-writing) in the Manual, then run tests locally with:
```shell
$ export NIXPKGS_ALLOW_UNFREE=1
$ cd path/to/nixpkgs
$ nix-build -A androidenv.test-suite.tests
```

View file

@ -1,4 +1,4 @@
{deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux}:
{deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall}:
deployAndroidPackage {
inherit package os;
@ -19,6 +19,8 @@ deployAndroidPackage {
wrapProgram $PWD/mainDexClasses \
--prefix PATH : ${pkgs.jdk8}/bin
''}
'';
cd $out/libexec/android-sdk
'' + postInstall;
noAuditTmpdir = true; # The checker script gets confused by the build-tools path that is incorrectly identified as a reference to /build
}

View file

@ -0,0 +1,39 @@
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgsi686Linux, stdenv, cmdLineToolsVersion, postInstall}:
deployAndroidPackage {
name = "androidsdk";
inherit package os;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals stdenv.isLinux [ autoPatchelfHook ];
patchInstructions = ''
${lib.optionalString (os == "linux") ''
# Auto patch all binaries
autoPatchelf .
''}
# Strip double dots from the root path
export ANDROID_SDK_ROOT="$out/libexec/android-sdk"
# Wrap all scripts that require JAVA_HOME
find $ANDROID_SDK_ROOT/cmdline-tools/${cmdLineToolsVersion}/bin -maxdepth 1 -type f -executable | while read program; do
if grep -q "JAVA_HOME" $program; then
wrapProgram $program --prefix PATH : ${pkgs.jdk11}/bin \
--prefix ANDROID_SDK_ROOT : $ANDROID_SDK_ROOT
fi
done
# Wrap sdkmanager script
wrapProgram $ANDROID_SDK_ROOT/cmdline-tools/${cmdLineToolsVersion}/bin/sdkmanager \
--prefix PATH : ${lib.makeBinPath [ pkgs.jdk11 ]} \
--add-flags "--sdk_root=$ANDROID_SDK_ROOT"
# Patch all script shebangs
patchShebangs $ANDROID_SDK_ROOT/cmdline-tools/${cmdLineToolsVersion}/bin
cd $ANDROID_SDK_ROOT
${postInstall}
'';
meta.license = lib.licenses.unfree;
}

View file

@ -2,7 +2,8 @@
, licenseAccepted ? false
}:
{ toolsVersion ? "26.1.1"
{ cmdLineToolsVersion ? "8.0"
, toolsVersion ? "26.1.1"
, platformToolsVersion ? "33.0.3"
, buildToolsVersions ? [ "33.0.1" ]
, includeEmulator ? false
@ -132,16 +133,40 @@ rec {
package = packages.platform-tools.${platformToolsVersion};
};
tools = callPackage ./tools.nix {
inherit deployAndroidPackage os;
package = packages.tools.${toolsVersion};
postInstall = ''
${linkPlugin { name = "platform-tools"; plugin = platform-tools; }}
${linkPlugin { name = "patcher"; plugin = patcher; }}
${linkPlugin { name = "emulator"; plugin = emulator; }}
'';
};
patcher = callPackage ./patcher.nix {
inherit deployAndroidPackage os;
package = packages.patcher."1";
};
build-tools = map (version:
callPackage ./build-tools.nix {
inherit deployAndroidPackage os;
package = packages.build-tools.${version};
postInstall = ''
${linkPlugin { name = "tools"; plugin = tools; check = toolsVersion != null; }}
'';
}
) buildToolsVersions;
emulator = callPackage ./emulator.nix {
inherit deployAndroidPackage os;
package = packages.emulator.${emulatorVersion};
postInstall = ''
${linkSystemImages { images = system-images; check = includeSystemImages; }}
'';
};
platforms = map (version:
@ -238,9 +263,19 @@ rec {
# Function that automatically links a plugin for which only one version exists
linkPlugin = {name, plugin, check ? true}:
lib.optionalString check ''
ln -s ${plugin}/libexec/android-sdk/* ${name}
ln -s ${plugin}/libexec/android-sdk/${name} ${name}
'';
linkSystemImages = { images, check }: lib.optionalString check ''
mkdir -p system-images
${lib.concatMapStrings (system-image: ''
apiVersion=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*))
type=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*/*))
mkdir -p system-images/$apiVersion/$type
ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type/* system-images/$apiVersion/$type
'') images}
'';
# Links all plugins related to a requested platform
linkPlatformPlugins = {name, plugins, check}:
lib.optionalString check ''
@ -260,12 +295,16 @@ rec {
${lib.concatMapStringsSep "\n" (str: " - ${str}") licenseNames}
by setting nixpkgs config option 'android_sdk.accept_license = true;'.
'' else callPackage ./tools.nix {
inherit deployAndroidPackage packages toolsVersion os;
'' else callPackage ./cmdline-tools.nix {
inherit deployAndroidPackage os cmdLineToolsVersion;
package = packages.cmdline-tools.${cmdLineToolsVersion};
postInstall = ''
# Symlink all requested plugins
${linkPlugin { name = "platform-tools"; plugin = platform-tools; }}
${linkPlugin { name = "tools"; plugin = tools; check = toolsVersion != null; }}
${linkPlugin { name = "patcher"; plugin = patcher; }}
${linkPlugins { name = "build-tools"; plugins = build-tools; }}
${linkPlugin { name = "emulator"; plugin = emulator; check = includeEmulator; }}
${linkPlugins { name = "platforms"; plugins = platforms; }}
@ -273,17 +312,7 @@ rec {
${linkPlugins { name = "cmake"; plugins = cmake; }}
${linkNdkPlugins { name = "ndk-bundle"; rootName = "ndk"; plugins = ndk-bundles; }}
${linkNdkPlugin { name = "ndk-bundle"; plugin = ndk-bundle; check = includeNDK; }}
${lib.optionalString includeSystemImages ''
mkdir -p system-images
${lib.concatMapStrings (system-image: ''
apiVersion=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*))
type=$(basename $(echo ${system-image}/libexec/android-sdk/system-images/*/*))
mkdir -p system-images/$apiVersion/$type
ln -s ${system-image}/libexec/android-sdk/system-images/$apiVersion/$type/* system-images/$apiVersion/$type
'') system-images}
''}
${linkSystemImages { images = system-images; check = includeSystemImages; }}
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleAPIs; }}
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleTVAddOns; }}
@ -304,27 +333,19 @@ rec {
# Expose common executables in bin/
mkdir -p $out/bin
find $PWD/tools -not -path '*/\.*' -type f -executable -mindepth 1 -maxdepth 1 | while read i
do
for i in ${platform-tools}/bin/*; do
ln -s $i $out/bin
done
find $PWD/tools/bin -not -path '*/\.*' -type f -executable -mindepth 1 -maxdepth 1 | while read i
do
for i in ${emulator}/bin/*; do
ln -s $i $out/bin
done
for i in ${platform-tools}/bin/*
do
find $ANDROID_SDK_ROOT/cmdline-tools/${cmdLineToolsVersion}/bin -type f -executable | while read i; do
ln -s $i $out/bin
done
# the emulator auto-linked from platform-tools does not find its local qemu, while this one does
${lib.optionalString includeEmulator ''
rm $out/bin/emulator
ln -s $out/libexec/android-sdk/emulator/emulator $out/bin
''}
# Write licenses
mkdir -p licenses
${lib.concatMapStrings (licenseName:

View file

@ -19,4 +19,6 @@ rec {
platformVersions = [ "28" ];
abiVersions = [ "x86" "x86_64"];
};
test-suite = pkgs.callPackage ./test-suite.nix {};
}

View file

@ -1,4 +1,4 @@
{ deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux }:
{ deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgsi686Linux, postInstall }:
deployAndroidPackage {
inherit package os;
@ -47,6 +47,15 @@ deployAndroidPackage {
]} \
--set QT_XKB_CONFIG_ROOT ${pkgs.xkeyboard_config}/share/X11/xkb \
--set QTCOMPOSE ${pkgs.xorg.libX11.out}/share/X11/locale
mkdir -p $out/bin
cd $out/bin
find $out/libexec/android-sdk/emulator -type f -executable -mindepth 1 -maxdepth 1 | while read i; do
ln -s $i
done
cd $out/libexec/android-sdk
${postInstall}
'';
dontMoveLib64 = true;
}

View file

@ -25,7 +25,7 @@ let
# versions may be used in multiple places in this Nix expression.
android = {
versions = {
tools = "26.1.1";
cmdLineToolsVersion = "8.0";
platformTools = "33.0.3";
buildTools = "30.0.3";
ndk = [
@ -60,7 +60,7 @@ let
};
androidComposition = androidEnv.composeAndroidPackages {
toolsVersion = android.versions.tools;
cmdLineToolsVersion = android.versions.cmdLineToolsVersion;
platformToolsVersion = android.versions.platformTools;
buildToolsVersions = [android.versions.buildTools];
platformVersions = android.platforms;
@ -138,11 +138,55 @@ pkgs.mkShell rec {
# Write out local.properties for Android Studio.
cat <<EOF > local.properties
# This file was automatically generated by nix-shell.
sdk.dir=$ANDROID_SDK_ROOT
ndk.dir=$ANDROID_NDK_ROOT
cmake.dir=$cmake_root
EOF
# This file was automatically generated by nix-shell.
sdk.dir=$ANDROID_SDK_ROOT
ndk.dir=$ANDROID_NDK_ROOT
cmake.dir=$cmake_root
EOF
'';
passthru.tests = {
sdkmanager-licenses-test = pkgs.runCommand "sdkmanager-licenses-test" {
buildInputs = [ androidSdk jdk ];
} ''
if [[ ! "$(sdkmanager --licenses)" =~ "All SDK package licenses accepted." ]]; then
echo "At least one of SDK package licenses are not accepted."
exit 1
fi
touch $out
'';
sdkmanager-packages-test = pkgs.runCommand "sdkmanager-packages-test" {
buildInputs = [ androidSdk jdk ];
} ''
output="$(sdkmanager --list)"
installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}')
packages=(
"build-tools;30.0.3" "ndk-bundle" "platform-tools" \
"platforms;android-23" "platforms;android-24" "platforms;android-25" "platforms;android-26" \
"platforms;android-27" "platforms;android-28" "platforms;android-29" "platforms;android-30" \
"platforms;android-31" "platforms;android-32" "platforms;android-33" \
"sources;android-23" "sources;android-24" "sources;android-25" "sources;android-26" \
"sources;android-27" "sources;android-28" "sources;android-29" "sources;android-30" \
"sources;android-31" "sources;android-32" "sources;android-33" \
"system-images;android-28;google_apis_playstore;arm64-v8a" \
"system-images;android-29;google_apis_playstore;arm64-v8a" \
"system-images;android-30;google_apis_playstore;arm64-v8a" \
"system-images;android-31;google_apis_playstore;arm64-v8a" \
"system-images;android-32;google_apis_playstore;arm64-v8a" \
"system-images;android-33;google_apis_playstore;arm64-v8a"
)
for package in "''${packages[@]}"; do
if [[ ! $installed_packages_section =~ "$package" ]]; then
echo "$package package was not installed."
exit 1
fi
done
touch "$out"
'';
};
}

View file

@ -0,0 +1,9 @@
{deployAndroidPackage, lib, package, os, autoPatchelfHook, pkgs, stdenv}:
deployAndroidPackage {
inherit package os;
nativeBuildInputs = lib.optionals stdenv.isLinux [ autoPatchelfHook ];
patchInstructions = lib.optionalString (os == "linux") ''
autoPatchelf $packageBaseDir/bin
'';
}

View file

@ -4,6 +4,7 @@ deployAndroidPackage {
inherit package os;
nativeBuildInputs = lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optionals (os == "linux") [ pkgs.glibc pkgs.zlib pkgs.ncurses5 ];
patchInstructions = lib.optionalString (os == "linux") ''
addAutoPatchelfSearchPath $packageBaseDir/lib64
autoPatchelf --no-recurse $packageBaseDir/lib64

View file

@ -0,0 +1,16 @@
{ stdenv, callPackage }:
let
examples-shell = callPackage ./examples/shell.nix {};
in
stdenv.mkDerivation {
name = "androidenv-test-suite";
src = ./.;
dontConfigure = true;
dontBuild = true;
passthru.tests = { } // examples-shell.passthru.tests;
meta.timeout = 60;
}

View file

@ -1,26 +1,42 @@
{deployAndroidPackage, requireFile, lib, packages, toolsVersion, os, callPackage, postInstall ? ""}:
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgsi686Linux, postInstall}:
if toolsVersion == "26.0.1" then callPackage ./tools/26.nix {
inherit deployAndroidPackage lib os postInstall;
package = {
name = "tools";
path = "tools";
revision = "26.0.1";
archives = {
linux = requireFile {
url = "https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip";
sha256 = "185yq7qwxflw24ccm5d6zziwlc9pxmsm3f54pm9p7xm0ik724kj4";
};
macosx = requireFile {
url = "https://dl.google.com/android/repository/sdk-tools-darwin-3859397.zip";
sha256 = "1ycx9gzdaqaw6n19yvxjawywacavn1jc6sadlz5qikhgfr57b0aa";
};
};
};
} else if toolsVersion == "26.1.1" then callPackage ./tools/26.nix {
inherit deployAndroidPackage lib os postInstall;
package = packages.tools.${toolsVersion};
} else callPackage ./tools/25.nix {
inherit deployAndroidPackage lib os postInstall;
package = packages.tools.${toolsVersion};
deployAndroidPackage {
name = "androidsdk";
inherit os package;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optional (os == "linux") (
(with pkgs; [ glibc freetype fontconfig fontconfig.lib])
++ (with pkgs.xorg; [ libX11 libXrender libXext ])
++ (with pkgsi686Linux; [ glibc xorg.libX11 xorg.libXrender xorg.libXext fontconfig.lib freetype zlib ])
);
patchInstructions = ''
${lib.optionalString (os == "linux") ''
# Auto patch all binaries
autoPatchelf .
''}
# Wrap all scripts that require JAVA_HOME
for i in bin; do
find $i -maxdepth 1 -type f -executable | while read program; do
if grep -q "JAVA_HOME" $program; then
wrapProgram $PWD/$program --prefix PATH : ${pkgs.jdk8}/bin
fi
done
done
# Wrap monitor script
wrapProgram $PWD/monitor \
--prefix PATH : ${pkgs.jdk8}/bin \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath (with pkgs; [ xorg.libX11 xorg.libXtst ])}
# Patch all script shebangs
patchShebangs .
cd $out/libexec/android-sdk
${postInstall}
'';
meta.license = lib.licenses.unfree;
}

View file

@ -1,62 +0,0 @@
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgsi686Linux, postInstall ? ""}:
deployAndroidPackage {
name = "androidsdk";
nativeBuildInputs = [ autoPatchelfHook makeWrapper ];
buildInputs = lib.optionals (os == "linux") [ pkgs.glibc pkgs.xorg.libX11 pkgs.xorg.libXext pkgs.xorg.libXdamage pkgs.xorg.libxcb pkgs.xorg.libXfixes pkgs.xorg.libXrender pkgs.fontconfig.lib pkgs.freetype pkgs.libGL pkgs.zlib pkgs.ncurses5 pkgs.libpulseaudio pkgsi686Linux.glibc pkgsi686Linux.xorg.libX11 pkgsi686Linux.xorg.libXrender pkgsi686Linux.fontconfig pkgsi686Linux.freetype pkgsi686Linux.zlib ];
inherit package os;
patchInstructions = ''
${lib.optionalString (os == "linux") ''
# Auto patch all binaries
addAutoPatchelfSearchPath $PWD/lib64
addAutoPatchelfSearchPath $PWD/lib64/libstdc++
addAutoPatchelfSearchPath $PWD/lib64/qt/lib
addAutoPatchelfSearchPath $PWD/lib
addAutoPatchelfSearchPath $PWD/lib/libstdc++
autoPatchelf .
''}
# Wrap all scripts that require JAVA_HOME
for i in bin
do
find $i -maxdepth 1 -type f -executable | while read program
do
if grep -q "JAVA_HOME" $program
then
wrapProgram $PWD/$program --prefix PATH : ${pkgs.jdk8}/bin
fi
done
done
# Wrap programs that require java
for i in draw9patch jobb lint screenshot2
do
wrapProgram $PWD/$i \
--prefix PATH : ${pkgs.jdk8}/bin
done
# Wrap programs that require java and SWT
for i in android ddms hierarchyviewer monitor monkeyrunner traceview uiautomatorviewer
do
wrapProgram $PWD/$i \
--prefix PATH : ${pkgs.jdk8}/bin \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ pkgs.xorg.libX11 pkgs.xorg.libXtst ]}
done
${lib.optionalString (os == "linux") ''
wrapProgram $PWD/emulator \
--prefix PATH : ${pkgs.file}/bin:${pkgs.glxinfo}/bin:${pkgs.pciutils}/bin \
--set QT_XKB_CONFIG_ROOT ${pkgs.xkeyboard_config}/share/X11/xkb \
--set QTCOMPOSE ${pkgs.xorg.libX11.out}/share/X11/locale
''}
# Patch all script shebangs
patchShebangs .
cd ..
${postInstall}
'';
meta.license = lib.licenses.unfree;
}

View file

@ -1,45 +0,0 @@
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgsi686Linux, postInstall ? ""}:
deployAndroidPackage {
name = "androidsdk";
inherit os package;
nativeBuildInputs = [ makeWrapper ]
++ lib.optionals (os == "linux") [ autoPatchelfHook ];
buildInputs = lib.optional (os == "linux") (
(with pkgs; [ glibc freetype fontconfig fontconfig.lib])
++ (with pkgs.xorg; [ libX11 libXrender libXext ])
++ (with pkgsi686Linux; [ glibc xorg.libX11 xorg.libXrender xorg.libXext fontconfig.lib freetype zlib ])
);
patchInstructions = ''
${lib.optionalString (os == "linux") ''
# Auto patch all binaries
autoPatchelf .
''}
# Wrap all scripts that require JAVA_HOME
for i in bin
do
find $i -maxdepth 1 -type f -executable | while read program
do
if grep -q "JAVA_HOME" $program
then
wrapProgram $PWD/$program --prefix PATH : ${pkgs.jdk8}/bin
fi
done
done
# Wrap monitor script
wrapProgram $PWD/monitor \
--prefix PATH : ${pkgs.jdk8}/bin \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ pkgs.xorg.libX11 pkgs.xorg.libXtst ]}
# Patch all script shebangs
patchShebangs .
cd ..
${postInstall}
'';
meta.license = lib.licenses.unfree;
}