Skip to content
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

pkgsMusl.pkgsStatic.stdenv is broken #114510

Open
r-burns opened this issue Feb 26, 2021 · 11 comments
Open

pkgsMusl.pkgsStatic.stdenv is broken #114510

r-burns opened this issue Feb 26, 2021 · 11 comments
Labels
0.kind: bug Something is broken 6.topic: cross-compilation Building packages on a different platform than they will be used on 6.topic: static

Comments

@r-burns
Copy link
Contributor

r-burns commented Feb 26, 2021

Describe the bug
The gcc used for pkgsMusl.pkgsStatic.stdenv fails to build on x86_64-linux, due to a faulty bintools setup, as pointed out by Sandro here: #112096 (comment).

I think the reason for this is that the binutils hostPlatform is different from the targetPlatform (host is dynamic musl, target is static) but the configs are both x86_64-unknown-linux-musl. So our package definitions expect the resulting bintools to have a x86_64-unknown-linux-musl targetPrefix, but they do not because the autotools configure script only sees matching host/target configs, so it produces unprefixed ld, as, etc binaries.

To Reproduce
nix-build '<nixpkgs>' -A pkgsMusl.pkgsStatic.stdenv

Notify maintainers
Nixpkgs cross maintainers: @matthewbauer @Ericson2314

Metadata

  • system: "x86_64-linux"
  • host os: Linux 5.4.87, NixOS, 21.03pre268206.536fe36e23a (Okapi)
  • multi-user?: yes
  • sandbox: yes
  • version: nix-env (Nix) 2.3.10
  • channels(root): "nixos-21.03pre268206.536fe36e23a"
  • nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixos

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
  - binutils
  - gcc
# a list of nixos modules affected by the problem
module:
@r-burns r-burns added 0.kind: bug Something is broken 6.topic: cross-compilation Building packages on a different platform than they will be used on labels Feb 26, 2021
@samueldr
Copy link
Member

samueldr commented Mar 3, 2021

Isn't pkgsStatic already musl? I ask, but I know it is.

nix-repl> pkgsStatic.targetPlatform.isMusl
true

I'm not sure what the difference should be when comparing pkgsMusl.pkgsStatic.* vs. pkgsStatic.* considering pkgsStatic is using musl.

To me, it feels like pkgsMusl.pkgsStatic should be a no-op, but obviously (as I'm observing) it is not.

@r-burns
Copy link
Contributor Author

r-burns commented Mar 3, 2021

Musl is not necessarily static, so pkgsMusl can be dynamic. I think pkgsStatic implies musl but only because glibc is bad at static linking. So I think pkgsStatic.pkgsMusl would be redundant but pkgsMusl.pkgsStatic would not be.

@samueldr
Copy link
Member

samueldr commented Mar 3, 2021

Yes, sorry, I should have made it clear that they shouldn't be expected to be equivalent, but at the current time, I would have assumed them to be equivalent. Since pkgsSatic is using musl, pkgsMusl.pkgsStatic to me should get to the same end result.

I'm wondering what are the differences in semantics that makes (the current implementation details heavy) pkgsStatic not be equivalent to pkgsMusl.pkgsStatic. Why is pkgsMusl.pkgStatic more broken?

@r-burns
Copy link
Contributor Author

r-burns commented Mar 3, 2021

Hmm yeah that's really weird. I'm not sure of the underlying cause, but here's one observable difference:

$ nix eval -f . pkgsStatic.pkgsMusl.stdenv.hostPlatform.isStatic
false
$ nix eval -f . pkgsMusl.pkgsStatic.stdenv.hostPlatform.isStatic
true

@r-burns
Copy link
Contributor Author

r-burns commented Mar 3, 2021

Wait a minute, that makes no sense. Shouldn't pkgsStatic.pkgsMusl mean musl and static? Does the pkgsMusl set "start over" and forget that it's still supposed to be static?

@samueldr
Copy link
Member

samueldr commented Mar 3, 2021

Definitions:

  • # All packages built with the Musl libc. This will override the
    # default GNU libc on Linux systems. Non-Linux systems are not
    # supported.
    pkgsMusl = if stdenv.hostPlatform.isLinux then nixpkgsFun {
    overlays = [ (self': super': {
    pkgsMusl = super';
    })] ++ overlays;
    ${if stdenv.hostPlatform == stdenv.buildPlatform
    then "localSystem" else "crossSystem"} = {
    parsed = stdenv.hostPlatform.parsed // {
    abi = {
    gnu = lib.systems.parse.abis.musl;
    gnueabi = lib.systems.parse.abis.musleabi;
    gnueabihf = lib.systems.parse.abis.musleabihf;
    }.${stdenv.hostPlatform.parsed.abi.name}
    or lib.systems.parse.abis.musl;
    };
    };
    } else throw "Musl libc only supports Linux systems.";
  • # Fully static packages.
    # Currently uses Musl on Linux (couldn’t get static glibc to work).
    pkgsStatic = nixpkgsFun ({
    overlays = [ (self': super': {
    pkgsStatic = super';
    })] ++ overlays;
    crossOverlays = [ (import ./static.nix) ];
    } // lib.optionalAttrs stdenv.hostPlatform.isLinux {
    crossSystem = {
    isStatic = true;
    parsed = stdenv.hostPlatform.parsed // {
    abi = {
    gnu = lib.systems.parse.abis.musl;
    gnueabi = lib.systems.parse.abis.musleabi;
    gnueabihf = lib.systems.parse.abis.musleabihf;
    }.${stdenv.hostPlatform.parsed.abi.name}
    or lib.systems.parse.abis.musl;
    };
    };
    });

