summary refs log tree commit diff
path: root/pkgs/development/mobile/androidenv/compose-android-packages.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/mobile/androidenv/compose-android-packages.nix')
-rw-r--r--pkgs/development/mobile/androidenv/compose-android-packages.nix228
1 files changed, 145 insertions, 83 deletions
diff --git a/pkgs/development/mobile/androidenv/compose-android-packages.nix b/pkgs/development/mobile/androidenv/compose-android-packages.nix
index f98547011bd..f528fcd8558 100644
--- a/pkgs/development/mobile/androidenv/compose-android-packages.nix
+++ b/pkgs/development/mobile/androidenv/compose-android-packages.nix
@@ -1,75 +1,118 @@
-{requireFile, autoPatchelfHook, pkgs, pkgs_i686, licenseAccepted ? false}:
+{ requireFile, autoPatchelfHook, pkgs, pkgsHostHost, pkgs_i686
+, licenseAccepted ? false
+}:
 
-{ toolsVersion ? "25.2.5"
-, platformToolsVersion ? "29.0.6"
-, buildToolsVersions ? [ "28.0.3" ]
+{ toolsVersion ? "26.1.1"
+, platformToolsVersion ? "31.0.2"
+, buildToolsVersions ? [ "30.0.3" ]
 , includeEmulator ? false
-, emulatorVersion ? "30.0.3"
+, emulatorVersion ? "30.6.3"
 , platformVersions ? []
 , includeSources ? false
-, includeDocs ? false
 , includeSystemImages ? false
-, systemImageTypes ? [ "default" ]
+, systemImageTypes ? [ "google_apis_playstore" ]
 , abiVersions ? [ "armeabi-v7a" ]
-, lldbVersions ? [ ]
 , cmakeVersions ? [ ]
 , includeNDK ? false
-, ndkVersion ? "18.1.5063045"
+, ndkVersion ? "22.1.7171670"
+, ndkVersions ? [ndkVersion]
 , useGoogleAPIs ? false
 , useGoogleTVAddOns ? false
 , includeExtras ? []
+, repoJson ? ./repo.json
+, repoXmls ? null
+, extraLicenses ? []
 }:
 
 let
-  inherit (pkgs) stdenv lib fetchurl makeWrapper unzip;
+  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}";
 
-  # Generated Nix packages
-  packages = import ./generated/packages.nix {
-    inherit fetchurl;
-  };
-
-  # Generated system images
-  system-images-packages-android = import ./generated/system-images-android.nix {
-    inherit fetchurl;
-  };
-
-  system-images-packages-android-tv = import ./generated/system-images-android-tv.nix {
-    inherit fetchurl;
-  };
-
-  system-images-packages-android-wear = import ./generated/system-images-android-wear.nix {
-    inherit fetchurl;
-  };
-
-  system-images-packages-android-wear-cn = import ./generated/system-images-android-wear-cn.nix {
-    inherit fetchurl;
-  };
-
-  system-images-packages-google_apis = import ./generated/system-images-google_apis.nix {
-    inherit fetchurl;
+  # 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
+    '';
   };
 
-  system-images-packages-google_apis_playstore = import ./generated/system-images-google_apis_playstore.nix {
-    inherit fetchurl;
+  # 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
+           builtins.fromJSON (builtins.readFile "${mkRepoJson repoXmlSpec}")
+         else
+           builtins.fromJSON (builtins.readFile 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;
   };
 
-  system-images-packages =
-    lib.recursiveUpdate
-      system-images-packages-android
-      (lib.recursiveUpdate system-images-packages-android-tv
-        (lib.recursiveUpdate system-images-packages-android-wear
-          (lib.recursiveUpdate system-images-packages-android-wear-cn
-            (lib.recursiveUpdate system-images-packages-google_apis system-images-packages-google_apis_playstore))));
-
-  # Generated addons
-  addons = import ./generated/addons.nix {
-    inherit fetchurl;
-  };
+  # 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 {
@@ -88,14 +131,9 @@ rec {
     }
   ) buildToolsVersions;
 
-  docs = deployAndroidPackage {
-    inherit os;
-    package = packages.docs."1";
-  };
-
   emulator = import ./emulator.nix {
     inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs pkgs_i686 lib;
-    package = packages.emulator.${emulatorVersion}.${os};
+    package = packages.emulator.${emulatorVersion};
   };
 
   platforms = map (version:
@@ -115,27 +153,22 @@ rec {
   system-images = lib.flatten (map (apiVersion:
     map (type:
       map (abiVersion:
-        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
-          '';
-        }
+        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);
 
-  lldb = map (version:
-    import ./lldb.nix {
-      inherit deployAndroidPackage os autoPatchelfHook pkgs lib;
-      package = packages.lldb.${version};
-    }
-  ) lldbVersions;
-
   cmake = map (version:
     import ./cmake.nix {
       inherit deployAndroidPackage os autoPatchelfHook pkgs lib;
@@ -143,10 +176,18 @@ rec {
     }
   ) cmakeVersions;
 
-  ndk-bundle = import ./ndk-bundle {
-    inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs lib platform-tools;
-    package = packages.ndk-bundle.${ndkVersion};
-  };
+  # Creates a NDK bundle.
+  makeNdkBundle = ndkVersion:
+    import ./ndk-bundle {
+      inherit deployAndroidPackage os autoPatchelfHook makeWrapper pkgs pkgsHostHost lib platform-tools;
+      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 {
@@ -171,6 +212,15 @@ rec {
       '') 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 ''
@@ -187,26 +237,27 @@ rec {
     ''; # */
 
   # This derivation deploys the tools package and symlinks all the desired
-  # plugins that we want to use.
-
+  # plugins that we want to use. If the license isn't accepted, prints all the licenses
+  # requested and throws.
   androidsdk = if !licenseAccepted then throw ''
-    You must accept the Android Software Development Kit License Agreement at
-    https://developer.android.com/studio/terms
-    by setting nixpkgs config option 'android_sdk.accept_license = true;'
+    ${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; }}
-      ${linkPlugin { name = "docs"; plugin = docs; check = includeDocs; }}
       ${linkPlugins { name = "platforms"; plugins = platforms; }}
       ${linkPlatformPlugins { name = "sources"; plugins = sources; check = includeSources; }}
-      ${linkPlugins { name = "lldb"; plugins = lldb; }}
       ${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 ''
@@ -253,6 +304,17 @@ rec {
       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}
     '';
   };
 }