cc-wrapper: use -fmacro-prefix-map to scrub __FILE__ references

This accomplishes the same thing as `sanitiseHeaderPathsHook`, but
applies to every build input and should have fewer side effects.
This commit is contained in:
Emily
2025-07-29 18:32:43 +01:00
parent 8d3f059d13
commit a413c6f5b4
3 changed files with 46 additions and 8 deletions
+33 -8
View File
@@ -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 <https://gcc.gnu.org/PR111527>, 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.
@@ -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
}
@@ -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 <https://gcc.gnu.org/PR111527>
# is fixed.
./13/mangle-NIX_STORE-in-__FILE__.patch
];
"14" = [