diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 2a88e3369a99..345aaa71cf78 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -363,6 +363,22 @@ let else targetPlatform.darwinPlatform ); + + # Header files that use `__FILE__` (e.g., for error reporting) lead + # to unwanted references to development packages and outputs in built + # binaries, like C++ programs depending on GCC and Boost at runtime. + # + # We use `-fmacro-prefix-map` to avoid the store references in these + # situations while keeping them in compiler diagnostics and debugging + # and profiling output. + # + # Unfortunately, doing this with GCC runs into issues with compiler + # argument length limits due to , so we + # disable it there in favour of our existing patch. + # + # TODO: Drop `mangle-NIX_STORE-in-__FILE__.patch` from GCC and make + # this unconditional once the upstream bug is fixed. + useMacroPrefixMap = !isGNU; in assert includeFortifyHeaders' -> fortify-headers != null; @@ -455,6 +471,14 @@ stdenvNoCC.mkDerivation { substituteAll "$wrapper" "$out/bin/$dst" chmod +x "$out/bin/$dst" } + + include() { + printf -- '%s %s\n' "$1" "$2" + ${lib.optionalString useMacroPrefixMap '' + local scrubbed="$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-''${2#"$NIX_STORE"/*-}" + printf -- '-fmacro-prefix-map=%s=%s\n' "$2" "$scrubbed" + ''} + } '' + ( @@ -673,13 +697,13 @@ stdenvNoCC.mkDerivation { echo "-B${libc_lib}${libc.libdir or "/lib/"}" >> $out/nix-support/libc-crt1-cflags '' + optionalString (!(cc.langD or false)) '' - echo "-${ + include "-${ if isArocc then "I" else "idirafter" - } ${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags + }" "${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags '' + optionalString (isGNU && (!(cc.langD or false))) '' for dir in "${cc}"/lib/gcc/*/*/include-fixed; do - echo '-idirafter' ''${dir} >> $out/nix-support/libc-cflags + include '-idirafter' ''${dir} >> $out/nix-support/libc-cflags done '' + '' @@ -695,7 +719,7 @@ stdenvNoCC.mkDerivation { # like option that forces the libc headers before all -idirafter, # hence -isystem here. + optionalString includeFortifyHeaders' '' - echo "-isystem ${fortify-headers}/include" >> $out/nix-support/libc-cflags + include -isystem "${fortify-headers}/include" >> $out/nix-support/libc-cflags '' ) @@ -718,19 +742,19 @@ stdenvNoCC.mkDerivation { # https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903) + optionalString (libcxx == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) '' for dir in ${gccForLibs}/include/c++/*; do - echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags + include -isystem "$dir" >> $out/nix-support/libcxx-cxxflags done for dir in ${gccForLibs}/include/c++/*/${targetPlatform.config}; do - echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags + include -isystem "$dir" >> $out/nix-support/libcxx-cxxflags done '' + optionalString (libcxx.isLLVM or false) '' - echo "-isystem ${getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags + include -isystem "${getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags '' # GCC NG friendly libc++ + optionalString (libcxx != null && libcxx.isGNU or false) '' - echo "-isystem ${getDev libcxx}/include" >> $out/nix-support/libcxx-cxxflags + include -isystem "${getDev libcxx}/include" >> $out/nix-support/libcxx-cxxflags '' ## @@ -937,6 +961,7 @@ stdenvNoCC.mkDerivation { inherit libc_bin libc_dev libc_lib; inherit darwinPlatformForCC; default_hardening_flags_str = builtins.toString defaultHardeningFlags; + inherit useMacroPrefixMap; } // lib.mapAttrs (_: lib.optionalString targetPlatform.isDarwin) { # These will become empty strings when not targeting Darwin. diff --git a/pkgs/build-support/cc-wrapper/setup-hook.sh b/pkgs/build-support/cc-wrapper/setup-hook.sh index 33a2b62a49b0..1c8b26061b03 100644 --- a/pkgs/build-support/cc-wrapper/setup-hook.sh +++ b/pkgs/build-support/cc-wrapper/setup-hook.sh @@ -68,12 +68,21 @@ ccWrapper_addCVars () { local role_post getHostRoleEnvHook + local found= + if [ -d "$1/include" ]; then export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include" + found=1 fi if [ -d "$1/Library/Frameworks" ]; then export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks" + found=1 + fi + + if [[ -n "@useMacroPrefixMap@" && -n ${NIX_STORE:-} && -n $found ]]; then + local scrubbed="$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${1#"$NIX_STORE"/*-}" + export NIX_CFLAGS_COMPILE${role_post}+=" -fmacro-prefix-map=$1=$scrubbed" fi } diff --git a/pkgs/development/compilers/gcc/patches/default.nix b/pkgs/development/compilers/gcc/patches/default.nix index 9a55332ade9b..dc6418c9241b 100644 --- a/pkgs/development/compilers/gcc/patches/default.nix +++ b/pkgs/development/compilers/gcc/patches/default.nix @@ -83,6 +83,10 @@ in # Do not try looking for binaries and libraries in /lib and /usr/lib ./13/no-sys-dirs-riscv.patch # Mangle the nix store hash in __FILE__ to prevent unneeded runtime references + # + # TODO: Remove these and the `useMacroPrefixMap` conditional + # in `cc-wrapper` once + # is fixed. ./13/mangle-NIX_STORE-in-__FILE__.patch ]; "14" = [