Describe the bug
When cross-compiling back to the same platform, such as with pkgsLLVM.buildPackages.gcc, GCC can't find its own libstdc++ headers. If I look at pkgsLLVM.buildPackages.gcc.cc the include/ folder is empty and the libstdc++ headers are instead found in x86_64-unknown-linux-gnu/include/c++/12.3.0/. However, GCC doesn't actually look there. If I ask GCC to print its include paths with echo | result/bin/x86_64-unknown-linux-gnu-g++ -xc++ -E -v - it says
ignoring nonexistent directory "/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0"
ignoring nonexistent directory "/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0/x86_64-unknown-linux-gnu"
ignoring nonexistent directory "/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0/backward"
#include "..." search starts here:
#include <...> search starts here:
/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/include
/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/include
/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/include-fixed
/nix/store/5wpf3nsdgdqfg2kxwb605sjc4gjqxi1h-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../x86_64-unknown-linux-gnu/include
/nix/store/c35ndrdaral7brqky6nrgkyni6aic5ar-glibc-x86_64-unknown-linux-gnu-2.37-8-dev/include
End of search list.
When I compare this with a non-cross-compiled gcc the headers are all in include/c++/12.3.0/ and the same command prints
ignoring nonexistent directory "/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0/x86_64-unknown-linux-gnu
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/../../../../include/c++/12.3.0/backward
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/include
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/include
/nix/store/n8dryz4xf7ln028j37zapgzg4j47p743-gcc-12.3.0/lib/gcc/x86_64-unknown-linux-gnu/12.3.0/include-fixed
/nix/store/4lap45ifj50lp980id60fnbvs81yj9lr-glibc-2.37-8-dev/include
End of search list.
Steps To Reproduce
Working example:
echo '#include <iostream>' | nix shell nixpkgs/5ba549eafcf3e33405e5f66decd1a72356632b96#gcc.cc -c x86_64-unknown-linux-gnu-g++ -xc++ -E -
That should print the contents of the iostream header.
Broken example:
echo '#include <iostream>' | nix shell nixpkgs/5ba549eafcf3e33405e5f66decd1a72356632b96#pkgsLLVM.buildPackages.gcc.cc -c x86_64-unknown-linux-gnu-g++ -xc++ -E -
This produces the following:
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/nix/store/c35ndrdaral7brqky6nrgkyni6aic5ar-glibc-x86_64-unknown-linux-gnu-2.37-8-dev/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "<stdin>"
<stdin>:1:10: fatal error: iostream: No such file or directory
compilation terminated.
Additional context
I don't know if the problem is that the headers are in the wrong place, or if GCC is looking in the wrong place. It seems reasonable for GCC to conclude that because the target platform config matches the host platform config that it doesn't need the target-prefixed path, but I haven't managed to find any code on the Nix side that moves the includes so I think the GCC build process is putting them there and then forgetting about it.
My example here uses pkgsLLVM for convenience, but in my actual code I'm using cross-compiling with a different dummy crossSystem key in order to replace glibc using crossOverlays.
Notify maintainers
@Synthetica9 @vcunat @Ericson2314
Metadata
Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.
❯ nix run nixpkgs#nix-info -- -m
- system: `"x86_64-linux"`
- host os: `Linux 6.1.51, NixOS, 23.11 (Tapir), 23.11.20230919.5ba549e`
- multi-user?: `yes`
- sandbox: `yes`
- version: `nix-env (Nix) 2.17.0`
- nixpkgs: `/etc/nix/inputs/nixpkgs`
Describe the bug
When cross-compiling back to the same platform, such as with
pkgsLLVM.buildPackages.gcc, GCC can't find its own libstdc++ headers. If I look atpkgsLLVM.buildPackages.gcc.cctheinclude/folder is empty and the libstdc++ headers are instead found inx86_64-unknown-linux-gnu/include/c++/12.3.0/. However, GCC doesn't actually look there. If I ask GCC to print its include paths withecho | result/bin/x86_64-unknown-linux-gnu-g++ -xc++ -E -v -it saysWhen I compare this with a non-cross-compiled gcc the headers are all in
include/c++/12.3.0/and the same command printsSteps To Reproduce
Working example:
That should print the contents of the iostream header.
Broken example:
This produces the following:
Additional context
I don't know if the problem is that the headers are in the wrong place, or if GCC is looking in the wrong place. It seems reasonable for GCC to conclude that because the target platform config matches the host platform config that it doesn't need the target-prefixed path, but I haven't managed to find any code on the Nix side that moves the includes so I think the GCC build process is putting them there and then forgetting about it.
My example here uses
pkgsLLVMfor convenience, but in my actual code I'm using cross-compiling with a different dummycrossSystemkey in order to replace glibc usingcrossOverlays.Notify maintainers
@Synthetica9 @vcunat @Ericson2314
Metadata
Please run
nix-shell -p nix-info --run "nix-info -m"and paste the result.