From 32136109fc99c1e362cc150e11f683c3e87b3483 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 8 Jan 2025 11:14:09 +0100 Subject: [PATCH] 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) --- dev/flake-module.nix | 3 ++- rust/bindgen-gcc.sh | 18 ++++++++++++++++++ rust/nci.nix | 15 ++++++++------- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 rust/bindgen-gcc.sh diff --git a/dev/flake-module.nix b/dev/flake-module.nix index 1f07ecb..ca5df3a 100644 --- a/dev/flake-module.nix +++ b/dev/flake-module.nix @@ -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 diff --git a/rust/bindgen-gcc.sh b/rust/bindgen-gcc.sh new file mode 100644 index 0000000..d904b61 --- /dev/null +++ b/rust/bindgen-gcc.sh @@ -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 diff --git a/rust/nci.nix b/rust/nci.nix index 08edb9f..25c7dfc 100644 --- a/rust/nci.nix +++ b/rust/nci.nix @@ -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"; }; }; };