mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-04 04:46:43 +00:00
lib/systems: elaborate properly with non-matching system / config / parsed args (#351608)
This commit is contained in:
commit
9396352fba
@ -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
|
||||
;
|
||||
}
|
||||
|
@ -78,6 +78,18 @@ lib.runTests (
|
||||
expr = toLosslessStringMaybe (lib.systems.elaborate "x86_64-linux" // { something = "extra"; });
|
||||
expected = null;
|
||||
};
|
||||
test_elaborate_config_over_system = {
|
||||
expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; system = "x86_64-linux"; }).system;
|
||||
expected = "i686-linux";
|
||||
};
|
||||
test_elaborate_config_over_parsed = {
|
||||
expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
|
||||
expected = "i686";
|
||||
};
|
||||
test_elaborate_system_over_parsed = {
|
||||
expr = (lib.systems.elaborate { system = "i686-linux"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
|
||||
expected = "i686";
|
||||
};
|
||||
}
|
||||
|
||||
# Generate test cases to assert that a change in any non-function attribute makes a platform unequal
|
||||
|
@ -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 {};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user