diff options
Diffstat (limited to 'pkgs/build-support/cc-wrapper/default.nix')
-rw-r--r-- | pkgs/build-support/cc-wrapper/default.nix | 124 |
1 files changed, 93 insertions, 31 deletions
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 6ee287e287b..235d244a7c0 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -6,6 +6,7 @@ # compiler and the linker just "work". { name ? "" +, lib , stdenvNoCC , cc ? null, libc ? null, bintools, coreutils ? null, shell ? stdenvNoCC.shell , gccForLibs ? null @@ -18,7 +19,7 @@ , libcxx ? null }: -with stdenvNoCC.lib; +with lib; assert nativeTools -> !propagateDoc && nativePrefix != ""; assert !nativeTools -> @@ -34,11 +35,11 @@ let # # TODO(@Ericson2314) Make unconditional, or optional but always true by # default. - targetPrefix = stdenv.lib.optionalString (targetPlatform != hostPlatform) + targetPrefix = lib.optionalString (targetPlatform != hostPlatform) (targetPlatform.config + "-"); - ccVersion = stdenv.lib.getVersion cc; - ccName = stdenv.lib.removePrefix targetPrefix (stdenv.lib.getName cc); + ccVersion = lib.getVersion cc; + ccName = lib.removePrefix targetPrefix (lib.getName cc); libc_bin = if libc == null then null else getBin libc; libc_dev = if libc == null then null else getDev libc; @@ -57,29 +58,61 @@ let suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config; expand-response-params = - if buildPackages.stdenv.hasCC && buildPackages.stdenv.cc != "/dev/null" + if (buildPackages.stdenv.hasCC or false) && buildPackages.stdenv.cc != "/dev/null" then import ../expand-response-params { inherit (buildPackages) stdenv; } else ""; + useGccForLibs = isClang + && libcxx == null + && !stdenv.targetPlatform.isDarwin + && !(stdenv.targetPlatform.useLLVM or false) + && !(stdenv.targetPlatform.useAndroidPrebuilt or false) + && !(stdenv.targetPlatform.isiOS or false) + && gccForLibs != null; + # older compilers (for example bootstrap's GCC 5) fail with -march=too-modern-cpu isGccArchSupported = arch: if isGNU then - { skylake = versionAtLeast ccVersion "6.0"; + { # Intel + skylake = versionAtLeast ccVersion "6.0"; skylake-avx512 = versionAtLeast ccVersion "6.0"; cannonlake = versionAtLeast ccVersion "8.0"; icelake-client = versionAtLeast ccVersion "8.0"; icelake-server = versionAtLeast ccVersion "8.0"; + cascadelake = versionAtLeast ccVersion "9.0"; + cooperlake = versionAtLeast ccVersion "10.0"; + tigerlake = versionAtLeast ccVersion "10.0"; knm = versionAtLeast ccVersion "8.0"; + # AMD + znver1 = versionAtLeast ccVersion "6.0"; + znver2 = versionAtLeast ccVersion "9.0"; + znver3 = versionAtLeast ccVersion "11.0"; }.${arch} or true else if isClang then - { cannonlake = versionAtLeast ccVersion "5.0"; + { # Intel + cannonlake = versionAtLeast ccVersion "5.0"; icelake-client = versionAtLeast ccVersion "7.0"; icelake-server = versionAtLeast ccVersion "7.0"; knm = versionAtLeast ccVersion "7.0"; + # AMD + znver1 = versionAtLeast ccVersion "4.0"; + znver2 = versionAtLeast ccVersion "9.0"; }.${arch} or true else false; + + darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin ( + if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" + else targetPlatform.darwinPlatform + ); + + darwinMinVersion = optionalString stdenv.targetPlatform.isDarwin ( + stdenv.targetPlatform.darwinMinVersion + ); + + darwinMinVersionVariable = optionalString stdenv.targetPlatform.isDarwin + stdenv.targetPlatform.darwinMinVersionVariable; in # Ensure bintools matches @@ -102,6 +135,7 @@ stdenv.mkDerivation { gnugrep_bin = if nativeTools then "" else gnugrep; inherit targetPrefix suffixSalt; + inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ]; @@ -140,6 +174,7 @@ stdenv.mkDerivation { local dst="$1" local wrapper="$2" export prog="$3" + export use_response_file_by_default=${if isClang then "1" else "0"} substituteAll "$wrapper" "$out/bin/$dst" chmod +x "$out/bin/$dst" } @@ -228,8 +263,8 @@ stdenv.mkDerivation { setupHooks = [ ../setup-hooks/role.bash - ] ++ stdenv.lib.optional (cc.langC or true) ./setup-hook.sh - ++ stdenv.lib.optional (cc.langFortran or false) ./fortran-hook.sh; + ] ++ lib.optional (cc.langC or true) ./setup-hook.sh + ++ lib.optional (cc.langFortran or false) ./fortran-hook.sh; postFixup = # Ensure flags files exists, as some other programs cat them. (That these @@ -264,13 +299,28 @@ stdenv.mkDerivation { ## ## GCC libs for non-GCC support ## - + optionalString (isClang && libcxx == null && !(stdenv.targetPlatform.useLLVM or false) && gccForLibs != null) '' + + optionalString useGccForLibs '' echo "-B${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-cflags echo "-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-ldflags echo "-L${gccForLibs.lib}/${targetPlatform.config}/lib" >> $out/nix-support/cc-ldflags '' + # TODO We would like to connect this to `useGccForLibs`, but we cannot yet + # because `libcxxStdenv` on linux still needs this. Maybe someday we'll + # always set `useLLVM` on Darwin, and maybe also break down `useLLVM` into + # fine-grained use flags (libgcc vs compiler-rt, ld.lld vs legacy, libc++ + # vs libstdc++, etc.) since Darwin isn't `useLLVM` on all counts. (See + # https://clang.llvm.org/docs/Toolchain.html for all the axes one might + # break `useLLVM` into.) + + optionalString (isClang + && targetPlatform.isLinux + && !(stdenv.targetPlatform.useAndroidPrebuilt or false) + && !(stdenv.targetPlatform.useLLVM or false) + && gccForLibs != null) '' + echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags + '' + ## ## General libc support ## @@ -308,11 +358,11 @@ stdenv.mkDerivation { # We have a libc++ directly, we have one via "smuggled" GCC, or we have one # bundled with the C compiler because it is GCC - + optionalString (libcxx != null || (isClang && !(stdenv.targetPlatform.useLLVM or false) && gccForLibs.langCC or false) || (isGNU && cc.langCC or false)) '' + + optionalString (libcxx != null || (useGccForLibs && gccForLibs.langCC or false) || (isGNU && cc.langCC or false)) '' touch "$out/nix-support/libcxx-cxxflags" touch "$out/nix-support/libcxx-ldflags" '' - + optionalString (libcxx == null && (isClang && !(stdenv.targetPlatform.useLLVM or false) && gccForLibs.langCC or false)) '' + + optionalString (libcxx == null && (useGccForLibs && gccForLibs.langCC or false)) '' for dir in ${gccForLibs}/include/c++/*; do echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags done @@ -321,9 +371,9 @@ stdenv.mkDerivation { done '' + optionalString (libcxx.isLLVM or false) ('' - echo "-isystem ${libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags + echo "-isystem ${lib.getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags - '' + stdenv.lib.optionalString stdenv.targetPlatform.isLinux '' + '' + lib.optionalString stdenv.targetPlatform.isLinux '' echo "-lc++abi" >> $out/nix-support/libcxx-ldflags '') @@ -355,7 +405,7 @@ stdenv.mkDerivation { echo "$ccLDFlags" >> $out/nix-support/cc-ldflags echo "$ccCFlags" >> $out/nix-support/cc-cflags '' + optionalString (targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) '' - echo " -L${libcxx}/lib" >> $out/nix-support/cc-ldflags + echo " -L${lib.getLib libcxx}/lib" >> $out/nix-support/cc-ldflags '' ## @@ -383,32 +433,34 @@ stdenv.mkDerivation { # Always add -march based on cpu in triple. Sometimes there is a # discrepency (x86_64 vs. x86-64), so we provide an "arch" arg in # that case. - + optionalString ((targetPlatform ? platform.gcc.arch) && - isGccArchSupported targetPlatform.platform.gcc.arch) '' - echo "-march=${targetPlatform.platform.gcc.arch}" >> $out/nix-support/cc-cflags-before + # TODO: aarch64-darwin has mcpu incompatible with gcc + + optionalString ((targetPlatform ? gcc.arch) && (isClang || !(stdenv.isDarwin && stdenv.isAarch64)) && + isGccArchSupported targetPlatform.gcc.arch) '' + echo "-march=${targetPlatform.gcc.arch}" >> $out/nix-support/cc-cflags-before '' # -mcpu is not very useful. You should use mtune and march # instead. It’s provided here for backwards compatibility. - + optionalString (targetPlatform ? platform.gcc.cpu) '' - echo "-mcpu=${targetPlatform.platform.gcc.cpu}" >> $out/nix-support/cc-cflags-before + # TODO: aarch64-darwin has mcpu incompatible with gcc + + optionalString ((targetPlatform ? gcc.cpu) && (isClang || !(stdenv.isDarwin && stdenv.isAarch64))) '' + echo "-mcpu=${targetPlatform.gcc.cpu}" >> $out/nix-support/cc-cflags-before '' # -mfloat-abi only matters on arm32 but we set it here # unconditionally just in case. If the abi specifically sets hard # vs. soft floats we use it here. - + optionalString (targetPlatform ? platform.gcc.float-abi) '' - echo "-mfloat-abi=${targetPlatform.platform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.float-abi) '' + echo "-mfloat-abi=${targetPlatform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.fpu) '' - echo "-mfpu=${targetPlatform.platform.gcc.fpu}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.fpu) '' + echo "-mfpu=${targetPlatform.gcc.fpu}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.mode) '' - echo "-mmode=${targetPlatform.platform.gcc.mode}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.mode) '' + echo "-mmode=${targetPlatform.gcc.mode}" >> $out/nix-support/cc-cflags-before '' - + optionalString (targetPlatform ? platform.gcc.tune && - isGccArchSupported targetPlatform.platform.gcc.tune) '' - echo "-mtune=${targetPlatform.platform.gcc.tune}" >> $out/nix-support/cc-cflags-before + + optionalString (targetPlatform ? gcc.tune && + isGccArchSupported targetPlatform.gcc.tune) '' + echo "-mtune=${targetPlatform.gcc.tune}" >> $out/nix-support/cc-cflags-before '' # TODO: categorize these and figure out a better place for them @@ -420,10 +472,12 @@ stdenv.mkDerivation { hardening_unsupported_flags+=" stackprotector pic" '' + optionalString (targetPlatform.libc == "newlib") '' hardening_unsupported_flags+=" stackprotector fortify pie pic" + '' + optionalString (targetPlatform.libc == "musl" && targetPlatform.isx86_32) '' + hardening_unsupported_flags+=" stackprotector" '' + optionalString targetPlatform.isNetBSD '' hardening_unsupported_flags+=" stackprotector fortify" '' + optionalString cc.langAda or false '' - hardening_unsupported_flags+=" stackprotector strictoverflow" + hardening_unsupported_flags+=" format stackprotector strictoverflow" '' + optionalString cc.langD or false '' hardening_unsupported_flags+=" format" '' + optionalString targetPlatform.isWasm '' @@ -436,6 +490,14 @@ stdenv.mkDerivation { done '' + + optionalString stdenv.targetPlatform.isDarwin '' + echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags + '' + + + optionalString targetPlatform.isAndroid '' + echo "-D__ANDROID_API__=${targetPlatform.sdkVer}" >> $out/nix-support/cc-cflags + '' + # There are a few tools (to name one libstdcxx5) which do not work # well with multi line flags, so make the flags single line again + '' @@ -462,7 +524,7 @@ stdenv.mkDerivation { let cc_ = if cc != null then cc else {}; in (if cc_ ? meta then removeAttrs cc.meta ["priority"] else {}) // { description = - stdenv.lib.attrByPath ["meta" "description"] "System C compiler" cc_ + lib.attrByPath ["meta" "description"] "System C compiler" cc_ + " (wrapper script)"; priority = 10; }; |