I guess one difference is the possible use of localSystem in pkgsMusl rather than crossSystem

Though I don't really grok how this "resets" pkgsMusl... I guess nixpkgsFun does not compose recursively on all attributes of the platform?

Should pkgsStatic also do if stdenv.hostPlatform == stdenv.buildPlatform then "localSystem" else "crossSystem"? Or is it that pkgsMusl should always cross? (probably not)

@r-burns
Copy link
Contributor Author

r-burns commented Mar 3, 2021

Thanks for posting that, I had assumed the pkgsStatic/pkgsMusl logic would be too complicated to skim but that's actually very well-contained and self-documenting. Is the "resetting" just a matter of pkgsMusl setting crossSystem.parsed but not crossSystem.isStatic? I think it would be fairly simple to have pkgsMusl propagate stdenv.hostPlatform.isStatic if that behavior would be more correct.

Also, I think I understand the non-commutativity now. When pkgsMusl is native, it switches over the build system to use musl as well. I think this is because the ordinary linux stdenv is able to bootstrap with musl or glibc, so we can take the native compilation pathway as it's more reliable.

$ nix eval nixpkgs.stdenv.buildPlatform.isMusl                                
false
$ nix eval nixpkgs.pkgsMusl.stdenv.buildPlatform.isMusl
true

However, there is no native static stdenv. The static stdenv still uses a dynamic buildPlatform, and goes the cross-compilation route to produce a final static package. So pkgsMusl.pkgsStatic is cross-compiling from dynamic to static musl, while pkgsStatic.pkgsMusl triggers the stdenv.hostPlatform != stdenv.buildPlatform case in pkgsMusl and ends up cross-compiling from dynamic glibc to static musl. Well, actually dynamic glibc to dynamic musl, since hostPlatform.isStatic isn't propagated.

Primitive demo:

for set in pkgsMusl.pkgsStatic pkgsStatic.pkgsMusl; do
    for platform in buildPlatform hostPlatform; do
        x=nixpkgs.$set.stdenv.$platform
        echo $set.$platform: $(nix eval $x.config) $(nix eval $x.isStatic)
    done
done
pkgsMusl.pkgsStatic.buildPlatform: "x86_64-unknown-linux-musl" false
pkgsMusl.pkgsStatic.hostPlatform: "x86_64-unknown-linux-musl" true
pkgsStatic.pkgsMusl.buildPlatform: "x86_64-unknown-linux-gnu" false
pkgsStatic.pkgsMusl.hostPlatform: "x86_64-unknown-linux-musl" false

