about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/androidndk-pkgs
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/development/androidndk-pkgs')
-rw-r--r--nixpkgs/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix162
-rw-r--r--nixpkgs/pkgs/development/androidndk-pkgs/default.nix95
2 files changed, 257 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix b/nixpkgs/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix
new file mode 100644
index 000000000000..475fe4564eee
--- /dev/null
+++ b/nixpkgs/pkgs/development/androidndk-pkgs/androidndk-pkgs.nix
@@ -0,0 +1,162 @@
+{ lib, stdenv, makeWrapper
+, runCommand, wrapBintoolsWith, wrapCCWith, autoPatchelfHook
+, 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.
+  #
+  # FIXME:
+  # There's some dragons here. Build host and target concepts are being mixed up.
+  ndkInfoFun = { config, ... }: {
+    x86_64-apple-darwin = {
+      double = "darwin-x86_64";
+    };
+    x86_64-unknown-linux-gnu = {
+      double = "linux-x86_64";
+    };
+    i686-unknown-linux-android = {
+      triple = "i686-linux-android";
+      arch = "x86";
+    };
+    x86_64-unknown-linux-android = {
+      triple = "x86_64-linux-android";
+      arch = "x86_64";
+    };
+    armv7a-unknown-linux-androideabi = {
+      arch = "arm";
+      triple = "arm-linux-androideabi";
+    };
+    aarch64-unknown-linux-android = {
+      arch = "arm64";
+      triple = "aarch64-linux-android";
+    };
+  }.${config} or
+    (throw "Android NDK doesn't support ${config}, as far as we know");
+
+  buildInfo = ndkInfoFun stdenv.buildPlatform;
+  hostInfo = ndkInfoFun stdenv.hostPlatform;
+  targetInfo = ndkInfoFun stdenv.targetPlatform;
+
+  inherit (stdenv.targetPlatform) sdkVer;
+  suffixSalt = lib.replaceStrings ["-" "."] ["_" "_"] stdenv.targetPlatform.config;
+
+  # targetInfo.triple is what Google thinks the toolchain should be, this is a little
+  # different from what we use. We make it four parts to conform with the existing
+  # standard more properly.
+  targetPrefix = lib.optionalString (stdenv.targetPlatform != stdenv.hostPlatform) (stdenv.targetPlatform.config + "-");
+in
+
+rec {
+  # Misc tools
+  binaries = stdenv.mkDerivation {
+    pname = "${targetPrefix}ndk-toolchain";
+    inherit (androidndk) version;
+    nativeBuildInputs = [ makeWrapper autoPatchelfHook ];
+    propagatedBuildInputs = [ androidndk ];
+    passthru = {
+      inherit targetPrefix;
+      isClang = true; # clang based cc, but bintools ld
+    };
+    dontUnpack = true;
+    dontBuild = true;
+    dontStrip = true;
+    dontConfigure = true;
+    dontPatch = true;
+    autoPatchelfIgnoreMissingDeps = true;
+    installPhase = ''
+      # https://developer.android.com/ndk/guides/other_build_systems
+      mkdir -p $out
+      cp -r ${androidndk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/${buildInfo.double} $out/toolchain
+      find $out/toolchain -type d -exec chmod 777 {} \;
+
+      if [ ! -d $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer} ]; then
+        echo "NDK does not contain libraries for SDK version ${sdkVer}";
+        exit 1
+      fi
+
+      ln -vfs $out/toolchain/sysroot/usr/lib $out/lib
+      ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/*.so $out/lib/
+      ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/*.a $out/lib/
+      chmod +w $out/lib/*
+      ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}/*.so $out/lib/
+      ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}/*.o $out/lib/
+
+      echo "INPUT(-lc++_static)" > $out/lib/libc++.a
+
+      ln -s $out/toolchain/bin $out/bin
+      ln -s $out/toolchain/${targetInfo.triple}/bin/* $out/bin/
+      for f in $out/bin/${targetInfo.triple}-*; do
+        ln -s $f ''${f/${targetInfo.triple}-/${targetPrefix}}
+      done
+      for f in $(find $out/toolchain -type d -name ${targetInfo.triple}); do
+        ln -s $f ''${f/${targetInfo.triple}/${targetPrefix}}
+      done
+
+      rm -f $out/bin/${targetPrefix}ld
+      ln -s $out/bin/lld $out/bin/${targetPrefix}ld
+
+      (cd $out/bin;
+        for tool in llvm-*; do
+          ln -sf $tool ${targetPrefix}$(echo $tool | sed 's/llvm-//')
+          ln -sf $tool $(echo $tool | sed 's/llvm-//')
+        done)
+
+      # handle last, as llvm-as is for llvm bytecode
+      ln -sf $out/bin/${targetInfo.triple}-as $out/bin/${targetPrefix}as
+      ln -sf $out/bin/${targetInfo.triple}-as $out/bin/as
+
+      patchShebangs $out/bin
+    '';
+  };
+
+  binutils = wrapBintoolsWith {
+    bintools = binaries;
+    libc = targetAndroidndkPkgs.libraries;
+  };
+
+  clang = wrapCCWith {
+    cc = binaries // {
+      # for packages expecting libcompiler-rt, etc. to come from here (stdenv.cc.cc.lib)
+      lib = targetAndroidndkPkgs.libraries;
+    };
+    bintools = binutils;
+    libc = targetAndroidndkPkgs.libraries;
+    extraBuildCommands = ''
+      echo "-D__ANDROID_API__=${stdenv.targetPlatform.sdkVer}" >> $out/nix-support/cc-cflags
+      # Android needs executables linked with -pie since version 5.0
+      # Use -fPIC for compilation, and link with -pie if no -shared flag used in ldflags
+      echo "-target ${targetInfo.triple} -fPIC" >> $out/nix-support/cc-cflags
+      echo "-z,noexecstack -z,relro -z,now -z,muldefs" >> $out/nix-support/cc-ldflags
+      echo 'expandResponseParams "$@"' >> $out/nix-support/add-flags.sh
+      echo 'if [[ ! (" ''${params[@]} " =~ " -shared ") && ! (" ''${params[@]} " =~ " -no-pie ") ]]; then NIX_LDFLAGS_${suffixSalt}+=" -pie"; fi' >> $out/nix-support/add-flags.sh
+      echo "-Xclang -mnoexecstack" >> $out/nix-support/cc-cxxflags
+      if [ ${targetInfo.triple} == arm-linux-androideabi ]; then
+        # https://android.googlesource.com/platform/external/android-cmake/+/refs/heads/cmake-master-dev/android.toolchain.cmake
+        echo "--fix-cortex-a8" >> $out/nix-support/cc-ldflags
+      fi
+    '';
+  };
+
+  # 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 = runCommand "bionic-prebuilt" {} ''
+    lpath=${buildAndroidndk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/${buildInfo.double}/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}
+    if [ ! -d $lpath ]; then
+      echo "NDK does not contain libraries for SDK version ${sdkVer} <$lpath>"
+      exit 1
+    fi
+    mkdir -p $out/lib
+    cp $lpath/*.so $lpath/*.a $out/lib
+    chmod +w $out/lib/*
+    cp $lpath/* $out/lib
+  '';
+}
diff --git a/nixpkgs/pkgs/development/androidndk-pkgs/default.nix b/nixpkgs/pkgs/development/androidndk-pkgs/default.nix
new file mode 100644
index 000000000000..a7001ce1d4a6
--- /dev/null
+++ b/nixpkgs/pkgs/development/androidndk-pkgs/default.nix
@@ -0,0 +1,95 @@
+{ lib, androidenv, buildPackages, pkgs, targetPackages
+}:
+
+{
+  "21" =
+    let
+      ndkVersion = "21.0.6113669";
+
+      buildAndroidComposition = buildPackages.buildPackages.androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+
+      androidComposition = androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+    in
+    import ./androidndk-pkgs.nix {
+      inherit lib;
+      inherit (buildPackages)
+        makeWrapper autoPatchelfHook;
+      inherit (pkgs)
+        stdenv
+        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 = buildAndroidComposition.ndk-bundle;
+      androidndk = androidComposition.ndk-bundle;
+      targetAndroidndkPkgs = targetPackages.androidndkPkgs_21;
+    };
+
+  "23b" =
+    let
+      ndkVersion = "23.1.7779620";
+
+      buildAndroidComposition = buildPackages.buildPackages.androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+
+      androidComposition = androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+    in
+    import ./androidndk-pkgs.nix {
+      inherit lib;
+      inherit (buildPackages)
+        makeWrapper autoPatchelfHook;
+      inherit (pkgs)
+        stdenv
+        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 = buildAndroidComposition.ndk-bundle;
+      androidndk = androidComposition.ndk-bundle;
+      targetAndroidndkPkgs = targetPackages.androidndkPkgs_23b;
+    };
+
+  "24" =
+    let
+      ndkVersion = "24.0.8215888";
+
+      buildAndroidComposition = buildPackages.buildPackages.androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+
+      androidComposition = androidenv.composeAndroidPackages {
+        includeNDK = true;
+        inherit ndkVersion;
+      };
+    in
+    import ./androidndk-pkgs.nix {
+      inherit lib;
+      inherit (buildPackages)
+        makeWrapper autoPatchelfHook;
+      inherit (pkgs)
+        stdenv
+        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 = buildAndroidComposition.ndk-bundle;
+      androidndk = androidComposition.ndk-bundle;
+      targetAndroidndkPkgs = targetPackages.androidndkPkgs_24;
+    };
+
+}