about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Ericson <Ericson2314@Yahoo.com>2017-02-17 00:36:10 -0500
committerJohn Ericson <John.Ericson@Obsidian.Systems>2018-02-27 14:15:39 -0500
commit2482e2858e7e2d5e91f506932f3774288ca6120d (patch)
tree3619ff9d81826a55baa3d4b10ab8a4f1c96d3abe
parentdfc5d7835d6e248d3cc83430da941277ae5cabaa (diff)
downloadnixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar.gz
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar.bz2
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar.lz
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar.xz
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.tar.zst
nixlib-2482e2858e7e2d5e91f506932f3774288ca6120d.zip
prebuilt android tools: Init using SDK
Expose as an option for the cross stdenv.
-rw-r--r--lib/systems/default.nix17
-rw-r--r--lib/systems/examples.nix7
-rw-r--r--lib/systems/inspect.nix1
-rw-r--r--lib/systems/parse.nix1
-rw-r--r--pkgs/development/mobile/androidenv/androidndk-pkgs.nix82
-rw-r--r--pkgs/development/mobile/androidenv/default.nix15
-rw-r--r--pkgs/stdenv/cross/default.nix4
-rw-r--r--pkgs/top-level/all-packages.nix5
-rw-r--r--pkgs/top-level/release-cross.nix7
9 files changed, 130 insertions, 9 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index 0729cc7ef293..d5a206e620c8 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -23,13 +23,15 @@ rec {
       config = parse.tripleFromSystem final.parsed;
       # Just a guess, based on `system`
       platform = platforms.selectBySystem final.system;
+      # Derived meta-data
       libc =
-        /**/ if final.isDarwin then "libSystem"
-        else if final.isMinGW  then "msvcrt"
-        else if final.isMusl  then "musl"
-        else if final.isLinux /* default */    then "glibc"
+        /**/ if final.isDarwin              then "libSystem"
+        else if final.isMinGW               then "msvcrt"
+        else if final.isMusl                then "musl"
+        else if final.isAndroid             then "bionic"
+        else if final.isLinux /* default */ then "glibc"
         # TODO(@Ericson2314) think more about other operating systems
-        else                        "native/impure";
+        else                                     "native/impure";
       extensions = {
         sharedLibrary =
           /**/ if final.isDarwin  then ".dylib"
@@ -39,7 +41,10 @@ rec {
           /**/ if final.isWindows then ".exe"
           else                         "";
       };
+      # Misc boolean options
+      useAndroidPrebuilt = false;
     } // mapAttrs (n: v: v final.parsed) inspect.predicates
       // args;
-  in final;
+  in assert final.useAndroidPrebuilt -> final.isAndroid;
+    final;
 }
diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix
index e0d08ed5daed..848737700b0b 100644
--- a/lib/systems/examples.nix
+++ b/lib/systems/examples.nix
@@ -38,6 +38,13 @@ rec {
     platform = platforms.aarch64-multiplatform;
   };
 
+  aarch64-android-prebuilt = rec {
+    config = "aarch64-unknown-linux-android";
+    arch = "aarch64";
+    platform = platforms.aarch64-multiplatform;
+    useAndroidPrebuilt = true;
+  };
+
   scaleway-c1 = armv7l-hf-multiplatform // rec {
     platform = platforms.scaleway-c1;
     inherit (platform.gcc) fpu;
diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix
index ff8f60001175..ab220af46e30 100644
--- a/lib/systems/inspect.nix
+++ b/lib/systems/inspect.nix
@@ -34,6 +34,7 @@ rec {
     Cygwin       = { kernel = kernels.windows; abi = abis.cygnus; };
     MinGW        = { kernel = kernels.windows; abi = abis.gnu; };
 
+    Android      = [ { abi = abis.android; } { abi = abis.androideabi; } ];
     Musl         = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
 
     Kexecable    = map (family: { kernel = kernels.linux; cpu.family = family; })
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index eea471f5773d..03d052f5f192 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -176,6 +176,7 @@ rec {
   types.abi = enum (attrValues abis);
 
   abis = setTypes types.openAbi {
+    android = {};
     cygnus = {};
     gnu = {};
     msvc = {};
diff --git a/pkgs/development/mobile/androidenv/androidndk-pkgs.nix b/pkgs/development/mobile/androidenv/androidndk-pkgs.nix
new file mode 100644
index 000000000000..19fc0dc812d8
--- /dev/null
+++ b/pkgs/development/mobile/androidenv/androidndk-pkgs.nix
@@ -0,0 +1,82 @@
+{ lib, hostPlatform, targetPlatform
+, makeWrapper
+, runCommand, wrapBintoolsWith, wrapCCWith
+, buildAndroidndk, androidndk, targetAndroidndkPkgs
+}:
+
+let
+  # Mapping from a platform to information needed to unpack NDK stuff for that
+  # platform.
+  #
+  # N.B. The Android NDK uses slightly different LLVM-style platform triples
+  # than we do. We don't just use theirs because ours are less ambiguous and
+  # some builds need that clarity.
+  ndkInfoFun = { config, ... }: {
+    "x86_64-unknown-linux-gnu" = {
+      double = "linux-x86_64";
+    };
+    "arm-unknown-linux-androideabi" = {
+      arch = "arm";
+      triple = "arm-linux-androideabi";
+      gccVer = "4.8";
+    };
+    "aarch64-unknown-linux-android" = {
+      arch = "arm64";
+      triple = "aarch64-linux-android";
+      gccVer = "4.9";
+    };
+  }.${config} or
+    (throw "Android NDK doesn't support ${config}, as far as we know");
+
+  hostInfo = ndkInfoFun hostPlatform;
+  targetInfo = ndkInfoFun targetPlatform;
+
+in
+
+rec {
+  # Misc tools
+  binaries = let
+      ndkBinDir =
+        "${androidndk}/libexec/${androidndk.name}/toolchains/${targetInfo.triple}-${targetInfo.gccVer}/prebuilt/${hostInfo.double}/bin";
+    in runCommand "ndk-gcc-binutils" {
+      isGNU = true; # for cc-wrapper
+      nativeBuildInputs = [ makeWrapper ];
+      propgatedBuildInputs = [ androidndk ];
+    } ''
+      mkdir -p $out/bin
+      for prog in ${ndkBinDir}/${targetInfo.triple}-*; do
+        prog_suffix=$(basename $prog | sed 's/${targetInfo.triple}-//')
+        ln -s $prog $out/bin/${targetPlatform.config}-$prog_suffix
+      done
+    '';
+
+  binutils = wrapBintoolsWith {
+    bintools = binaries;
+    libc = targetAndroidndkPkgs.libraries;
+  };
+
+  gcc = wrapCCWith {
+    cc = binaries;
+    bintools = binutils;
+    libc = targetAndroidndkPkgs.libraries;
+    extraBuildCommands =
+      # GCC 4.9 is the first relase with "-fstack-protector"
+      lib.optionalString (lib.versionOlder targetInfo.gccVer "4.9") ''
+        sed -E \
+        -i $out/nix-support/add-hardening.sh \
+        -e 's|(-fstack-protector)-strong|\1|g'
+      '';
+  };
+
+  # Bionic lib C and other libraries.
+  #
+  # We use androidndk from the previous stage, else we waste time or get cycles
+  # cross-compiling packages to wrap incorrectly wrap binaries we don't include
+  # anyways.
+  libraries = {
+    name = "bionic-prebuilt";
+    type = "derivation";
+    outPath = "${buildAndroidndk}/libexec/${buildAndroidndk.name}/platforms/android-21/arch-${hostInfo.arch}/usr/";
+    drvPath = throw "fake derivation, build ${buildAndroidndk} to use";
+  };
+}
diff --git a/pkgs/development/mobile/androidenv/default.nix b/pkgs/development/mobile/androidenv/default.nix
index 98531eeb069e..c053712302dd 100644
--- a/pkgs/development/mobile/androidenv/default.nix
+++ b/pkgs/development/mobile/androidenv/default.nix
@@ -242,4 +242,19 @@ rec {
     inherit (pkgs) stdenv;
     inherit androidsdk;
   };
+
+  androidndkPkgs = import ./androidndk-pkgs.nix {
+    inherit (buildPackages)
+      makeWrapper;
+    inherit (pkgs)
+      lib hostPlatform targetPlatform
+      runCommand wrapBintoolsWith wrapCCWith;
+    # buildPackages.foo rather than buildPackages.buildPackages.foo would work,
+    # but for splicing messing up on infinite recursion for the variants we
+    # *dont't* use. Using this workaround, but also making a test to ensure
+    # these two really are the same.
+    buildAndroidndk = buildPackages.buildPackages.androidenv.androidndk;
+    inherit androidndk;
+    targetAndroidndkPkgs = targetPackages.androidenv.androidndkPkgs;
+  };
 }
diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix
index 8197510eeecc..8da3555c6c60 100644
--- a/pkgs/stdenv/cross/default.nix
+++ b/pkgs/stdenv/cross/default.nix
@@ -34,7 +34,9 @@ in bootStages ++ [
       hostPlatform = crossSystem;
       targetPlatform = crossSystem;
       cc = if crossSystem.useiOSCross or false
-           then buildPackages.darwin.ios-cross
+             then buildPackages.darwin.ios-cross
+           else if crossSystem.useAndroidPrebuilt
+             then buildPackages.androidenv.androidndkPkgs.gcc
            else buildPackages.gcc;
     };
   })
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 24908b4863b7..68cf3e6bb15e 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -8326,6 +8326,10 @@ with pkgs;
 
   libopcodes = callPackage ../development/libraries/libopcodes { };
 