Ultimately this is all pretty tangential to the original issue, lol. I guess my conclusion is that pkgsMusl.pkgsStatic is broken due to the issue in the OP but otherwise sound and useful. Meanwhile pkgsStatic.pkgsMusl is completely busted.

@stale
Copy link

stale bot commented Sep 3, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Sep 3, 2021
@r-burns
Copy link
Contributor Author

r-burns commented Sep 3, 2021

pkgsMusl.pkgsStatic.stdenv was fixed by #119625.

pkgsStatic.pkgsMusl.stdenv is still broken.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Sep 3, 2021
@stale
Copy link

stale bot commented Apr 28, 2022

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 28, 2022
@uri-canva
Copy link
Contributor

Opened a new issue for pkgsStatic using musl, so it's easier to find and people can refer to it: #196329.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 16, 2022
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Sep 25, 2024
This makes combinations work, where pkgsi686Linux or pkgsMusl are used
on another package set, for example:

- Keeps pkgsStatic.pkgsMusl.stdenv.hostPlatform.isStatic at "true"
- Keeps pkgsCross.ppc64-musl.pkgsMusl.stdenv.hostPlatform.gcc.abi at
"elfv2"
- Keeps pkgsLLVM.pkgsi686Linux.stdenv.hostPlatform.useLLVM at "true"

Supersedes NixOS#136549
Resolves NixOS#114510
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 15, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.gnu64 is a cross compilation from musl to glibc
  - pkgsCross.gnu64.pkgsMusl is a cross compilation to musl

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead of
    musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 16, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.gnu64 is a cross compilation from musl to glibc
  - pkgsCross.gnu64.pkgsMusl is a cross compilation to musl

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead of
    musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 21, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.gnu64 is a cross compilation from musl to glibc
  - pkgsCross.gnu64.pkgsMusl is a cross compilation to musl

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead of
    musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 21, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.aarch64-multiplatform is a cross compilation from
musl to glibc/aarch64
  - pkgsCross.aarch64-multiplatform.pkgsMusl is a cross compilation to
musl/aarch64

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead
of
    musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 21, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.aarch64-multiplatform is a cross compilation from
musl to glibc/aarch64
  - pkgsCross.aarch64-multiplatform.pkgsMusl is a cross compilation to
musl/aarch64

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead
of musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
wolfgangwalther added a commit to wolfgangwalther/nixpkgs that referenced this issue Dec 21, 2024
The various pkgsXYZ top-level package sets did not pass localSystem /
crossSystem to lower levels, so far. This change propagates original
arguments to lower levels, which include the overrides made by an upper
package sets.

There is an extensive test-suite to test various combinations of package
sets in pkgs/test/top-level. There are a few basic promises made:

- Package sets must be idempotent. pkgsMusl.pkgsMusl === pkgsMusl.

- Once pkgsCross is used any subsequent package sets should affect the
  **host platform** and not the build platform. Examples:
  - pkgsMusl.pkgsCross.aarch64-multiplatform is a cross compilation from
musl to glibc/aarch64
  - pkgsCross.aarch64-multiplatform.pkgsMusl is a cross compilation to
musl/aarch64

- Modifications from an earlier layer should not be lost, unless
  explicitly overwritten. Examples:
  - pkgsStatic.pkgsMusl should still be static.
  - pkgsStatic.pkgsCross.gnu64 should be static, but with glibc instead
of musl.

Exceptions / TODOs:
- pkgsExtraHardening is currently not idempotent, because it applies the
  same flags over and over again.

Supersedes NixOS#136549
Resolves NixOS#114510
Resolves NixOS#212494
Resolves NixOS#281596
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug Something is broken 6.topic: cross-compilation Building packages on a different platform than they will be used on 6.topic: static
Projects
None yet
Development

No branches or pull requests

4 participants