Skip to content

Build failure: gcc fails to compile on linux when nixpkgs is configured to cross-compile back to the same system and libcCross does not contain passthru.libgcc #263040

@lilyball

Description

@lilyball

GCC fails to compile when nixpkgs is configured to cross-compile back to the same system and libcCross does not contain passthru.libgcc. Most of the GCC build determines whether it's cross-compiling by testing if targetPlatform != hostPlatform, but preFixupLibGccPhase instead tests hostPlatform.config != targetPlatform.config. This means that when building under these circumstances it does most of the build and then fails to find libgcc_s.so as it's looking in the wrong place. The preFixupLibGccPhase code needs to use the same test as the code that defines targetConfig.

This isn't normally noticed as glibcCross includes passthru.libgcc, but if I use crossOverlays to replace it with a libc that does not have this passthru, that's when GCC breaks. This is blocking me as I am attempting to backdate glibc to an older version that doesn't bundle libgcc (for symbol versioning reasons).

targetConfig definition:

targetConfig = if targetPlatform != hostPlatform then targetPlatform.config else null;

preFixupLibGccPhase tests:

targetPlatformSlash =
if hostPlatform.config == targetPlatform.config
then ""
else "${targetPlatform.config}/";

+ lib.optionalString (hostPlatform.config != targetPlatform.config) ''
mkdir -p $lib/lib/
ln -s ${targetPlatformSlash}lib $lib/lib
''

Steps To Reproduce

nix build --impure --expr 'let pkgs = import (builtins.getFlake "nixpkgs/5ba549eafcf3e33405e5f66decd1a72356632b96") {
  crossOverlays = [(self: super: {
    glibcCross = super.glibcCross.overrideAttrs (old: {
      passthru = builtins.removeAttrs old.passthru [ "libgcc" ];
    });
  })];
}; in pkgs.pkgsLLVM.buildPackages.gcc.cc'

Build log

Relevant output from the end of the log:

Moving /nix/store/qmpisiz34xp8757sj3dbrxqv2ha394jk-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0/x86_64-unknown-linux-gnu/lib/libgcc_s.so.1 to /nix/store/1d1dgmqfk54cdg7kr3rz7761qrcldifp-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0-lib/x86_64-unknown-linux-gnu/lib/libgcc_s.so.1
[...]
preFixupLibGccPhase
mv: cannot stat '/nix/store/1d1dgmqfk54cdg7kr3rz7761qrcldifp-x86_64-unknown-linux-gnu-stage-final-gcc-12.3.0-lib/lib/libgcc_s.so': No such file or directory

Notice now the libgcc_s.so.1 path includes the target config in the lib path, but the preFixupLibGccPhase tries to look for it without the target config.

Additional context

If I override the package to set targetConfig to null it seems to skip building libgcc_s.so entirely, so it looks like the targetConfig definition is correct and the libgcc.nix code needs to be updated to use the same test (or possibly to just check if targetConfig != null instead of trying to independently test for cross-compilation).

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`

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions