Merge pull request #117591 from s1341/android_non_prebuilt

treewide: Support aarch64-android using minimal prebuilt components

authored by

John Ericson and committed by
GitHub
912c8262 032a1e44

+222 -12
+9
lib/systems/examples.nix
··· 70 70 useAndroidPrebuilt = true; 71 71 }; 72 72 73 + aarch64-android = { 74 + config = "aarch64-unknown-linux-android"; 75 + sdkVer = "30"; 76 + ndkVer = "21"; 77 + libc = "bionic"; 78 + useAndroidPrebuilt = false; 79 + useLLVM = true; 80 + }; 81 + 73 82 scaleway-c1 = armv7l-hf-multiplatform // platforms.scaleway-c1; 74 83 75 84 pogoplug4 = {
+4
pkgs/build-support/cc-wrapper/default.nix
··· 493 493 echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags 494 494 '' 495 495 496 + + optionalString targetPlatform.isAndroid '' 497 + echo "-D__ANDROID_API__=${targetPlatform.sdkVer}" >> $out/nix-support/cc-cflags 498 + '' 499 + 496 500 # There are a few tools (to name one libstdcxx5) which do not work 497 501 # well with multi line flags, so make the flags single line again 498 502 + ''
+6 -4
pkgs/development/compilers/llvm/12/compiler-rt/default.nix
··· 4 4 5 5 useLLVM = stdenv.hostPlatform.useLLVM or false; 6 6 bareMetal = stdenv.hostPlatform.parsed.kernel.name == "none"; 7 + haveLibc = stdenv.cc.libc != null; 7 8 inherit (stdenv.hostPlatform) isMusl; 8 9 9 10 in 10 11 11 12 stdenv.mkDerivation rec { 12 - pname = "compiler-rt"; 13 + pname = "compiler-rt" + lib.optionalString (haveLibc) "-libc"; 13 14 inherit version; 14 - src = fetch pname "0d444qihq9jhqnfv003cr704v363va72zl6qaw2algj1c85cva45"; 15 + src = fetch "compiler-rt" "0d444qihq9jhqnfv003cr704v363va72zl6qaw2algj1c85cva45"; 15 16 16 17 nativeBuildInputs = [ cmake python3 llvm.dev ]; 17 18 buildInputs = lib.optional stdenv.hostPlatform.isDarwin libcxxabi; ··· 29 30 "-DCOMPILER_RT_BUILD_XRAY=OFF" 30 31 "-DCOMPILER_RT_BUILD_LIBFUZZER=OFF" 31 32 "-DCOMPILER_RT_BUILD_PROFILE=OFF" 32 - ] ++ lib.optionals (useLLVM || bareMetal) [ 33 + ] ++ lib.optionals ((useLLVM || bareMetal) && !haveLibc) [ 33 34 "-DCMAKE_C_COMPILER_WORKS=ON" 34 35 "-DCMAKE_CXX_COMPILER_WORKS=ON" 35 36 "-DCOMPILER_RT_BAREMETAL_BUILD=ON" 36 37 "-DCMAKE_SIZEOF_VOID_P=${toString (stdenv.hostPlatform.parsed.cpu.bits / 8)}" 38 + ] ++ lib.optionals (useLLVM && !haveLibc) [ 39 + "-DCMAKE_C_FLAGS=-nodefaultlibs" 37 40 ] ++ lib.optionals (useLLVM) [ 38 41 "-DCOMPILER_RT_BUILD_BUILTINS=ON" 39 - "-DCMAKE_C_FLAGS=-nodefaultlibs" 40 42 #https://stackoverflow.com/questions/53633705/cmake-the-c-compiler-is-not-able-to-compile-a-simple-test-program 41 43 "-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY" 42 44 ] ++ lib.optionals (bareMetal) [
+23 -1
pkgs/development/compilers/llvm/12/default.nix
··· 131 131 echo "-B${targetLlvmLibraries.compiler-rt}/lib" >> $out/nix-support/cc-cflags 132 132 '' + lib.optionalString (!stdenv.targetPlatform.isWasm) '' 133 133 echo "--unwindlib=libunwind" >> $out/nix-support/cc-cflags 134 + '' + lib.optionalString (stdenv.targetPlatform.isAndroid && stdenv.targetPlatform.useLLVM) '' 135 + echo "-lunwind" >> $out/nix-support/cc-ldflags 134 136 '' + lib.optionalString stdenv.targetPlatform.isWasm '' 135 137 echo "-fno-exceptions" >> $out/nix-support/cc-cflags 136 138 '' + mkExtraBuildCommands cc; ··· 181 183 '' + mkExtraBuildCommands0 cc; 182 184 }; 183 185 186 + lldClangNoCompilerRtWithLibc = wrapCCWith rec { 187 + cc = tools.clang-unwrapped; 188 + libcxx = null; 189 + bintools = wrapBintoolsWith { 190 + inherit (tools) bintools; 191 + }; 192 + extraPackages = [ ]; 193 + extraBuildCommands = mkExtraBuildCommands0 cc; 194 + }; 195 + 184 196 }); 185 197 186 198 libraries = lib.makeExtensible (libraries: let 187 199 callPackage = newScope (libraries // buildLlvmTools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch; }); 188 200 in { 189 201 190 - compiler-rt = callPackage ./compiler-rt ({ inherit llvm_meta; } // 202 + compiler-rt-libc = callPackage ./compiler-rt ({ inherit llvm_meta; } // 203 + (lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) { 204 + stdenv = overrideCC stdenv buildLlvmTools.lldClangNoCompilerRtWithLibc; 205 + })); 206 + 207 + compiler-rt-no-libc = callPackage ./compiler-rt ({ inherit llvm_meta; } // 191 208 (lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) { 192 209 stdenv = overrideCC stdenv buildLlvmTools.lldClangNoCompilerRt; 193 210 })); 211 + 212 + # N.B. condition is safe because without useLLVM both are the same. 213 + compiler-rt = if stdenv.hostPlatform.isAndroid 214 + then libraries.compiler-rt-libc 215 + else libraries.compiler-rt-no-libc; 194 216 195 217 stdenv = overrideCC stdenv buildLlvmTools.clang; 196 218
+113
pkgs/os-specific/linux/bionic-prebuilt/default.nix
··· 1 + { stdenvNoCC, lib, fetchurl, fetchzip, pkgs 2 + }: 3 + let 4 + 5 + prebuilt_crt = fetchzip { 6 + url = "https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/+archive/98dce673ad97a9640c5d90bbb1c718e75c21e071/lib/gcc/aarch64-linux-android/4.9.x.tar.gz"; 7 + sha256 = "sha256-LLD2OJi78sNN5NulOsJZl7Ei4F1EUYItGG6eUsKWULc="; 8 + stripRoot = false; 9 + }; 10 + 11 + prebuilt_libs = fetchzip { 12 + url = "https://android.googlesource.com/platform/prebuilts/ndk/+archive/f2c77d8ba8a7f5c2d91771e31164f29be0b8ff98/platform/platforms/android-30/arch-arm64/usr/lib.tar.gz"; 13 + sha256 = "sha256-TZBV7+D1QvKOCEi+VNGT5SStkgj0xRbyWoLH65zSrjw="; 14 + stripRoot = false; 15 + }; 16 + 17 + prebuilt_ndk_crt = fetchzip { 18 + url = "https://android.googlesource.com/toolchain/prebuilts/ndk/r23/+archive/6c5fa4c0d3999b9ee932f6acbd430eb2f31f3151/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/30.tar.gz"; 19 + sha256 = "sha256-KHw+cCwAwlm+5Nwp1o8WONqdi4BBDhFaVVr+7GxQ5uE="; 20 + stripRoot = false; 21 + }; 22 + 23 + ndk_support_headers = fetchzip { 24 + url ="https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+archive/0e7f808fa26cce046f444c9616d9167dafbfb272/clang-r416183b/include/c++/v1/support.tar.gz"; 25 + sha256 = "sha256-NBv7Pk1CEaz8ns9moleEERr3x/rFmVmG33LgFSeO6fY="; 26 + stripRoot = false; 27 + }; 28 + 29 + kernelHeaders = pkgs.makeLinuxHeaders { 30 + version = "android-common-11-5.4"; 31 + src = fetchurl { 32 + url = "https://android.googlesource.com/kernel/common/+archive/48ffcbf0b9e7f0280bfb8c32c68da0aaf0fdfef6.tar.gz"; 33 + sha256 = "0ksm1243zm9hsv0a6q9v15jabf2rivsn14kmnm2qw6zk3mjd4jvv"; 34 + }; 35 + }; 36 + 37 + in 38 + stdenvNoCC.mkDerivation rec { 39 + pname = "bionic-prebuilt"; 40 + version = "ndk-release-r23"; 41 + 42 + src = fetchurl { 43 + url = "https://android.googlesource.com/platform/bionic/+archive/00e8ce1142d8823b0d2fc8a98b40119b0f1f02cd.tar.gz"; 44 + sha256 = "0cfkwdcb2c9nnlmkx0inbsja3cyiha71nj92lm66m5an70zc3b8q"; 45 + }; 46 + 47 + sourceRoot = "."; 48 + 49 + NIX_DONT_SET_RPATH = true; 50 + 51 + dontConfigure = true; 52 + dontBuild = true; 53 + 54 + patches = [ 55 + ./ndk-version.patch 56 + ]; 57 + 58 + postPatch = '' 59 + substituteInPlace libc/include/sys/cdefs.h --replace \ 60 + "__has_builtin(__builtin_umul_overflow)" "1" 61 + substituteInPlace libc/include/bits/ioctl.h --replace \ 62 + "!defined(BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD)" "0" 63 + ''; 64 + 65 + installPhase= '' 66 + # copy the bionic headers 67 + mkdir -p $out/include/support $out/include/android 68 + cp -vr libc/include/* $out/include 69 + # copy the kernel headers 70 + cp -vr ${kernelHeaders}/include/* $out/include/ 71 + 72 + chmod -R +w $out/include/linux 73 + 74 + # fix a bunch of kernel headers so that things can actually be found 75 + sed -i 's,struct epoll_event {,#include <bits/epoll_event.h>\nstruct Xepoll_event {,' $out/include/linux/eventpoll.h 76 + sed -i 's,struct in_addr {,typedef unsigned int in_addr_t;\nstruct in_addr {,' $out/include/linux/in.h 77 + sed -i 's,struct udphdr {,struct Xudphdr {,' $out/include/linux/udp.h 78 + sed -i 's,union semun {,union Xsemun {,' $out/include/linux/sem.h 79 + sed -i 's,struct __kernel_sockaddr_storage,#define sockaddr_storage __kernel_sockaddr_storage\nstruct __kernel_sockaddr_storage,' $out/include/linux/socket.h 80 + sed -i 's,#ifndef __UAPI_DEF_.*$,#if 1,' $out/include/linux/libc-compat.h 81 + substituteInPlace $out/include/linux/in.h --replace "__be32 imr_" "struct in_addr imr_" 82 + substituteInPlace $out/include/linux/in.h --replace "__be32 imsf_" "struct in_addr imsf_" 83 + substituteInPlace $out/include/linux/sysctl.h --replace "__unused" "_unused" 84 + 85 + # what could possibly live in <linux/compiler.h> 86 + touch $out/include/linux/compiler.h 87 + 88 + # copy the support headers 89 + cp -vr ${ndk_support_headers}* $out/include/support/ 90 + 91 + mkdir $out/lib 92 + cp -v ${prebuilt_crt.out}/*.o $out/lib/ 93 + cp -v ${prebuilt_crt.out}/libgcc.a $out/lib/ 94 + cp -v ${prebuilt_ndk_crt.out}/*.o $out/lib/ 95 + for i in libc.so libm.so libdl.so liblog.so; do 96 + cp -v ${prebuilt_libs.out}/$i $out/lib/ 97 + done 98 + 99 + mkdir -p $dev/include 100 + cp -v $out/include/*.h $dev/include/ 101 + ''; 102 + 103 + outputs = [ "out" "dev" ]; 104 + passthru.linuxHeaders = kernelHeaders; 105 + 106 + meta = with lib; { 107 + description = "The Android libc implementation"; 108 + homepage = "https://android.googlesource.com/platform/bionic/"; 109 + license = licenses.mit; 110 + platforms = platforms.linux; 111 + maintainers = with maintainers; [ s1341 ]; 112 + }; 113 + }
+42
pkgs/os-specific/linux/bionic-prebuilt/ndk-version.patch
··· 1 + --- a/libc/include/android/ndk-version.h 2021-04-01 16:08:03.109183965 +0300 2 + +++ b/libc/include/android/ndk-version.h 2021-04-01 16:07:19.811424641 +0300 3 + @@ -0,0 +1,39 @@ 4 + +#pragma once 5 + + 6 + +/** 7 + + * Set to 1 if this is an NDK, unset otherwise. See 8 + + * https://android.googlesource.com/platform/bionic/+/master/docs/defines.md. 9 + + */ 10 + +#define __ANDROID_NDK__ 1 11 + + 12 + +/** 13 + + * Major version of this NDK. 14 + + * 15 + + * For example: 16 for r16. 16 + + */ 17 + +#define __NDK_MAJOR__ 22 18 + + 19 + +/** 20 + + * Minor version of this NDK. 21 + + * 22 + + * For example: 0 for r16 and 1 for r16b. 23 + + */ 24 + +#define __NDK_MINOR__ 0 25 + + 26 + +/** 27 + + * Set to 0 if this is a release build, or 1 for beta 1, 28 + + * 2 for beta 2, and so on. 29 + + */ 30 + +#define __NDK_BETA__ 0 31 + + 32 + +/** 33 + + * Build number for this NDK. 34 + + * 35 + + * For a local development build of the NDK, this is -1. 36 + + */ 37 + +#define __NDK_BUILD__ 7026061 38 + + 39 + +/** 40 + + * Set to 1 if this is a canary build, 0 if not. 41 + + */ 42 + +#define __NDK_CANARY__ 0
+18 -4
pkgs/os-specific/linux/kernel-headers/default.nix
··· 1 - { stdenvNoCC, lib, buildPackages, fetchurl, perl, elf-header }: 1 + { stdenvNoCC, lib, buildPackages, fetchurl, perl, elf-header 2 + , bison ? null, flex ? null, python ? null, rsync ? null 3 + }: 4 + 5 + assert stdenvNoCC.hostPlatform.isAndroid -> 6 + (flex != null && bison != null && python != null && rsync != null); 2 7 3 8 let 4 9 makeLinuxHeaders = { src, version, patches ? [] }: stdenvNoCC.mkDerivation { ··· 13 18 # We do this so we have a build->build, not build->host, C compiler. 14 19 depsBuildBuild = [ buildPackages.stdenv.cc ]; 15 20 # `elf-header` is null when libc provides `elf.h`. 16 - nativeBuildInputs = [ perl elf-header ]; 21 + nativeBuildInputs = [ 22 + perl elf-header 23 + ] ++ lib.optionals stdenvNoCC.hostPlatform.isAndroid [ 24 + flex bison python rsync 25 + ]; 17 26 18 27 extraIncludeDirs = lib.optional stdenvNoCC.hostPlatform.isPowerPC ["ppc"]; 19 28 20 29 inherit patches; 21 30 22 31 hardeningDisable = lib.optional stdenvNoCC.buildPlatform.isDarwin "format"; 32 + 33 + sourceRoot = lib.optionalString stdenvNoCC.hostPlatform.isAndroid "."; 23 34 24 35 makeFlags = [ 25 36 "SHELL=bash" ··· 36 47 # Skip clean on darwin, case-sensitivity issues. 37 48 buildPhase = lib.optionalString (!stdenvNoCC.buildPlatform.isDarwin) '' 38 49 make mrproper $makeFlags 39 - '' + '' 50 + '' + (if stdenvNoCC.hostPlatform.isAndroid then '' 51 + make defconfig 52 + make headers_install 53 + '' else '' 40 54 make headers $makeFlags 41 - ''; 55 + ''); 42 56 43 57 checkPhase = '' 44 58 make headers_check $makeFlags
+7 -3
pkgs/top-level/all-packages.nix
··· 11176 11176 llvmPackages_7 11177 11177 else if isFreeBSD then 11178 11178 llvmPackages_7 11179 + else if isAndroid then 11180 + llvmPackages_12 11179 11181 else if isLinux then 11180 11182 llvmPackages_7 11181 11183 else if isWasm then ··· 14046 14048 bicgl = callPackage ../development/libraries/science/biology/bicgl { }; 14047 14049 14048 14050 # TODO(@Ericson2314): Build bionic libc from source 14049 - bionic = assert stdenv.hostPlatform.useAndroidPrebuilt; 14050 - pkgs."androidndkPkgs_${stdenv.hostPlatform.ndkVer}".libraries; 14051 + bionic = if stdenv.hostPlatform.useAndroidPrebuilt 14052 + then pkgs."androidndkPkgs_${stdenv.hostPlatform.ndkVer}".libraries 14053 + else callPackage ../os-specific/linux/bionic-prebuilt { }; 14054 + 14051 14055 14052 14056 bobcat = callPackage ../development/libraries/bobcat { }; 14053 14057 ··· 20049 20053 lkl = callPackage ../applications/virtualization/lkl { }; 20050 20054 20051 20055 inherit (callPackages ../os-specific/linux/kernel-headers { }) 20052 - linuxHeaders; 20056 + linuxHeaders makeLinuxHeaders; 20053 20057 20054 20058 kernelPatches = callPackage ../os-specific/linux/kernel/patches.nix { }; 20055 20059