Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / androidndk-pkgs / androidndk-pkgs.nix
bloba8b172f4eb5d2e8c6651aaa89fb75a75b0d2dee1
1 { lib, stdenv, makeWrapper
2 , runCommand, wrapBintoolsWith, wrapCCWith, autoPatchelfHook
3 , buildAndroidndk, androidndk, targetAndroidndkPkgs
4 }:
6 let
7   # Mapping from a platform to information needed to unpack NDK stuff for that
8   # platform.
9   #
10   # N.B. The Android NDK uses slightly different LLVM-style platform triples
11   # than we do. We don't just use theirs because ours are less ambiguous and
12   # some builds need that clarity.
13   #
14   ndkBuildInfoFun = { config, ... }: {
15     x86_64-apple-darwin = {
16       double = "darwin-x86_64";
17     };
18     x86_64-unknown-linux-gnu = {
19       double = "linux-x86_64";
20     };
21   }.${config} or
22     (throw "Android NDK doesn't support building on ${config}, as far as we know");
24   ndkTargetInfoFun = { config, ... }: {
25     i686-unknown-linux-android = {
26       triple = "i686-linux-android";
27       arch = "x86";
28     };
29     x86_64-unknown-linux-android = {
30       triple = "x86_64-linux-android";
31       arch = "x86_64";
32     };
33     armv7a-unknown-linux-androideabi = {
34       arch = "arm";
35       triple = "arm-linux-androideabi";
36     };
37     aarch64-unknown-linux-android = {
38       arch = "arm64";
39       triple = "aarch64-linux-android";
40     };
41   }.${config} or
42     (throw "Android NDK doesn't support targetting ${config}, as far as we know");
44   buildInfo = ndkBuildInfoFun stdenv.buildPlatform;
45   targetInfo = ndkTargetInfoFun stdenv.targetPlatform;
47   inherit (stdenv.targetPlatform) sdkVer;
48   suffixSalt = lib.replaceStrings ["-" "."] ["_" "_"] stdenv.targetPlatform.config;
50   # targetInfo.triple is what Google thinks the toolchain should be, this is a little
51   # different from what we use. We make it four parts to conform with the existing
52   # standard more properly.
53   targetPrefix = lib.optionalString (stdenv.targetPlatform != stdenv.hostPlatform) (stdenv.targetPlatform.config + "-");
56 rec {
57   # Misc tools
58   binaries = stdenv.mkDerivation {
59     pname = "${targetPrefix}ndk-toolchain";
60     inherit (androidndk) version;
61     nativeBuildInputs = [ makeWrapper autoPatchelfHook ];
62     propagatedBuildInputs = [ androidndk ];
63     passthru = {
64       inherit targetPrefix;
65       isClang = true; # clang based cc, but bintools ld
66     };
67     dontUnpack = true;
68     dontBuild = true;
69     dontStrip = true;
70     dontConfigure = true;
71     dontPatch = true;
72     autoPatchelfIgnoreMissingDeps = true;
73     installPhase = ''
74       # https://developer.android.com/ndk/guides/other_build_systems
75       mkdir -p $out
76       cp -r ${androidndk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/${buildInfo.double} $out/toolchain
77       find $out/toolchain -type d -exec chmod 777 {} \;
79       if [ ! -d $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer} ]; then
80         echo "NDK does not contain libraries for SDK version ${sdkVer}";
81         exit 1
82       fi
84       ln -vfs $out/toolchain/sysroot/usr/lib $out/lib
85       ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/*.so $out/lib/
86       ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/*.a $out/lib/
87       chmod +w $out/lib/*
88       ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}/*.so $out/lib/
89       ln -s $out/toolchain/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}/*.o $out/lib/
91       echo "INPUT(-lc++_static)" > $out/lib/libc++.a
93       ln -s $out/toolchain/bin $out/bin
94       ln -s $out/toolchain/${targetInfo.triple}/bin/* $out/bin/
95       for f in $out/bin/${targetInfo.triple}-*; do
96         ln -s $f ''${f/${targetInfo.triple}-/${targetPrefix}}
97       done
98       for f in $(find $out/toolchain -type d -name ${targetInfo.triple}); do
99         ln -s $f ''${f/${targetInfo.triple}/${targetPrefix}}
100       done
102       rm -f $out/bin/${targetPrefix}ld
103       ln -s $out/bin/lld $out/bin/${targetPrefix}ld
105       (cd $out/bin;
106         for tool in llvm-*; do
107           ln -sf $tool ${targetPrefix}$(echo $tool | sed 's/llvm-//')
108           ln -sf $tool $(echo $tool | sed 's/llvm-//')
109         done)
111       # handle last, as llvm-as is for llvm bytecode
112       ln -sf $out/bin/${targetInfo.triple}-as $out/bin/${targetPrefix}as
113       ln -sf $out/bin/${targetInfo.triple}-as $out/bin/as
115       patchShebangs $out/bin
116     '';
117   };
119   binutils = wrapBintoolsWith {
120     bintools = binaries;
121     libc = targetAndroidndkPkgs.libraries;
122   };
124   clang = wrapCCWith {
125     cc = binaries // {
126       # for packages expecting libcompiler-rt, etc. to come from here (stdenv.cc.cc.lib)
127       lib = targetAndroidndkPkgs.libraries;
128     };
129     bintools = binutils;
130     libc = targetAndroidndkPkgs.libraries;
131     extraBuildCommands = ''
132       echo "-D__ANDROID_API__=${stdenv.targetPlatform.sdkVer}" >> $out/nix-support/cc-cflags
133       # Android needs executables linked with -pie since version 5.0
134       # Use -fPIC for compilation, and link with -pie if no -shared flag used in ldflags
135       echo "-target ${targetInfo.triple} -fPIC" >> $out/nix-support/cc-cflags
136       echo "-z,noexecstack -z,relro -z,now -z,muldefs" >> $out/nix-support/cc-ldflags
137       echo 'expandResponseParams "$@"' >> $out/nix-support/add-flags.sh
138       echo 'if [[ ! (" ''${params[@]} " =~ " -shared ") && ! (" ''${params[@]} " =~ " -no-pie ") ]]; then NIX_LDFLAGS_${suffixSalt}+=" -pie"; fi' >> $out/nix-support/add-flags.sh
139       echo "-Xclang -mnoexecstack" >> $out/nix-support/cc-cxxflags
140       if [ ${targetInfo.triple} == arm-linux-androideabi ]; then
141         # https://android.googlesource.com/platform/external/android-cmake/+/refs/heads/cmake-master-dev/android.toolchain.cmake
142         echo "--fix-cortex-a8" >> $out/nix-support/cc-ldflags
143       fi
144     '';
145   };
147   # Bionic lib C and other libraries.
148   #
149   # We use androidndk from the previous stage, else we waste time or get cycles
150   # cross-compiling packages to wrap incorrectly wrap binaries we don't include
151   # anyways.
152   libraries = runCommand "bionic-prebuilt" {} ''
153     lpath=${buildAndroidndk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/${buildInfo.double}/sysroot/usr/lib/${targetInfo.triple}/${sdkVer}
154     if [ ! -d $lpath ]; then
155       echo "NDK does not contain libraries for SDK version ${sdkVer} <$lpath>"
156       exit 1
157     fi
158     mkdir -p $out/lib
159     cp $lpath/*.so $lpath/*.a $out/lib
160     chmod +w $out/lib/*
161     cp $lpath/* $out/lib
162   '';