nixpkgs/pkgs/development/mobile/androidenv/androidndk-pkgs.nix
Matthew Bauer c8fd285c8d android: add ndkVer to resolve ndk ambiguity
It wasn’t exactly clear which NDK you were using previously. This adds
an attribute to system that handles what version of the NDK we should
use when building things.

/cc @Ericson2314
2018-06-22 11:06:17 -04:00

117 lines
4.1 KiB
Nix

{ 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";
};
"armv5tel-unknown-linux-androideabi" = {
arch = "arm";
triple = "arm-linux-androideabi";
gccVer = "4.8";
};
"armv7a-unknown-linux-androideabi" = {
arch = "arm";
triple = "arm-linux-androideabi";
gccVer = "4.9";
};
"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 = lib.optionalString targetPlatform.isAarch32 (let
p = targetPlatform.platform.gcc or {}
// targetPlatform.parsed.abi;
flags = lib.concatLists [
(lib.optional (p ? arch) "-march=${p.arch}")
(lib.optional (p ? cpu) "-mcpu=${p.cpu}")
(lib.optional (p ? abi) "-mabi=${p.abi}")
(lib.optional (p ? fpu) "-mfpu=${p.fpu}")
(lib.optional (p ? float) "-mfloat=${p.float}")
(lib.optional (p ? float-abi) "-mfloat-abi=${p.float-abi}")
(lib.optional (p ? mode) "-mmode=${p.mode}")
];
in ''
sed -E -i \
$out/bin/${targetPlatform.config}-cc \
$out/bin/${targetPlatform.config}-c++ \
$out/bin/${targetPlatform.config}-gcc \
$out/bin/${targetPlatform.config}-g++ \
-e '130i extraBefore+=(-Wl,--fix-cortex-a8)' \
-e 's|^(extraBefore=)\(\)$|\1(${builtins.toString flags})|'
'')
# 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 =
let
includePath = if buildAndroidndk.version == "10e" then
"${buildAndroidndk}/libexec/${buildAndroidndk.name}/platforms/android-${hostPlatform.sdkVer}/arch-${hostInfo.arch}/usr/include/"
else
"${buildAndroidndk}/libexec/${buildAndroidndk.name}/sysroot/usr/include";
libPath = "${buildAndroidndk}/libexec/${buildAndroidndk.name}/platforms/android-${hostPlatform.sdkVer}/arch-${hostInfo.arch}/usr/lib/";
in
runCommand "bionic-prebuilt" {} ''
mkdir -p $out
cp -r ${includePath} $out/include
chmod +w $out/include
${lib.optionalString (lib.versionOlder "10e" buildAndroidndk.version)
"ln -s $out/include/${hostInfo.triple}/asm $out/include/asm"}
ln -s ${libPath} $out/lib
'';
}