diff --git a/lib/systems/default.nix b/lib/systems/default.nix index a6ceef2cc3a11..d682eb815003c 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -6,9 +6,9 @@ let filterAttrs foldl hasInfix + isAttrs isFunction isList - isString mapAttrs optional optionalAttrs @@ -55,24 +55,34 @@ let */ flakeExposed = import ./flake-systems.nix { }; + # Turn localSystem or crossSystem, which could be system-string or attrset, into + # attrset. + systemToAttrs = systemOrArgs: + if isAttrs systemOrArgs then systemOrArgs else { system = systemOrArgs; }; + # Elaborate a `localSystem` or `crossSystem` so that it contains everything # necessary. # # `parsed` is inferred from args, both because there are two options with one # clearly preferred, and to prevent cycles. A simpler fixed point where the RHS # always just used `final.*` would fail on both counts. - elaborate = args': let - args = if isString args' then { system = args'; } - else args'; + elaborate = systemOrArgs: let + allArgs = systemToAttrs systemOrArgs; + + # Those two will always be derived from "config", if given, so they should NOT + # be overridden further down with "// args". + args = builtins.removeAttrs allArgs [ "parsed" "system" ]; # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL. rust = args.rust or args.rustc or {}; final = { # Prefer to parse `config` as it is strictly more informative. - parsed = parse.mkSystemFromString (if args ? config then args.config else args.system); - # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds. + parsed = parse.mkSystemFromString (args.config or allArgs.system); + # This can be losslessly-extracted from `parsed` iff parsing succeeds. system = parse.doubleFromSystem final.parsed; + # TODO: This currently can't be losslessly-extracted from `parsed`, for example + # because of -mingw32. config = parse.tripleFromSystem final.parsed; # Determine whether we can execute binaries built for the provided platform. canExecute = platform: @@ -435,5 +445,6 @@ in inspect parse platforms + systemToAttrs ; } diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 265ab242d86d2..78c22d4f70e2f 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -246,7 +246,7 @@ let })] ++ overlays; ${if stdenv.hostPlatform == stdenv.buildPlatform then "localSystem" else "crossSystem"} = { - parsed = makeMuslParsedPlatform stdenv.hostPlatform.parsed; + config = lib.systems.parse.tripleFromSystem (makeMuslParsedPlatform stdenv.hostPlatform.parsed); }; } else throw "Musl libc only supports 64-bit Linux systems."; @@ -258,9 +258,9 @@ let })] ++ overlays; ${if stdenv.hostPlatform == stdenv.buildPlatform then "localSystem" else "crossSystem"} = { - parsed = stdenv.hostPlatform.parsed // { + config = lib.systems.parse.tripleFromSystem (stdenv.hostPlatform.parsed // { cpu = lib.systems.parse.cpuTypes.i686; - }; + }); }; } else throw "i686 Linux package set can only be used with the x86 family."; @@ -270,9 +270,9 @@ let pkgsx86_64Darwin = super'; })] ++ overlays; localSystem = { - parsed = stdenv.hostPlatform.parsed // { + config = lib.systems.parse.tripleFromSystem (stdenv.hostPlatform.parsed // { cpu = lib.systems.parse.cpuTypes.x86_64; - }; + }); }; } else throw "x86_64 Darwin package set can only be used on Darwin systems."; @@ -311,10 +311,11 @@ let })] ++ overlays; crossSystem = { isStatic = true; - parsed = + config = lib.systems.parse.tripleFromSystem ( if stdenv.hostPlatform.isLinux then makeMuslParsedPlatform stdenv.hostPlatform.parsed - else stdenv.hostPlatform.parsed; + else stdenv.hostPlatform.parsed + ); gcc = lib.optionalAttrs (stdenv.hostPlatform.system == "powerpc64-linux") { abi = "elfv2"; } // stdenv.hostPlatform.gcc or {}; };