+  # TODO(@Ericson2314): Build bionic libc from source
+  bionic = assert hostPlatform.useAndroidPrebuilt;
+    androidenv.androidndkPkgs.libraries;
+
   bobcat = callPackage ../development/libraries/bobcat { };
 
   boehmgc = callPackage ../development/libraries/boehm-gc { };
@@ -8862,6 +8866,7 @@ with pkgs;
     # libc is hackily often used from the previous stage. This `or`
     # hack fixes the hack, *sigh*.
     /**/ if name == "glibc" then targetPackages.glibcCross or glibcCross
+    else if name == "bionic" then targetPackages.bionic
     else if name == "uclibc" then uclibcCross
     else if name == "musl" then targetPackages.muslCross or muslCross
     else if name == "msvcrt" then targetPackages.windows.mingw_w64 or windows.mingw_w64
diff --git a/pkgs/top-level/release-cross.nix b/pkgs/top-level/release-cross.nix
index be6dd89bf7dd..ef99dbd619e4 100644
--- a/pkgs/top-level/release-cross.nix
+++ b/pkgs/top-level/release-cross.nix
@@ -93,6 +93,7 @@ in
     mapTestEqual = lib.mapAttrsRecursive testEqual;
 
   in mapTestEqual {
+    androidndk = nativePlatforms;
     boehmgc = nativePlatforms;
     libffi = nativePlatforms;
     libiconv = nativePlatforms;
@@ -125,12 +126,14 @@ in
   rpi = mapTestOnCross lib.systems.examples.raspberryPi rpiCommon;
   rpi-musl = mapTestOnCross lib.systems.examples.muslpi rpiCommon;
 
-  /* Linux on Aarch64 (TODO make android for real)  */
-  android = mapTestOnCross lib.systems.examples.aarch64-multiplatform linuxCommon;
   aarch64-musl = mapTestOnCross lib.systems.examples.aarch64-multiplatform-musl linuxCommon;
 
   x86_64-musl = mapTestOnCross lib.systems.examples.musl64 linuxCommon;
 
+  /* Linux on Aarch64 */
+  android64 = mapTestOnCross lib.systems.examples.aarch64-android-prebuilt (linuxCommon // {
+  });
+
   /* Cross-built bootstrap tools for every supported platform */
   bootstrapTools = let
     tools = import ../stdenv/linux/make-bootstrap-tools-cross.nix { system = "x86_64-linux"; };