-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GCC stdenv broken when cross-compiling to same system and depsBuildBuild
contains buildPackages.stdenv.cc
#265121
Comments
I think this is a duplicate of There is a test case for that bug in and a fix in |
This comment was marked as outdated.
This comment was marked as outdated.
See |
BTW it is not your fault for not noticing this. The splicing mechanism in nixpkgs is simply batshit-insane. I've given up on trying to rally support for replacing/removing it, and am settling for adding warnings (e.g. #265121) to all the situations where it does things that are totally unexpected. |
I'm not doing it, packages I'm trying to use are doing it (such as ncurses). Also this approach is documented in the manual. Regarding 1c85a4c0272e2c4a63f82813953642abc5cdc37c, won't setting Incidentally, you kept linking this issue instead of the PR you're talking about that adds warnings. |
Actually I think I overcomplicated it. Using All that said, changing the dependency from the compiler to all of |
The splicing thing is a complete red herring. Using |
Describe the bug
If I have a package that is configured with
depsBuildBuild = [ buildPackages.stdenv.cc ]
, this package will fail to compile when building with the GCC stdenv and cross-compiling back to the same system. The simplest way to see this is to build something that usesgccStdenv
in thepkgsLLVM
set, such aspkgsLLVM.kexec-tools
, but this will affect other packages too (such asncurses
) if I do a custom cross-compile setup likeThe rationale for such a setup is I'm using
crossOverlays
to swap outglibc
for the host system, and I need thecrossSystem
definition or stdenv just uses the stage 2glibc
instead.The root cause seems to be that unwrapped GCC always includes target-prefixed binaries even when not cross-compiling.
A quick grep through nixpkgs suggests this issue will affect close to 100 derivations.
Steps To Reproduce
Build log
If I keep the failed build and inspect the resulting
config.log
file it fails atI dug into what's going on here and the problem is that the
$PATH
for such a derivation ends up looking like"${buildPackages.stdenv.cc}/bin:${buildPackages.stdenv.cc.cc}/bin:[…]:${buildPackages.stdenv.cc.bintools}/bin:${buildPackages.stdenv.cc.bintools.bintools}/bin:[…]:${stdenv.cc}/bin:${stdenv.cc.cc}/bin:[…]:${stdenv.cc.bintools}/bin:${stdenv.cc.bintools.bintools}/bin:[…]"
Notice here how the
buildPackages.stdenv
wrapped compiler and unwrapped compiler show up before thestdenv
wrapped compiler.buildPackages.stdenv.cc
contains only unprefixed binaries (e.g.gcc
), because it only includes the prefix whenhostPlatform != targetPlatform
andbuildPackages.stdenv
usesbuildPackages.buildPackages.gcc
. However the unwrapped compiler does include the target-prefixed binaries. This means that when the package tries to look for$CC
it finds the prefixed binary in the unwrapped build compiler instead of finding the expected cross-compiler.It looks to me like this setup was designed with the expectation that cross-compiling will always go to another system and therefore the target-prefixed binary will always uniquely refer to the host compiler (is that the right name for it?), but when cross-compiling back to the same system it ends up being the unwrapped build compiler instead.
This isn't noticed for most of the packages in
pkgsLLVM
because the host compiler is clang instead of gcc, it's only packages that usegccStdenv
that have the problem, or it's when cross-compiling without settinguseLLVM
.Based on this, it seems the root cause is that the unwrapped GCC always includes target-prefixed binaries even when not cross-compiling. Clang doesn't do this (nor does bintools), so I don't understand why GCC does. Because it does that, it means that any derivation that looks for
{target}-gcc
is going to get a broken compiler.I noticed in
cc-wrapper/default.nix
there's a comment suggesting that cc-wrapper should always include the target-prefixed binaries:nixpkgs/pkgs/build-support/cc-wrapper/default.nix
Lines 74 to 79 in fdc5d61
This would mask the issue but cause another one. It would mean that
{target}-gcc
resolves to the build compiler instead of the host compiler. It would be a wrapped compiler, so compilation would work, but it will use the build linker instead of the host linker (which matters for e.g.pkgsLLVM
) and it will use the build libc instead of the host libc (which matters for me because I'm swapping out glibc withcrossOverlays
).Notify maintainers
@Synthetica9 @vcunat @Ericson2314 @amjoseph-nixpkgs
Metadata
The text was updated successfully, but these errors were encountered: