NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.74k stars 13.86k forks source link

gcc cross-compiles from i686 don't support LTO? (efibootmgr fails to cross-compile from i686) #143901

Closed dwf closed 2 years ago

dwf commented 2 years ago

Describe the bug

efibootmgr fails to compile from i686 to armv6l (raspberryPi), because stdenv.isi686 is false and -flto is passed in CFLAGS, however the gcc cross-compiler doesn't support the flag.

Steps To Reproduce

Steps to reproduce the behavior:

  1. From x86-64 Linux, nix-build -A pkgsi686Linux.pkgsCross.raspberryPi.efibootmgr '<nixpkgs>'

Expected behavior

The build to complete successfully.

Additional context

Changing the efibootmgr derivation to use stdenv.buildPlatform.isi686 instead of stdenv.isi686 fixes the build but I'm not sure this is the right fix. It seems that the derivation is perhaps right, and gcc should support LTO on i686 for non-i686 target platforms. Perhaps the references in the gcc sections of pkgs/top-level/all-packages.nix should read enableLTO = !stdenv.hostPlatform.isi686?

Notify maintainers

efibootmgr doesn't have any maintainers listed and I think the actual problem relates to gcc.

@vcunat @Synthetica9 @Ericson2314

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

[nix-shell:~]# nix-shell -p nix-info --run "nix-info -m"
these paths will be fetched (0.05 MiB download, 0.28 MiB unpacked):
  /nix/store/p5lnl4zr45n7mf9kz9w8yz3rqh001b5c-bash-interactive-4.4-p23-dev
copying path '/nix/store/p5lnl4zr45n7mf9kz9w8yz3rqh001b5c-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
 - system: `"x86_64-linux"`
 - host os: `Linux 5.10.74, NixOS, 21.05.3892.70904d4a992 (Okapi)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.16`
 - channels(root): `"nixos-21.05.3892.70904d4a992, unstable-21.11pre323695.9aeeb7574fb"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
# a list of nixos modules affected by the problem
module:
r-burns commented 2 years ago

It looks like LTO availability depends on this setting:

https://github.com/NixOS/nixpkgs/blob/86661be08742ffe5270395d3938e0b3a68a68e96/pkgs/top-level/all-packages.nix#L11691-L11697

So immediately I have a few thoughts:

dwf commented 2 years ago

Your buildPlatform modification appears to be correct, as the enableLTO setting depends on gcc's hostPlatform rather than its targetPlatform

I agree that that's the effect, but is that the intent? Is LTO a problem on i686 hosts or i686 targets, or both? It looks like this was first introduced in 22284b07 by @vcunat who might have some additional context for the change.

r-burns commented 2 years ago

Good point, usually settings like that affect the target platform. It's possible this was only tested for the native case, so it's a good idea to verify the platform predicate is correct.

vcunat commented 2 years ago

It was reaction to non-cross problems during bootstrapping. It's well possible that they won't appear when not bootstrapping (e.g. any cross). Confirming that gcc builds should be enough for the problems from my commit.

dwf commented 2 years ago

I see. It sounds like maybe switching on stdenv.targetPlatform.isi686 is more appropriate, then.

I'm a bit new to Nix, is there a way to force a build from scratch rather than a fetch from cache? The docs are failing me here.

Synthetica9 commented 2 years ago

I think you want nix-build --check

r-burns commented 2 years ago

Linking likely related https://github.com/NixOS/nixpkgs/pull/144778 so I don't forget to look into it along with this

thiagokokada commented 2 years ago

Linking likely related #144778 so I don't forget to look into it along with this

Sorry, maybe I merged it too soon :sweat_smile: ?

r-burns commented 2 years ago

No no worries, I didn't link it there because I don't think the supportsLTO ~ isi686 cleanup is your responsibility. There are probably other locations as well I'll need to look into.

r-burns commented 2 years ago

Hmm, so I was thinking I'd figure out the right host/target platform distinction for gcc and then expose whether it has LTO with e.g. stdenv.cc.hasLTO. But I'm unable to encounter any scenario where LTO doesn't work on i686, so I think we can reenable it fully, and I'll just remove the treewide i686-specific LTO workarounds if that sounds reasonable.

r-burns commented 2 years ago

Never mind, efivar is a reliable reproducer

Going to go ahead with the stdenv.cc.hasLTO strategy, happy to discuss alternatives here or in the upcoming PR.

efivar LTO seems broken for an unrelated reason (it's broken on x86_64 too), everything else seems to work fine with LTO on i686 (regardless of native or cross compilation). PR coming soon.