maint: Ask GCC for system headers

In the previous update commit, the Nix `cc.version` didn't match the
in-output directory name anymore, causing a build failure.

By asking GCC properly, we are robust against such discrepancies.

The script isn't great, relying on GCC "log" output specifics, but it
seems that the GCC output has been like this for a while, and the
lines before and after seem to be intentional about their purpose...

(cherry picked from commit 68f928555660cb914105b0ad668d6cadc25223e9)
This commit is contained in:
Robert Hensing 2025-01-08 11:14:09 +01:00
parent d693957c1a
commit 32136109fc
3 changed files with 28 additions and 8 deletions

View file

@ -36,7 +36,7 @@
inputsFrom = [ config.nci.outputs.nix-bindings.devShell ];
inherit (config.nci.outputs.nix-bindings.devShell.env)
LIBCLANG_PATH
BINDGEN_EXTRA_CLANG_ARGS
NIX_CC_UNWRAPPED
;
NIX_DEBUG_INFO_DIRS =
let
@ -66,6 +66,7 @@
];
shellHook = ''
${config.pre-commit.installationScript}
source ${../rust/bindgen-gcc.sh}
echo 1>&2 "Welcome to the development shell!"
'';
# rust-analyzer needs a NIX_PATH for some reason

18
rust/bindgen-gcc.sh Normal file
View file

@ -0,0 +1,18 @@
# Rust bindgen uses Clang to generate bindings, but that means that it can't
# find the "system" or compiler headers when the stdenv compiler is GCC.
# This script tells it where to find them.
echo "Extending BINDGEN_EXTRA_CLANG_ARGS with system include paths..." 2>&1
BINDGEN_EXTRA_CLANG_ARGS="''${BINDGEN_EXTRA_CLANG_ARGS:-}"
export BINDGEN_EXTRA_CLANG_ARGS
include_paths=$(
echo | $NIX_CC_UNWRAPPED -v -E -x c - 2>&1 \
| awk '/#include <...> search starts here:/{flag=1;next} \
/End of search list./{flag=0} \
flag==1 {print $1}'
)
for path in $include_paths; do
echo " - $path" 2>&1
BINDGEN_EXTRA_CLANG_ARGS="$BINDGEN_EXTRA_CLANG_ARGS -I$path"
done

View file

@ -13,6 +13,11 @@
nativeBuildInputs = [
pkgs.pkg-config
];
# bindgen uses clang to generate bindings, but it doesn't know where to
# find our stdenv cc's headers, so when it's gcc, we need to tell it.
postConfigure = lib.optionalString pkgs.stdenv.cc.isGNU ''
source ${./bindgen-gcc.sh}
'';
# Prepare the environment for Nix to work.
# Nix does not provide a suitable environment for running itself in
# the sandbox - not by default. We configure it to use a relocated store.
@ -46,13 +51,9 @@
null # don't set the variable
else
lib.makeLibraryPath [ pkgs.buildPackages.llvmPackages.clang-unwrapped ];
BINDGEN_EXTRA_CLANG_ARGS =
if pkgs.stdenv.cc.isClang then
null # don't set the variable
else
"-I${pkgs.stdenv.cc.libc.dev}/include"
+ " -I${lib.getDev pkgs.stdenv.cc.cc}/lib/gcc/${pkgs.stdenv.hostPlatform.config}/${pkgs.stdenv.cc.cc.version}/include"
;
} // lib.optionalAttrs pkgs.stdenv.cc.isGNU {
# Avoid cc wrapper, because we only need to add the compiler/"system" dirs
NIX_CC_UNWRAPPED = "${pkgs.stdenv.cc.cc}/bin/gcc";
};
};
};