uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead
https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948 this can do it nicely. Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
commit
56de2bcd43
30691 changed files with 3076956 additions and 0 deletions
2
pkgs/development/mobile/androidenv/.gitignore
vendored
Normal file
2
pkgs/development/mobile/androidenv/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/xml
|
||||
local.properties
|
||||
6
pkgs/development/mobile/androidenv/README.md
Normal file
6
pkgs/development/mobile/androidenv/README.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# How to update
|
||||
|
||||
1. `./fetchrepo.sh`
|
||||
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`
|
||||
48
pkgs/development/mobile/androidenv/build-app.nix
Normal file
48
pkgs/development/mobile/androidenv/build-app.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{ composeAndroidPackages, stdenv, lib, ant, jdk, gnumake, gawk }:
|
||||
|
||||
{ name
|
||||
, release ? false, keyStore ? null, keyAlias ? null, keyStorePassword ? null, keyAliasPassword ? null
|
||||
, antFlags ? ""
|
||||
, ...
|
||||
}@args:
|
||||
|
||||
assert release -> keyStore != null && keyAlias != null && keyStorePassword != null && keyAliasPassword != null;
|
||||
|
||||
let
|
||||
androidSdkFormalArgs = builtins.functionArgs composeAndroidPackages;
|
||||
androidArgs = builtins.intersectAttrs androidSdkFormalArgs args;
|
||||
androidsdk = (composeAndroidPackages androidArgs).androidsdk;
|
||||
|
||||
extraArgs = removeAttrs args ([ "name" ] ++ builtins.attrNames androidSdkFormalArgs);
|
||||
in
|
||||
stdenv.mkDerivation ({
|
||||
name = lib.replaceChars [" "] [""] name; # Android APKs may contain white spaces in their names, but Nix store paths cannot
|
||||
ANDROID_HOME = "${androidsdk}/libexec/android-sdk";
|
||||
buildInputs = [ jdk ant ];
|
||||
buildPhase = ''
|
||||
${lib.optionalString release ''
|
||||
# Provide key singing attributes
|
||||
( echo "key.store=${keyStore}"
|
||||
echo "key.alias=${keyAlias}"
|
||||
echo "key.store.password=${keyStorePassword}"
|
||||
echo "key.alias.password=${keyAliasPassword}"
|
||||
) >> ant.properties
|
||||
''}
|
||||
|
||||
export ANDROID_SDK_HOME=`pwd` # Key files cannot be stored in the user's home directory. This overrides it.
|
||||
|
||||
${lib.optionalString (args ? includeNDK && args.includeNDK) ''
|
||||
export GNUMAKE=${gnumake}/bin/make
|
||||
export NDK_HOST_AWK=${gawk}/bin/gawk
|
||||
${androidsdk}/libexec/android-sdk/ndk-bundle/ndk-build
|
||||
''}
|
||||
ant ${antFlags} ${if release then "release" else "debug"}
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
mv bin/*-${if release then "release" else "debug"}.apk $out
|
||||
|
||||
mkdir -p $out/nix-support
|
||||
echo "file binary-dist \"$(echo $out/*.apk)\"" > $out/nix-support/hydra-build-products
|
||||
'';
|
||||
} // extraArgs)
|
||||
21
pkgs/development/mobile/androidenv/build-tools.nix
Normal file
21
pkgs/development/mobile/androidenv/build-tools.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgs_i686}:
|
||||
|
||||
deployAndroidPackage {
|
||||
inherit package os;
|
||||
buildInputs = [ makeWrapper ] ++
|
||||
lib.optionals (os == "linux") [ autoPatchelfHook pkgs.glibc pkgs.zlib pkgs.ncurses5 pkgs_i686.glibc pkgs_i686.zlib pkgs_i686.ncurses5 pkgs.libcxx ];
|
||||
patchInstructions = ''
|
||||
${lib.optionalString (os == "linux") ''
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib
|
||||
if [[ -d $packageBaseDir/lib64 ]]; then
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib64
|
||||
autoPatchelf --no-recurse $packageBaseDir/lib64
|
||||
fi
|
||||
autoPatchelf --no-recurse $packageBaseDir
|
||||
''}
|
||||
|
||||
wrapProgram $PWD/mainDexClasses \
|
||||
--prefix PATH : ${pkgs.jdk8}/bin
|
||||
'';
|
||||
noAuditTmpdir = true; # The checker script gets confused by the build-tools path that is incorrectly identified as a reference to /build
|
||||
}
|
||||
10
pkgs/development/mobile/androidenv/cmake.nix
Normal file
10
pkgs/development/mobile/androidenv/cmake.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{deployAndroidPackage, lib, package, os, autoPatchelfHook, pkgs, stdenv}:
|
||||
|
||||
deployAndroidPackage {
|
||||
inherit package os;
|
||||
nativeBuildInputs = lib.optionals stdenv.isLinux [ autoPatchelfHook ];
|
||||
buildInputs = lib.optional (os == "linux") [ pkgs.stdenv.cc.libc pkgs.stdenv.cc.cc pkgs.ncurses5 ];
|
||||
patchInstructions = lib.optionalString (os == "linux") ''
|
||||
autoPatchelf $packageBaseDir/bin
|
||||
'';
|
||||
}
|
||||
321
pkgs/development/mobile/androidenv/compose-android-packages.nix
Normal file
321
pkgs/development/mobile/androidenv/compose-android-packages.nix
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
{ requireFile, autoPatchelfHook, pkgs, pkgsHostHost, pkgs_i686
|
||||
, licenseAccepted ? false
|
||||
}:
|
||||
|
||||
{ toolsVersion ? "26.1.1"
|
||||
, platformToolsVersion ? "33.0.1"
|
||||
, buildToolsVersions ? [ "32.0.0" ]
|
||||
, includeEmulator ? false
|
||||
, emulatorVersion ? "31.3.7"
|
||||
, platformVersions ? []
|
||||
, includeSources ? false
|
||||
, includeSystemImages ? false
|
||||
, systemImageTypes ? [ "google_apis_playstore" ]
|
||||
, abiVersions ? [ "armeabi-v7a" ]
|
||||
, cmakeVersions ? [ ]
|
||||
, includeNDK ? false
|
||||
, ndkVersion ? "24.0.8215888"
|
||||
, ndkVersions ? [ndkVersion]
|
||||
, useGoogleAPIs ? false
|
||||
, useGoogleTVAddOns ? false
|
||||
, includeExtras ? []
|
||||
, repoJson ? ./repo.json
|
||||
, repoXmls ? null
|
||||
, extraLicenses ? []
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) stdenv lib fetchurl;
|
||||
inherit (pkgs.buildPackages) makeWrapper unzip;
|
||||
|
||||
# Determine the Android os identifier from Nix's system identifier
|
||||
os = if stdenv.system == "x86_64-linux" then "linux"
|
||||
else if stdenv.system == "x86_64-darwin" then "macosx"
|
||||
else throw "No Android SDK tarballs are available for system architecture: ${stdenv.system}";
|
||||
|
||||
# Uses mkrepo.rb to create a repo spec.
|
||||
mkRepoJson = { packages ? [], images ? [], addons ? [] }: let
|
||||
mkRepoRuby = (pkgs.ruby.withPackages (pkgs: with pkgs; [ slop nokogiri ]));
|
||||
mkRepoRubyArguments = lib.lists.flatten [
|
||||
(builtins.map (package: ["--packages" "${package}"]) packages)
|
||||
(builtins.map (image: ["--images" "${image}"]) images)
|
||||
(builtins.map (addon: ["--addons" "${addon}"]) addons)
|
||||
];
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "androidenv-repo-json";
|
||||
buildInputs = [ mkRepoRuby ];
|
||||
preferLocalBuild = true;
|
||||
unpackPhase = "true";
|
||||
buildPhase = ''
|
||||
ruby ${./mkrepo.rb} ${lib.escapeShellArgs mkRepoRubyArguments} > repo.json
|
||||
'';
|
||||
installPhase = ''
|
||||
mv repo.json $out
|
||||
'';
|
||||
};
|
||||
|
||||
# Reads the repo JSON. If repoXmls is provided, will build a repo JSON into the Nix store.
|
||||
repo = if repoXmls != null then
|
||||
let
|
||||
repoXmlSpec = {
|
||||
packages = repoXmls.packages or [];
|
||||
images = repoXmls.images or [];
|
||||
addons = repoXmls.addons or [];
|
||||
};
|
||||
in
|
||||
lib.importJSON "${mkRepoJson repoXmlSpec}"
|
||||
else
|
||||
lib.importJSON repoJson;
|
||||
|
||||
# Converts all 'archives' keys in a repo spec to fetchurl calls.
|
||||
fetchArchives = attrSet:
|
||||
lib.attrsets.mapAttrsRecursive
|
||||
(path: value:
|
||||
if (builtins.elemAt path ((builtins.length path) - 1)) == "archives" then
|
||||
(builtins.listToAttrs
|
||||
(builtins.map
|
||||
(archive: lib.attrsets.nameValuePair archive.os (fetchurl { inherit (archive) url sha1; })) value))
|
||||
else value
|
||||
)
|
||||
attrSet;
|
||||
|
||||
# Converts the repo attrset into fetch calls
|
||||
packages = fetchArchives repo.packages;
|
||||
system-images-packages = fetchArchives repo.images;
|
||||
addons = {
|
||||
addons = fetchArchives repo.addons;
|
||||
extras = fetchArchives repo.extras;
|
||||
};
|
||||
|
||||
# Converts a license name to a list of license texts.
|
||||
mkLicenses = licenseName: repo.licenses.${licenseName};
|
||||
|
||||
# Converts a list of license names to a flattened list of license texts.
|
||||
# Just used for displaying licenses.
|
||||
mkLicenseTexts = licenseNames:
|
||||
lib.lists.flatten
|
||||
(builtins.map
|
||||
(licenseName:
|
||||
builtins.map
|
||||
(licenseText: "--- ${licenseName} ---\n${licenseText}")
|
||||
(mkLicenses licenseName))
|
||||
licenseNames);
|
||||
|
||||
# Converts a license name to a list of license hashes.
|
||||
mkLicenseHashes = licenseName:
|
||||
builtins.map
|
||||
(licenseText: builtins.hashString "sha1" licenseText)
|
||||
(mkLicenses licenseName);
|
||||
|
||||
# The list of all license names we're accepting. Put android-sdk-license there
|
||||
# by default.
|
||||
licenseNames = lib.lists.unique ([
|
||||
"android-sdk-license"
|
||||
] ++ extraLicenses);
|
||||
in
|
||||
rec {
|
||||
deployAndroidPackage = import ./deploy-androidpackage.nix {
|
||||
inherit stdenv unzip;
|
||||
};
|
||||
|
||||
platform-tools = import ./platform-tools.nix {
|
||||
inherit deployAndroidPackage autoPatchelfHook pkgs lib;
|
||||
os = if stdenv.system == "aarch64-darwin" then "macosx" else os; # "macosx" is a universal binary here
|
||||
package = packages.platform-tools.${platformToolsVersion};
|
||||
};
|
||||
|
||||
build-tools = map (version:
|
||||
import ./build-tools.nix {
|
||||
inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs pkgs_i686 lib;
|
||||
package = packages.build-tools.${version};
|
||||
}
|
||||
) buildToolsVersions;
|
||||
|
||||
emulator = import ./emulator.nix {
|
||||
inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs pkgs_i686 lib;
|
||||
package = packages.emulator.${emulatorVersion};
|
||||
};
|
||||
|
||||
platforms = map (version:
|
||||
deployAndroidPackage {
|
||||
inherit os;
|
||||
package = packages.platforms.${version};
|
||||
}
|
||||
) platformVersions;
|
||||
|
||||
sources = map (version:
|
||||
deployAndroidPackage {
|
||||
inherit os;
|
||||
package = packages.sources.${version};
|
||||
}
|
||||
) platformVersions;
|
||||
|
||||
system-images = lib.flatten (map (apiVersion:
|
||||
map (type:
|
||||
map (abiVersion:
|
||||
if lib.hasAttrByPath [apiVersion type abiVersion] system-images-packages then
|
||||
deployAndroidPackage {
|
||||
inherit os;
|
||||
package = system-images-packages.${apiVersion}.${type}.${abiVersion};
|
||||
# Patch 'google_apis' system images so they're recognized by the sdk.
|
||||
# Without this, `android list targets` shows 'Tag/ABIs : no ABIs' instead
|
||||
# of 'Tag/ABIs : google_apis*/*' and the emulator fails with an ABI-related error.
|
||||
patchInstructions = lib.optionalString (lib.hasPrefix "google_apis" type) ''
|
||||
sed -i '/^Addon.Vendor/d' source.properties
|
||||
'';
|
||||
}
|
||||
else []
|
||||
) abiVersions
|
||||
) systemImageTypes
|
||||
) platformVersions);
|
||||
|
||||
cmake = map (version:
|
||||
import ./cmake.nix {
|
||||
inherit deployAndroidPackage os autoPatchelfHook pkgs lib stdenv;
|
||||
package = packages.cmake.${version};
|
||||
}
|
||||
) cmakeVersions;
|
||||
|
||||
# Creates a NDK bundle.
|
||||
makeNdkBundle = ndkVersion:
|
||||
import ./ndk-bundle {
|
||||
inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs pkgsHostHost lib platform-tools stdenv;
|
||||
package = packages.ndk-bundle.${ndkVersion};
|
||||
};
|
||||
|
||||
# All NDK bundles.
|
||||
ndk-bundles = if includeNDK then map makeNdkBundle ndkVersions else [];
|
||||
|
||||
# The "default" NDK bundle.
|
||||
ndk-bundle = if includeNDK then lib.findFirst (x: x != null) null ndk-bundles else null;
|
||||
|
||||
google-apis = map (version:
|
||||
deployAndroidPackage {
|
||||
inherit os;
|
||||
package = addons.addons.${version}.google_apis;
|
||||
}
|
||||
) (builtins.filter (platformVersion: platformVersion < "26") platformVersions); # API level 26 and higher include Google APIs by default
|
||||
|
||||
google-tv-addons = map (version:
|
||||
deployAndroidPackage {
|
||||
inherit os;
|
||||
package = addons.addons.${version}.google_tv_addon;
|
||||
}
|
||||
) platformVersions;
|
||||
|
||||
# Function that automatically links all plugins for which multiple versions can coexist
|
||||
linkPlugins = {name, plugins}:
|
||||
lib.optionalString (plugins != []) ''
|
||||
mkdir -p ${name}
|
||||
${lib.concatMapStrings (plugin: ''
|
||||
ln -s ${plugin}/libexec/android-sdk/${name}/* ${name}
|
||||
'') plugins}
|
||||
'';
|
||||
|
||||
# Function that automatically links all NDK plugins.
|
||||
linkNdkPlugins = {name, plugins, rootName ? name}:
|
||||
lib.optionalString (plugins != []) ''
|
||||
mkdir -p ${rootName}
|
||||
${lib.concatMapStrings (plugin: ''
|
||||
ln -s ${plugin}/libexec/android-sdk/${name} ${rootName}/${plugin.version}
|
||||
'') plugins}
|
||||
'';
|
||||
|
||||
# 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}
|
||||
'';
|
||||
|
||||
# Links all plugins related to a requested platform
|
||||
linkPlatformPlugins = {name, plugins, check}:
|
||||
lib.optionalString check ''
|
||||
mkdir -p ${name}
|
||||
${lib.concatMapStrings (plugin: ''
|
||||
ln -s ${plugin}/libexec/android-sdk/${name}/* ${name}
|
||||
'') plugins}
|
||||
''; # */
|
||||
|
||||
# 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
|
||||
# requested and throws.
|
||||
androidsdk = if !licenseAccepted then throw ''
|
||||
${builtins.concatStringsSep "\n\n" (mkLicenseTexts licenseNames)}
|
||||
|
||||
You must accept the following licenses:
|
||||
${lib.concatMapStringsSep "\n" (str: " - ${str}") licenseNames}
|
||||
|
||||
by setting nixpkgs config option 'android_sdk.accept_license = true;'.
|
||||
'' else import ./tools.nix {
|
||||
inherit deployAndroidPackage requireFile packages toolsVersion autoPatchelfHook makeWrapper os pkgs pkgs_i686 lib;
|
||||
|
||||
postInstall = ''
|
||||
# Symlink all requested plugins
|
||||
${linkPlugin { name = "platform-tools"; plugin = platform-tools; }}
|
||||
${linkPlugins { name = "build-tools"; plugins = build-tools; }}
|
||||
${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; }}
|
||||
${linkPlugin { 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}
|
||||
''}
|
||||
|
||||
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleAPIs; }}
|
||||
${linkPlatformPlugins { name = "add-ons"; plugins = google-apis; check = useGoogleTVAddOns; }}
|
||||
|
||||
# Link extras
|
||||
${lib.concatMapStrings (identifier:
|
||||
let
|
||||
path = addons.extras.${identifier}.path;
|
||||
addon = deployAndroidPackage {
|
||||
inherit os;
|
||||
package = addons.extras.${identifier};
|
||||
};
|
||||
in
|
||||
''
|
||||
targetDir=$(dirname ${path})
|
||||
mkdir -p $targetDir
|
||||
ln -s ${addon}/libexec/android-sdk/${path} $targetDir
|
||||
'') includeExtras}
|
||||
|
||||
# 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
|
||||
ln -s $i $out/bin
|
||||
done
|
||||
|
||||
find $PWD/tools/bin -not -path '*/\.*' -type f -executable -mindepth 1 -maxdepth 1 | while read i
|
||||
do
|
||||
ln -s $i $out/bin
|
||||
done
|
||||
|
||||
for i in ${platform-tools}/bin/*
|
||||
do
|
||||
ln -s $i $out/bin
|
||||
done
|
||||
|
||||
# Write licenses
|
||||
mkdir -p licenses
|
||||
${lib.concatMapStrings (licenseName:
|
||||
let
|
||||
licenseHashes = builtins.concatStringsSep "\n" (mkLicenseHashes licenseName);
|
||||
licenseHashFile = pkgs.writeText "androidenv-${licenseName}" licenseHashes;
|
||||
in
|
||||
''
|
||||
ln -s ${licenseHashFile} licenses/${licenseName}
|
||||
'') licenseNames}
|
||||
'';
|
||||
};
|
||||
}
|
||||
26
pkgs/development/mobile/androidenv/default.nix
Normal file
26
pkgs/development/mobile/androidenv/default.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs ? import <nixpkgs> {}, pkgsHostHost ? pkgs.pkgsHostHost
|
||||
, pkgs_i686 ? import <nixpkgs> { system = "i686-linux"; }
|
||||
, licenseAccepted ? config.android_sdk.accept_license or false
|
||||
}:
|
||||
|
||||
rec {
|
||||
composeAndroidPackages = import ./compose-android-packages.nix {
|
||||
inherit (pkgs) requireFile autoPatchelfHook;
|
||||
inherit pkgs pkgsHostHost pkgs_i686 licenseAccepted;
|
||||
};
|
||||
|
||||
buildApp = import ./build-app.nix {
|
||||
inherit (pkgs) stdenv lib jdk ant gnumake gawk;
|
||||
inherit composeAndroidPackages;
|
||||
};
|
||||
|
||||
emulateApp = import ./emulate-app.nix {
|
||||
inherit (pkgs) stdenv lib runtimeShell;
|
||||
inherit composeAndroidPackages;
|
||||
};
|
||||
|
||||
androidPkgs_9_0 = composeAndroidPackages {
|
||||
platformVersions = [ "28" ];
|
||||
abiVersions = [ "x86" "x86_64"];
|
||||
};
|
||||
}
|
||||
46
pkgs/development/mobile/androidenv/deploy-androidpackage.nix
Normal file
46
pkgs/development/mobile/androidenv/deploy-androidpackage.nix
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{stdenv, unzip}:
|
||||
{package, os ? null, buildInputs ? [], patchInstructions ? "", meta ? {}, ...}@args:
|
||||
|
||||
let
|
||||
extraParams = removeAttrs args [ "package" "os" "buildInputs" "patchInstructions" ];
|
||||
in
|
||||
stdenv.mkDerivation ({
|
||||
pname = package.name;
|
||||
version = package.revision;
|
||||
src = if os != null && builtins.hasAttr os package.archives then package.archives.${os} else package.archives.all;
|
||||
buildInputs = [ unzip ] ++ buildInputs;
|
||||
preferLocalBuild = true;
|
||||
|
||||
# Most Android Zip packages have a root folder, but some don't. We unpack
|
||||
# the zip file in a folder and we try to discover whether it has a single root
|
||||
# folder. If this is the case, we adjust the current working folder.
|
||||
unpackPhase = ''
|
||||
mkdir extractedzip
|
||||
cd extractedzip
|
||||
unpackFile "$src"
|
||||
if [ "$(find . -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ]
|
||||
then
|
||||
cd "$(find . -mindepth 1 -maxdepth 1 -type d)"
|
||||
fi
|
||||
sourceRoot="$PWD"
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
packageBaseDir=$out/libexec/android-sdk/${package.path}
|
||||
mkdir -p $packageBaseDir
|
||||
cd $packageBaseDir
|
||||
cp -a $sourceRoot/* .
|
||||
${patchInstructions}
|
||||
'';
|
||||
|
||||
# We never attempt to strip. This is not required since we're doing binary
|
||||
# deployments. Moreover, some executables that have been patched with patchelf
|
||||
# may not work any longer after they have been stripped.
|
||||
dontStrip = true;
|
||||
dontPatchELF = true;
|
||||
dontAutoPatchelf = true;
|
||||
|
||||
meta = {
|
||||
description = package.displayName;
|
||||
} // meta;
|
||||
} // extraParams)
|
||||
137
pkgs/development/mobile/androidenv/emulate-app.nix
Normal file
137
pkgs/development/mobile/androidenv/emulate-app.nix
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{ composeAndroidPackages, stdenv, lib, runtimeShell }:
|
||||
{ name, app ? null
|
||||
, platformVersion ? "16", abiVersion ? "armeabi-v7a", systemImageType ? "default"
|
||||
, enableGPU ? false, extraAVDFiles ? []
|
||||
, package ? null, activity ? null
|
||||
, avdHomeDir ? null, sdkExtraArgs ? {}
|
||||
}:
|
||||
|
||||
let
|
||||
sdkArgs = {
|
||||
toolsVersion = "26.1.1";
|
||||
platformVersions = [ platformVersion ];
|
||||
includeEmulator = true;
|
||||
includeSystemImages = true;
|
||||
systemImageTypes = [ systemImageType ];
|
||||
abiVersions = [ abiVersion ];
|
||||
} // sdkExtraArgs;
|
||||
|
||||
sdk = (composeAndroidPackages sdkArgs).androidsdk;
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
buildCommand = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
cat > $out/bin/run-test-emulator << "EOF"
|
||||
#!${runtimeShell} -e
|
||||
|
||||
# We need a TMPDIR
|
||||
if [ "$TMPDIR" = "" ]
|
||||
then
|
||||
export TMPDIR=/tmp
|
||||
fi
|
||||
|
||||
${if avdHomeDir == null then ''
|
||||
# Store the virtual devices somewhere else, instead of polluting a user's HOME directory
|
||||
export ANDROID_SDK_HOME=$(mktemp -d $TMPDIR/nix-android-vm-XXXX)
|
||||
'' else ''
|
||||
mkdir -p "${avdHomeDir}"
|
||||
export ANDROID_SDK_HOME="${avdHomeDir}"
|
||||
''}
|
||||
|
||||
# We need to specify the location of the Android SDK root folder
|
||||
export ANDROID_SDK_ROOT=${sdk}/libexec/android-sdk
|
||||
|
||||
# We have to look for a free TCP port
|
||||
|
||||
echo "Looking for a free TCP port in range 5554-5584" >&2
|
||||
|
||||
for i in $(seq 5554 2 5584)
|
||||
do
|
||||
if [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb devices | grep emulator-$i)" ]
|
||||
then
|
||||
port=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$port" ]
|
||||
then
|
||||
echo "Unfortunately, the emulator port space is exhausted!" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "We have a free TCP port: $port" >&2
|
||||
fi
|
||||
|
||||
export ANDROID_SERIAL="emulator-$port"
|
||||
|
||||
# Create a virtual android device for testing if it does not exist
|
||||
${sdk}/libexec/android-sdk/tools/bin/avdmanager list target
|
||||
|
||||
if [ "$(${sdk}/libexec/android-sdk/tools/android list avd | grep 'Name: device')" = "" ]
|
||||
then
|
||||
# Create a virtual android device
|
||||
yes "" | ${sdk}/libexec/android-sdk/tools/bin/avdmanager create avd -n device -k "system-images;android-${platformVersion};${systemImageType};${abiVersion}" $NIX_ANDROID_AVD_FLAGS
|
||||
|
||||
${lib.optionalString enableGPU ''
|
||||
# Enable GPU acceleration
|
||||
echo "hw.gpu.enabled=yes" >> $ANDROID_SDK_HOME/.android/avd/device.avd/config.ini
|
||||
''}
|
||||
|
||||
${lib.concatMapStrings (extraAVDFile: ''
|
||||
ln -sf ${extraAVDFile} $ANDROID_SDK_HOME/.android/avd/device.avd
|
||||
'') extraAVDFiles}
|
||||
fi
|
||||
|
||||
# Launch the emulator
|
||||
${sdk}/libexec/android-sdk/emulator/emulator -avd device -no-boot-anim -port $port $NIX_ANDROID_EMULATOR_FLAGS &
|
||||
|
||||
# Wait until the device has completely booted
|
||||
echo "Waiting until the emulator has booted the device and the package manager is ready..." >&2
|
||||
|
||||
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port wait-for-device
|
||||
|
||||
echo "Device state has been reached" >&2
|
||||
|
||||
while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop dev.bootcomplete | grep 1)" ]
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "dev.bootcomplete property is 1" >&2
|
||||
|
||||
#while [ -z "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell getprop sys.boot_completed | grep 1)" ]
|
||||
#do
|
||||
#sleep 5
|
||||
#done
|
||||
|
||||
#echo "sys.boot_completed property is 1" >&2
|
||||
|
||||
echo "ready" >&2
|
||||
|
||||
${lib.optionalString (app != null) ''
|
||||
# Install the App through the debugger, if it has not been installed yet
|
||||
|
||||
if [ -z "${package}" ] || [ "$(${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell pm list packages | grep package:${package})" = "" ]
|
||||
then
|
||||
if [ -d "${app}" ]
|
||||
then
|
||||
appPath="$(echo ${app}/*.apk)"
|
||||
else
|
||||
appPath="${app}"
|
||||
fi
|
||||
|
||||
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port install "$appPath"
|
||||
fi
|
||||
|
||||
# Start the application
|
||||
${lib.optionalString (package != null && activity != null) ''
|
||||
${sdk}/libexec/android-sdk/platform-tools/adb -s emulator-$port shell am start -a android.intent.action.MAIN -n ${package}/${activity}
|
||||
''}
|
||||
''}
|
||||
EOF
|
||||
chmod +x $out/bin/run-test-emulator
|
||||
'';
|
||||
}
|
||||
52
pkgs/development/mobile/androidenv/emulator.nix
Normal file
52
pkgs/development/mobile/androidenv/emulator.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{ deployAndroidPackage, lib, package, os, autoPatchelfHook, makeWrapper, pkgs, pkgs_i686 }:
|
||||
|
||||
deployAndroidPackage {
|
||||
inherit package os;
|
||||
buildInputs = [ makeWrapper ]
|
||||
++ lib.optionals (os == "linux") (with pkgs; [
|
||||
autoPatchelfHook
|
||||
glibc
|
||||
libcxx
|
||||
libGL
|
||||
libpulseaudio
|
||||
libuuid
|
||||
zlib
|
||||
ncurses5
|
||||
stdenv.cc.cc
|
||||
i686.glibc
|
||||
expat
|
||||
freetype
|
||||
nss
|
||||
nspr
|
||||
alsa-lib
|
||||
]) ++ (with pkgs.xorg; [
|
||||
libX11
|
||||
libXext
|
||||
libXdamage
|
||||
libXfixes
|
||||
libxcb
|
||||
libXcomposite
|
||||
libXcursor
|
||||
libXi
|
||||
libXrender
|
||||
libXtst
|
||||
]);
|
||||
patchInstructions = lib.optionalString (os == "linux") ''
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib64
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib64/qt/lib
|
||||
# autoPatchelf is not detecting libuuid :(
|
||||
addAutoPatchelfSearchPath ${pkgs.libuuid.out}/lib
|
||||
autoPatchelf $out
|
||||
|
||||
# Wrap emulator so that it can load required libraries at runtime
|
||||
wrapProgram $out/libexec/android-sdk/emulator/emulator \
|
||||
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [
|
||||
pkgs.dbus
|
||||
pkgs.systemd
|
||||
]} \
|
||||
--set QT_XKB_CONFIG_ROOT ${pkgs.xkeyboard_config}/share/X11/xkb \
|
||||
--set QTCOMPOSE ${pkgs.xorg.libX11.out}/share/X11/locale
|
||||
'';
|
||||
dontMoveLib64 = true;
|
||||
}
|
||||
145
pkgs/development/mobile/androidenv/examples/shell.nix
Normal file
145
pkgs/development/mobile/androidenv/examples/shell.nix
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
{
|
||||
# If you copy this example out of nixpkgs, use these lines instead of the next.
|
||||
# This example pins nixpkgs: https://nix.dev/tutorials/towards-reproducibility-pinning-nixpkgs.html
|
||||
/*nixpkgsSource ? (builtins.fetchTarball {
|
||||
name = "nixpkgs-20.09";
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/20.09.tar.gz";
|
||||
sha256 = "1wg61h4gndm3vcprdcg7rc4s1v3jkm5xd7lw8r2f67w502y94gcy";
|
||||
}),
|
||||
pkgs ? import nixpkgsSource {},
|
||||
pkgs_i686 ? import nixpkgsSource { system = "i686-linux"; },*/
|
||||
|
||||
# If you want to use the in-tree version of nixpkgs:
|
||||
pkgs ? import ../../../../.. {},
|
||||
pkgs_i686 ? import ../../../../.. { system = "i686-linux"; },
|
||||
|
||||
config ? pkgs.config
|
||||
}:
|
||||
|
||||
# Copy this file to your Android project.
|
||||
let
|
||||
# Declaration of versions for everything. This is useful since these
|
||||
# versions may be used in multiple places in this Nix expression.
|
||||
android = {
|
||||
versions = {
|
||||
tools = "26.1.1";
|
||||
platformTools = "31.0.2";
|
||||
buildTools = "30.0.3";
|
||||
ndk = [
|
||||
"22.1.7171670"
|
||||
"21.3.6528147" # LTS NDK
|
||||
];
|
||||
cmake = "3.18.1";
|
||||
emulator = "30.6.3";
|
||||
};
|
||||
|
||||
platforms = ["23" "24" "25" "26" "27" "28" "29" "30"];
|
||||
abis = ["armeabi-v7a" "arm64-v8a"];
|
||||
extras = ["extras;google;gcm"];
|
||||
};
|
||||
|
||||
# If you copy this example out of nixpkgs, something like this will work:
|
||||
/*androidEnvNixpkgs = fetchTarball {
|
||||
name = "androidenv";
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/<fill me in from Git>.tar.gz";
|
||||
sha256 = "<fill me in with nix-prefetch-url --unpack>";
|
||||
};
|
||||
|
||||
androidEnv = pkgs.callPackage "${androidEnvNixpkgs}/pkgs/development/mobile/androidenv" {
|
||||
inherit config pkgs pkgs_i686;
|
||||
licenseAccepted = true;
|
||||
};*/
|
||||
|
||||
# Otherwise, just use the in-tree androidenv:
|
||||
androidEnv = pkgs.callPackage ./.. {
|
||||
inherit config pkgs pkgs_i686;
|
||||
licenseAccepted = true;
|
||||
};
|
||||
|
||||
androidComposition = androidEnv.composeAndroidPackages {
|
||||
toolsVersion = android.versions.tools;
|
||||
platformToolsVersion = android.versions.platformTools;
|
||||
buildToolsVersions = [android.versions.buildTools];
|
||||
platformVersions = android.platforms;
|
||||
abiVersions = android.abis;
|
||||
|
||||
includeSources = true;
|
||||
includeSystemImages = true;
|
||||
includeEmulator = true;
|
||||
emulatorVersion = android.versions.emulator;
|
||||
|
||||
includeNDK = true;
|
||||
ndkVersions = android.versions.ndk;
|
||||
cmakeVersions = [android.versions.cmake];
|
||||
|
||||
useGoogleAPIs = true;
|
||||
includeExtras = android.extras;
|
||||
|
||||
# If you want to use a custom repo JSON:
|
||||
# repoJson = ../repo.json;
|
||||
|
||||
# If you want to use custom repo XMLs:
|
||||
/*repoXmls = {
|
||||
packages = [ ../xml/repository2-1.xml ];
|
||||
images = [
|
||||
../xml/android-sys-img2-1.xml
|
||||
../xml/android-tv-sys-img2-1.xml
|
||||
../xml/android-wear-sys-img2-1.xml
|
||||
../xml/android-wear-cn-sys-img2-1.xml
|
||||
../xml/google_apis-sys-img2-1.xml
|
||||
../xml/google_apis_playstore-sys-img2-1.xml
|
||||
];
|
||||
addons = [ ../xml/addon2-1.xml ];
|
||||
};*/
|
||||
|
||||
# Accepting more licenses declaratively:
|
||||
extraLicenses = [
|
||||
# Already accepted for you with the global accept_license = true or
|
||||
# licenseAccepted = true on androidenv.
|
||||
# "android-sdk-license"
|
||||
|
||||
# These aren't, but are useful for more uncommon setups.
|
||||
"android-sdk-preview-license"
|
||||
"android-googletv-license"
|
||||
"android-sdk-arm-dbt-license"
|
||||
"google-gdk-license"
|
||||
"intel-android-extra-license"
|
||||
"intel-android-sysimage-license"
|
||||
"mips-android-sysimage-license"
|
||||
];
|
||||
};
|
||||
|
||||
androidSdk = androidComposition.androidsdk;
|
||||
platformTools = androidComposition.platform-tools;
|
||||
jdk = pkgs.jdk;
|
||||
in
|
||||
pkgs.mkShell rec {
|
||||
name = "androidenv-demo";
|
||||
packages = [ androidSdk platformTools jdk pkgs.android-studio ];
|
||||
|
||||
LANG = "C.UTF-8";
|
||||
LC_ALL = "C.UTF-8";
|
||||
JAVA_HOME = jdk.home;
|
||||
|
||||
# Note: ANDROID_HOME is deprecated. Use ANDROID_SDK_ROOT.
|
||||
ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
|
||||
ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle";
|
||||
|
||||
# Ensures that we don't have to use a FHS env by using the nix store's aapt2.
|
||||
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${android.versions.buildTools}/aapt2";
|
||||
|
||||
shellHook = ''
|
||||
# Add cmake to the path.
|
||||
cmake_root="$(echo "$ANDROID_SDK_ROOT/cmake/${android.versions.cmake}"*/)"
|
||||
export PATH="$cmake_root/bin:$PATH"
|
||||
|
||||
# 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
|
||||
'';
|
||||
}
|
||||
|
||||
26
pkgs/development/mobile/androidenv/fetchrepo.sh
Executable file
26
pkgs/development/mobile/androidenv/fetchrepo.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl
|
||||
|
||||
die() {
|
||||
echo "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
fetch() {
|
||||
local url="https://dl.google.com/android/repository/$1"
|
||||
echo "$url -> $2"
|
||||
curl -s "$url" -o "$2" || die "Failed to fetch $url"
|
||||
}
|
||||
|
||||
pushd "$(dirname "$0")" &>/dev/null || exit 1
|
||||
|
||||
mkdir -p xml
|
||||
|
||||
fetch repository2-1.xml xml/repository2-1.xml
|
||||
for img in android android-tv android-wear android-wear-cn android-automotive google_apis google_apis_playstore
|
||||
do
|
||||
fetch sys-img/$img/sys-img2-1.xml xml/$img-sys-img2-1.xml
|
||||
done
|
||||
fetch addon2-1.xml xml/addon2-1.xml
|
||||
|
||||
popd &>/dev/null
|
||||
3
pkgs/development/mobile/androidenv/generate.sh
Executable file
3
pkgs/development/mobile/androidenv/generate.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
./fetchrepo.sh && ./mkrepo.sh
|
||||
321
pkgs/development/mobile/androidenv/mkrepo.rb
Normal file
321
pkgs/development/mobile/androidenv/mkrepo.rb
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'json'
|
||||
require 'nokogiri'
|
||||
require 'slop'
|
||||
|
||||
# Returns a repo URL for a given package name.
|
||||
def repo_url value
|
||||
if value && value.start_with?('http')
|
||||
value
|
||||
elsif value
|
||||
"https://dl.google.com/android/repository/#{value}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a system image URL for a given system image name.
|
||||
def image_url value, dir
|
||||
if value && value.start_with?('http')
|
||||
value
|
||||
elsif value
|
||||
"https://dl.google.com/android/repository/sys-img/#{dir}/#{value}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a tuple of [type, revision, revision components] for a package node.
|
||||
def package_revision package
|
||||
type_details = package.at_css('> type-details')
|
||||
type = type_details.attributes['type']
|
||||
type &&= type.value
|
||||
|
||||
revision = nil
|
||||
components = nil
|
||||
|
||||
case type
|
||||
when 'generic:genericDetailsType', 'addon:extraDetailsType', 'addon:mavenType'
|
||||
major = text package.at_css('> revision > major')
|
||||
minor = text package.at_css('> revision > minor')
|
||||
micro = text package.at_css('> revision > micro')
|
||||
preview = text package.at_css('> revision > preview')
|
||||
|
||||
revision = ''
|
||||
components = []
|
||||
unless empty?(major)
|
||||
revision << major
|
||||
components << major
|
||||
end
|
||||
|
||||
unless empty?(minor)
|
||||
revision << ".#{minor}"
|
||||
components << minor
|
||||
end
|
||||
|
||||
unless empty?(micro)
|
||||
revision << ".#{micro}"
|
||||
components << micro
|
||||
end
|
||||
|
||||
unless empty?(preview)
|
||||
revision << "-rc#{preview}"
|
||||
components << preview
|
||||
end
|
||||
when 'sdk:platformDetailsType'
|
||||
codename = text type_details.at_css('> codename')
|
||||
api_level = text type_details.at_css('> api-level')
|
||||
revision = empty?(codename) ? api_level : codename
|
||||
components = [revision]
|
||||
when 'sdk:sourceDetailsType'
|
||||
api_level = text type_details.at_css('> api-level')
|
||||
revision, components = api_level, [api_level]
|
||||
when 'sys-img:sysImgDetailsType'
|
||||
codename = text type_details.at_css('> codename')
|
||||
api_level = text type_details.at_css('> api-level')
|
||||
id = text type_details.at_css('> tag > id')
|
||||
abi = text type_details.at_css('> abi')
|
||||
|
||||
revision = ''
|
||||
components = []
|
||||
if empty?(codename)
|
||||
revision << api_level
|
||||
components << api_level
|
||||
else
|
||||
revision << codename
|
||||
components << codename
|
||||
end
|
||||
|
||||
unless empty?(id)
|
||||
revision << "-#{id}"
|
||||
components << id
|
||||
end
|
||||
|
||||
unless empty?(abi)
|
||||
revision << "-#{abi}"
|
||||
components << abi
|
||||
end
|
||||
when 'addon:addonDetailsType' then
|
||||
api_level = text type_details.at_css('> api-level')
|
||||
id = text type_details.at_css('> tag > id')
|
||||
revision = api_level
|
||||
components = [api_level, id]
|
||||
end
|
||||
|
||||
[type, revision, components]
|
||||
end
|
||||
|
||||
# Returns a hash of archives for the specified package node.
|
||||
def package_archives package
|
||||
archives = {}
|
||||
package.css('> archives > archive').each do |archive|
|
||||
host_os = text archive.at_css('> host-os')
|
||||
host_os = 'all' if empty?(host_os)
|
||||
archives[host_os] = {
|
||||
'size' => Integer(text(archive.at_css('> complete > size'))),
|
||||
'sha1' => text(archive.at_css('> complete > checksum')),
|
||||
'url' => yield(text(archive.at_css('> complete > url')))
|
||||
}
|
||||
end
|
||||
archives
|
||||
end
|
||||
|
||||
# Returns the text from a node, or nil.
|
||||
def text node
|
||||
node ? node.text : nil
|
||||
end
|
||||
|
||||
# Nil or empty helper.
|
||||
def empty? value
|
||||
!value || value.empty?
|
||||
end
|
||||
|
||||
# Fixes up returned hashes by sorting keys.
|
||||
# Will also convert archives (e.g. {'linux' => {'sha1' => ...}, 'macosx' => ...} to
|
||||
# [{'os' => 'linux', 'sha1' => ...}, {'os' => 'macosx', ...}, ...].
|
||||
def fixup value
|
||||
Hash[value.map do |k, v|
|
||||
if k == 'archives' && v.is_a?(Hash)
|
||||
[k, v.map do |os, archive|
|
||||
fixup({'os' => os}.merge(archive))
|
||||
end]
|
||||
elsif v.is_a?(Hash)
|
||||
[k, fixup(v)]
|
||||
else
|
||||
[k, v]
|
||||
end
|
||||
end.sort {|(k1, v1), (k2, v2)| k1 <=> k2}]
|
||||
end
|
||||
|
||||
# Normalize the specified license text.
|
||||
# See: https://brash-snapper.glitch.me/ for how the munging works.
|
||||
def normalize_license license
|
||||
license = license.dup
|
||||
license.gsub!(/([^\n])\n([^\n])/m, '\1 \2')
|
||||
license.gsub!(/ +/, ' ')
|
||||
license
|
||||
end
|
||||
|
||||
# Gets all license texts, deduplicating them.
|
||||
def get_licenses doc
|
||||
licenses = {}
|
||||
doc.css('license[type="text"]').each do |license_node|
|
||||
license_id = license_node['id']
|
||||
if license_id
|
||||
licenses[license_id] ||= []
|
||||
licenses[license_id] |= [normalize_license(text(license_node))]
|
||||
end
|
||||
end
|
||||
licenses
|
||||
end
|
||||
|
||||
def parse_package_xml doc
|
||||
licenses = get_licenses doc
|
||||
packages = {}
|
||||
|
||||
doc.css('remotePackage').each do |package|
|
||||
name, _, version = package['path'].partition(';')
|
||||
next if version == 'latest'
|
||||
|
||||
type, revision, _ = package_revision(package)
|
||||
next unless revision
|
||||
|
||||
path = package['path'].tr(';', '/')
|
||||
display_name = text package.at_css('> display-name')
|
||||
uses_license = package.at_css('> uses-license')
|
||||
uses_license &&= uses_license['ref']
|
||||
archives = package_archives(package) {|url| repo_url url}
|
||||
|
||||
target = (packages[name] ||= {})
|
||||
target = (target[revision] ||= {})
|
||||
|
||||
target['name'] ||= name
|
||||
target['path'] ||= path
|
||||
target['revision'] ||= revision
|
||||
target['displayName'] ||= display_name
|
||||
target['license'] ||= uses_license if uses_license
|
||||
target['archives'] ||= {}
|
||||
merge target['archives'], archives
|
||||
end
|
||||
|
||||
[licenses, packages]
|
||||
end
|
||||
|
||||
def parse_image_xml doc
|
||||
licenses = get_licenses doc
|
||||
images = {}
|
||||
|
||||
doc.css('remotePackage[path^="system-images;"]').each do |package|
|
||||
type, revision, components = package_revision(package)
|
||||
next unless revision
|
||||
|
||||
path = package['path'].tr(';', '/')
|
||||
display_name = text package.at_css('> display-name')
|
||||
uses_license = package.at_css('> uses-license')
|
||||
uses_license &&= uses_license['ref']
|
||||
archives = package_archives(package) {|url| image_url url, components[-2]}
|
||||
|
||||
target = images
|
||||
components.each do |component|
|
||||
target = (target[component] ||= {})
|
||||
end
|
||||
|
||||
target['name'] ||= "system-image-#{revision}"
|
||||
target['path'] ||= path
|
||||
target['revision'] ||= revision
|
||||
target['displayName'] ||= display_name
|
||||
target['license'] ||= uses_license if uses_license
|
||||
target['archives'] ||= {}
|
||||
merge target['archives'], archives
|
||||
end
|
||||
|
||||
[licenses, images]
|
||||
end
|
||||
|
||||
def parse_addon_xml doc
|
||||
licenses = get_licenses doc
|
||||
addons, extras = {}, {}
|
||||
|
||||
doc.css('remotePackage').each do |package|
|
||||
type, revision, components = package_revision(package)
|
||||
next unless revision
|
||||
|
||||
path = package['path'].tr(';', '/')
|
||||
display_name = text package.at_css('> display-name')
|
||||
uses_license = package.at_css('> uses-license')
|
||||
uses_license &&= uses_license['ref']
|
||||
archives = package_archives(package) {|url| repo_url url}
|
||||
|
||||
case type
|
||||
when 'addon:addonDetailsType'
|
||||
name = components.last
|
||||
target = addons
|
||||
|
||||
# Hack for Google APIs 25 r1, which displays as 23 for some reason
|
||||
archive_name = text package.at_css('> archives > archive > complete > url')
|
||||
if archive_name == 'google_apis-25_r1.zip'
|
||||
path = 'add-ons/addon-google_apis-google-25'
|
||||
revision = '25'
|
||||
components = [revision, components.last]
|
||||
end
|
||||
when 'addon:extraDetailsType', 'addon:mavenType'
|
||||
name = package['path'].tr(';', '-')
|
||||
components = [package['path']]
|
||||
target = extras
|
||||
end
|
||||
|
||||
components.each do |component|
|
||||
target = (target[component] ||= {})
|
||||
end
|
||||
|
||||
target['name'] ||= name
|
||||
target['path'] ||= path
|
||||
target['revision'] ||= revision
|
||||
target['displayName'] ||= display_name
|
||||
target['license'] ||= uses_license if uses_license
|
||||
target['archives'] ||= {}
|
||||
merge target['archives'], archives
|
||||
end
|
||||
|
||||
[licenses, addons, extras]
|
||||
end
|
||||
|
||||
def merge dest, src
|
||||
dest.merge! src
|
||||
end
|
||||
|
||||
opts = Slop.parse do |o|
|
||||
o.array '-p', '--packages', 'packages repo XMLs to parse'
|
||||
o.array '-i', '--images', 'system image repo XMLs to parse'
|
||||
o.array '-a', '--addons', 'addon repo XMLs to parse'
|
||||
end
|
||||
|
||||
result = {
|
||||
licenses: {},
|
||||
packages: {},
|
||||
images: {},
|
||||
addons: {},
|
||||
extras: {}
|
||||
}
|
||||
|
||||
opts[:packages].each do |filename|
|
||||
licenses, packages = parse_package_xml(Nokogiri::XML(File.open(filename)))
|
||||
merge result[:licenses], licenses
|
||||
merge result[:packages], packages
|
||||
end
|
||||
|
||||
opts[:images].each do |filename|
|
||||
licenses, images = parse_image_xml(Nokogiri::XML(File.open(filename)))
|
||||
merge result[:licenses], licenses
|
||||
merge result[:images], images
|
||||
end
|
||||
|
||||
opts[:addons].each do |filename|
|
||||
licenses, addons, extras = parse_addon_xml(Nokogiri::XML(File.open(filename)))
|
||||
merge result[:licenses], licenses
|
||||
merge result[:addons], addons
|
||||
merge result[:extras], extras
|
||||
end
|
||||
|
||||
puts JSON.pretty_generate(fixup(result))
|
||||
19
pkgs/development/mobile/androidenv/mkrepo.sh
Executable file
19
pkgs/development/mobile/androidenv/mkrepo.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p "ruby.withPackages (pkgs: with pkgs; [ slop nokogiri ])"
|
||||
|
||||
set -e
|
||||
|
||||
pushd "$(dirname "$0")" &>/dev/null || exit 1
|
||||
|
||||
echo "Writing repo.json" >&2
|
||||
ruby mkrepo.rb \
|
||||
--packages ./xml/repository2-1.xml \
|
||||
--images ./xml/android-sys-img2-1.xml \
|
||||
--images ./xml/android-tv-sys-img2-1.xml \
|
||||
--images ./xml/android-wear-cn-sys-img2-1.xml \
|
||||
--images ./xml/android-wear-sys-img2-1.xml \
|
||||
--images ./xml/google_apis-sys-img2-1.xml \
|
||||
--images ./xml/google_apis_playstore-sys-img2-1.xml \
|
||||
--addons ./xml/addon2-1.xml > repo.json
|
||||
|
||||
popd &>/dev/null
|
||||
65
pkgs/development/mobile/androidenv/ndk-bundle/default.nix
Normal file
65
pkgs/development/mobile/androidenv/ndk-bundle/default.nix
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{ stdenv, lib, pkgs, pkgsHostHost, makeWrapper, autoPatchelfHook
|
||||
, deployAndroidPackage, package, os, platform-tools
|
||||
}:
|
||||
|
||||
let
|
||||
runtime_paths = lib.makeBinPath (with pkgsHostHost; [
|
||||
coreutils file findutils gawk gnugrep gnused jdk python3 which
|
||||
]) + ":${platform-tools}/platform-tools";
|
||||
in
|
||||
deployAndroidPackage {
|
||||
inherit package os;
|
||||
nativeBuildInputs = [ makeWrapper ]
|
||||
++ lib.optionals stdenv.isLinux [ autoPatchelfHook ];
|
||||
autoPatchelfIgnoreMissingDeps = true;
|
||||
buildInputs = lib.optional (os == "linux") [ pkgs.glibc pkgs.stdenv.cc.cc pkgs.python2 pkgs.ncurses5 pkgs.zlib pkgs.libcxx.out pkgs.libxml2 ];
|
||||
patchInstructions = lib.optionalString (os == "linux") (''
|
||||
patchShebangs .
|
||||
|
||||
# Fix the shebangs of the auto-generated scripts.
|
||||
substituteInPlace ./build/tools/make_standalone_toolchain.py \
|
||||
--replace '#!/bin/bash' '#!${pkgs.bash}/bin/bash'
|
||||
|
||||
'' + lib.optionalString (builtins.compareVersions (lib.getVersion package) "21" > 0) ''
|
||||
patch -p1 \
|
||||
--no-backup-if-mismatch < ${./make_standalone_toolchain.py_18.patch} || true
|
||||
wrapProgram ./build/tools/make_standalone_toolchain.py --prefix PATH : "${runtime_paths}"
|
||||
'' + ''
|
||||
|
||||
# TODO: allow this stuff
|
||||
rm -rf docs tests
|
||||
|
||||
# Patch the executables of the toolchains, but not the libraries -- they are needed for crosscompiling
|
||||
if [ -d $out/libexec/android-sdk/ndk-bundle/toolchains/renderscript/prebuilt/linux-x86_64/lib64 ]; then
|
||||
addAutoPatchelfSearchPath $out/libexec/android-sdk/ndk-bundle/toolchains/renderscript/prebuilt/linux-x86_64/lib64
|
||||
fi
|
||||
|
||||
if [ -d $out/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/lib64 ]; then
|
||||
addAutoPatchelfSearchPath $out/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/lib64
|
||||
fi
|
||||
|
||||
find toolchains -type d -name bin -or -name lib64 | while read dir; do
|
||||
autoPatchelf "$dir"
|
||||
done
|
||||
|
||||
# fix ineffective PROGDIR / MYNDKDIR determination
|
||||
for progname in ndk-build; do
|
||||
sed -i -e 's|^PROGDIR=`dirname $0`|PROGDIR=`dirname $(readlink -f $(which $0))`|' $progname
|
||||
done
|
||||
|
||||
# Patch executables
|
||||
autoPatchelf prebuilt/linux-x86_64
|
||||
|
||||
# wrap
|
||||
for progname in ndk-build; do
|
||||
wrapProgram "$(pwd)/$progname" --prefix PATH : "${runtime_paths}"
|
||||
done
|
||||
|
||||
# make some executables available in PATH
|
||||
mkdir -p $out/bin
|
||||
for progname in ndk-build; do
|
||||
ln -sf ../libexec/android-sdk/ndk-bundle/$progname $out/bin/$progname
|
||||
done
|
||||
'');
|
||||
noAuditTmpdir = true; # Audit script gets invoked by the build/ component in the path for the make standalone script
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
diff -Naur android-ndk-r18b/build/tools/make_standalone_toolchain.py android-ndk-r18b-new/build/tools/make_standalone_toolchain.py
|
||||
--- android-ndk-r18b/build/tools/make_standalone_toolchain.py 2018-10-11 12:49:38.000000000 +0200
|
||||
+++ android-ndk-r18b-new/build/tools/make_standalone_toolchain.py 2018-11-20 21:55:52.689991420 +0100
|
||||
@@ -30,7 +30,7 @@
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
-
|
||||
+import subprocess
|
||||
|
||||
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
|
||||
NDK_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..'))
|
||||
@@ -173,6 +173,7 @@
|
||||
logger().debug('Copying %s', src_file)
|
||||
shutil.copy2(src_file, dst_dir)
|
||||
|
||||
+ subprocess.check_call(["chmod", "-R", "+w", dst])
|
||||
|
||||
def make_clang_scripts(install_dir, triple, api, windows):
|
||||
"""Creates Clang wrapper scripts.
|
||||
@@ -365,6 +366,7 @@
|
||||
install_headers = os.path.join(install_sysroot, 'usr/include')
|
||||
os.makedirs(os.path.dirname(install_headers))
|
||||
shutil.copytree(headers, install_headers)
|
||||
+ subprocess.check_call(["chmod", "-R", "+w", install_path])
|
||||
|
||||
arch_headers = os.path.join(sysroot, 'usr/include', triple)
|
||||
copy_directory_contents(arch_headers, os.path.join(install_headers))
|
||||
@@ -375,6 +377,7 @@
|
||||
install_sysroot, 'usr/lib{}'.format(lib_suffix))
|
||||
if os.path.exists(lib_path):
|
||||
shutil.copytree(lib_path, lib_install)
|
||||
+ subprocess.check_call(["chmod", "-R", "+w", install_path])
|
||||
|
||||
static_lib_path = os.path.join(sysroot, 'usr/lib', triple)
|
||||
static_lib_install = os.path.join(install_sysroot, 'usr/lib')
|
||||
@@ -389,6 +392,7 @@
|
||||
NDK_DIR, 'prebuilt', 'android-' + arch, 'gdbserver')
|
||||
gdbserver_install = os.path.join(install_path, 'share', 'gdbserver')
|
||||
shutil.copytree(gdbserver_path, gdbserver_install)
|
||||
+ subprocess.check_call(["chmod", "-R", "+w", install_path])
|
||||
|
||||
toolchain_lib_dir = os.path.join(gcc_path, 'lib/gcc', triple)
|
||||
dirs = os.listdir(toolchain_lib_dir)
|
||||
18
pkgs/development/mobile/androidenv/platform-tools.nix
Normal file
18
pkgs/development/mobile/androidenv/platform-tools.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{deployAndroidPackage, lib, package, os, autoPatchelfHook, pkgs}:
|
||||
|
||||
deployAndroidPackage {
|
||||
inherit package os;
|
||||
buildInputs = lib.optionals (os == "linux") [ autoPatchelfHook pkgs.glibc pkgs.zlib pkgs.ncurses5 ];
|
||||
patchInstructions = lib.optionalString (os == "linux") ''
|
||||
addAutoPatchelfSearchPath $packageBaseDir/lib64
|
||||
autoPatchelf --no-recurse $packageBaseDir/lib64
|
||||
autoPatchelf --no-recurse $packageBaseDir
|
||||
'' + ''
|
||||
mkdir -p $out/bin
|
||||
cd $out/bin
|
||||
find $out/libexec/android-sdk/platform-tools -type f -executable -mindepth 1 -maxdepth 1 -not -name sqlite3 | while read i
|
||||
do
|
||||
ln -s $i
|
||||
done
|
||||
'';
|
||||
}
|
||||
23
pkgs/development/mobile/androidenv/querypackages.sh
Executable file
23
pkgs/development/mobile/androidenv/querypackages.sh
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p jq
|
||||
|
||||
set -e
|
||||
|
||||
pushd "$(dirname "$0")" &>/dev/null || exit 1
|
||||
|
||||
if [ "$1" == '' ]; then
|
||||
echo "Please select a group: 'packages', 'images', 'addons', 'extras', or 'licenses'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
namespace="$1"
|
||||
|
||||
if [ "$namespace" == 'licenses' ]; then
|
||||
jq -r '.licenses | keys | join("\n")' < repo.json
|
||||
else
|
||||
jq -r --arg NAMESPACE "$namespace" \
|
||||
'.[$NAMESPACE] | paths as $path | getpath($path) as $v | select($path[-1] == "displayName") | [[$NAMESPACE] + $path[:-1] | map("\"" + . + "\"") | join("."), $v] | join(": ")' \
|
||||
< repo.json
|
||||
fi
|
||||
|
||||
popd &>/dev/null
|
||||
6339
pkgs/development/mobile/androidenv/repo.json
Normal file
6339
pkgs/development/mobile/androidenv/repo.json
Normal file
File diff suppressed because one or more lines are too long
26
pkgs/development/mobile/androidenv/tools.nix
Normal file
26
pkgs/development/mobile/androidenv/tools.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{deployAndroidPackage, requireFile, lib, packages, toolsVersion, autoPatchelfHook, makeWrapper, os, pkgs, pkgs_i686, postInstall ? ""}:
|
||||
|
||||
if toolsVersion == "26.0.1" then import ./tools/26.nix {
|
||||
inherit deployAndroidPackage lib autoPatchelfHook makeWrapper os pkgs pkgs_i686 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 import ./tools/26.nix {
|
||||
inherit deployAndroidPackage lib autoPatchelfHook makeWrapper os pkgs pkgs_i686 postInstall;
|
||||
package = packages.tools.${toolsVersion};
|
||||
} else import ./tools/25.nix {
|
||||
inherit deployAndroidPackage lib autoPatchelfHook makeWrapper os pkgs pkgs_i686 postInstall;
|
||||
package = packages.tools.${toolsVersion};
|
||||
}
|
||||
62
pkgs/development/mobile/androidenv/tools/25.nix
Normal file
62
pkgs/development/mobile/androidenv/tools/25.nix
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgs_i686, postInstall ? ""}:
|
||||
|
||||
deployAndroidPackage {
|
||||
name = "androidsdk";
|
||||
buildInputs = [ autoPatchelfHook makeWrapper ]
|
||||
++ lib.optional (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 pkgs_i686.glibc pkgs_i686.xorg.libX11 pkgs_i686.xorg.libXrender pkgs_i686.fontconfig pkgs_i686.freetype pkgs_i686.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.licenses = lib.licenses.unfree;
|
||||
}
|
||||
44
pkgs/development/mobile/androidenv/tools/26.nix
Normal file
44
pkgs/development/mobile/androidenv/tools/26.nix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{deployAndroidPackage, lib, package, autoPatchelfHook, makeWrapper, os, pkgs, pkgs_i686, postInstall ? ""}:
|
||||
|
||||
deployAndroidPackage {
|
||||
name = "androidsdk";
|
||||
inherit os package;
|
||||
buildInputs = [ makeWrapper ]
|
||||
++ lib.optional (os == "linux") (
|
||||
(with pkgs; [ autoPatchelfHook glibc freetype fontconfig fontconfig.lib])
|
||||
++ (with pkgs.xorg; [ libX11 libXrender libXext ])
|
||||
++ (with pkgs_i686; [ 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.licenses = lib.licenses.unfree;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue