Merge pull request #295374 from philiptaron/issue-208242/lib.systems

lib: use explicit name imports in `lib/systems`
This commit is contained in:
Silvan Mosberger 2024-03-25 18:41:46 +01:00 committed by GitHub
commit b803ba5a48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 140 additions and 51 deletions

View File

@ -1,7 +1,25 @@
{ lib }: { lib }:
let inherit (lib.attrsets) mapAttrs; in
rec { let
inherit (lib)
any
filterAttrs
foldl
hasInfix
isFunction
isList
isString
mapAttrs
optional
optionalAttrs
optionalString
removeSuffix
replaceStrings
toUpper
;
inherit (lib.strings) toJSON;
doubles = import ./doubles.nix { inherit lib; }; doubles = import ./doubles.nix { inherit lib; };
parse = import ./parse.nix { inherit lib; }; parse = import ./parse.nix { inherit lib; };
inspect = import ./inspect.nix { inherit lib; }; inspect = import ./inspect.nix { inherit lib; };
@ -24,7 +42,7 @@ rec {
both arguments have been `elaborate`-d. both arguments have been `elaborate`-d.
*/ */
equals = equals =
let removeFunctions = a: lib.filterAttrs (_: v: !builtins.isFunction v) a; let removeFunctions = a: filterAttrs (_: v: !isFunction v) a;
in a: b: removeFunctions a == removeFunctions b; in a: b: removeFunctions a == removeFunctions b;
/* List of all Nix system doubles the nixpkgs flake will expose the package set /* List of all Nix system doubles the nixpkgs flake will expose the package set
@ -41,7 +59,7 @@ rec {
# clearly preferred, and to prevent cycles. A simpler fixed point where the RHS # clearly preferred, and to prevent cycles. A simpler fixed point where the RHS
# always just used `final.*` would fail on both counts. # always just used `final.*` would fail on both counts.
elaborate = args': let elaborate = args': let
args = if lib.isString args' then { system = args'; } args = if isString args' then { system = args'; }
else args'; else args';
# TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL. # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
@ -96,7 +114,7 @@ rec {
then "lib64" then "lib64"
else "lib" else "lib"
else null; else null;
extensions = lib.optionalAttrs final.hasSharedLibraries { extensions = optionalAttrs final.hasSharedLibraries {
sharedLibrary = sharedLibrary =
if final.isDarwin then ".dylib" if final.isDarwin then ".dylib"
else if final.isWindows then ".dll" else if final.isWindows then ".dll"
@ -134,9 +152,9 @@ rec {
# uname -m # uname -m
processor = processor =
if final.isPower64 if final.isPower64
then "ppc64${lib.optionalString final.isLittleEndian "le"}" then "ppc64${optionalString final.isLittleEndian "le"}"
else if final.isPower else if final.isPower
then "ppc${lib.optionalString final.isLittleEndian "le"}" then "ppc${optionalString final.isLittleEndian "le"}"
else if final.isMips64 else if final.isMips64
then "mips64" # endianness is *not* included on mips64 then "mips64" # endianness is *not* included on mips64
else final.parsed.cpu.name; else final.parsed.cpu.name;
@ -202,8 +220,8 @@ rec {
else if final.isS390 && !final.isS390x then null else if final.isS390 && !final.isS390x then null
else if final.isx86_64 then "x86_64" else if final.isx86_64 then "x86_64"
else if final.isx86 then "i386" else if final.isx86 then "i386"
else if final.isMips64n32 then "mipsn32${lib.optionalString final.isLittleEndian "el"}" else if final.isMips64n32 then "mipsn32${optionalString final.isLittleEndian "el"}"
else if final.isMips64 then "mips64${lib.optionalString final.isLittleEndian "el"}" else if final.isMips64 then "mips64${optionalString final.isLittleEndian "el"}"
else final.uname.processor; else final.uname.processor;
# Name used by UEFI for architectures. # Name used by UEFI for architectures.
@ -259,7 +277,7 @@ rec {
if pkgs.stdenv.hostPlatform.canExecute final if pkgs.stdenv.hostPlatform.canExecute final
then "${pkgs.runtimeShell} -c '\"$@\"' --" then "${pkgs.runtimeShell} -c '\"$@\"' --"
else if final.isWindows else if final.isWindows
then "${wine}/bin/wine${lib.optionalString (final.parsed.cpu.bits == 64) "64"}" then "${wine}/bin/wine${optionalString (final.parsed.cpu.bits == 64) "64"}"
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux && final.qemuArch != null else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux && final.qemuArch != null
then "${qemu-user}/bin/qemu-${final.qemuArch}" then "${qemu-user}/bin/qemu-${final.qemuArch}"
else if final.isWasi else if final.isWasi
@ -310,10 +328,10 @@ rec {
let let
f = args.rustc.platform.target-family; f = args.rustc.platform.target-family;
in in
if builtins.isList f then f else [ f ] if isList f then f else [ f ]
) )
else lib.optional final.isUnix "unix" else optional final.isUnix "unix"
++ lib.optional final.isWindows "windows"; ++ optional final.isWindows "windows";
# https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor # https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor
vendor = let vendor = let
@ -337,13 +355,13 @@ rec {
vendor_ = final.rust.platform.vendor; vendor_ = final.rust.platform.vendor;
# TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL. # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
in args.rust.rustcTarget or args.rustc.config in args.rust.rustcTarget or args.rustc.config
or "${cpu_}-${vendor_}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}"; or "${cpu_}-${vendor_}-${kernel.name}${optionalString (abi.name != "unknown") "-${abi.name}"}";
# The name of the rust target if it is standard, or the json file # The name of the rust target if it is standard, or the json file
# containing the custom target spec. # containing the custom target spec.
rustcTargetSpec = rust.rustcTargetSpec or ( rustcTargetSpec = rust.rustcTargetSpec or (
/**/ if rust ? platform /**/ if rust ? platform
then builtins.toFile (final.rust.rustcTarget + ".json") (builtins.toJSON rust.platform) then builtins.toFile (final.rust.rustcTarget + ".json") (toJSON rust.platform)
else final.rust.rustcTarget); else final.rust.rustcTarget);
# The name of the rust target if it is standard, or the # The name of the rust target if it is standard, or the
@ -352,7 +370,7 @@ rec {
# #
# This is the name used by Cargo for target subdirectories. # This is the name used by Cargo for target subdirectories.
cargoShortTarget = cargoShortTarget =
lib.removeSuffix ".json" (baseNameOf "${final.rust.rustcTargetSpec}"); removeSuffix ".json" (baseNameOf "${final.rust.rustcTargetSpec}");
# When used as part of an environment variable name, triples are # When used as part of an environment variable name, triples are
# uppercased and have all hyphens replaced by underscores: # uppercased and have all hyphens replaced by underscores:
@ -360,17 +378,17 @@ rec {
# https://github.com/rust-lang/cargo/pull/9169 # https://github.com/rust-lang/cargo/pull/9169
# https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431 # https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431
cargoEnvVarTarget = cargoEnvVarTarget =
lib.strings.replaceStrings ["-"] ["_"] replaceStrings ["-"] ["_"]
(lib.strings.toUpper final.rust.cargoShortTarget); (toUpper final.rust.cargoShortTarget);
# True if the target is no_std # True if the target is no_std
# https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421 # https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421
isNoStdTarget = isNoStdTarget =
builtins.any (t: lib.hasInfix t final.rust.rustcTarget) ["-none" "nvptx" "switch" "-uefi"]; any (t: hasInfix t final.rust.rustcTarget) ["-none" "nvptx" "switch" "-uefi"];
}; };
}; };
in assert final.useAndroidPrebuilt -> final.isAndroid; in assert final.useAndroidPrebuilt -> final.isAndroid;
assert lib.foldl assert foldl
(pass: { assertion, message }: (pass: { assertion, message }:
if assertion final if assertion final
then pass then pass
@ -378,4 +396,20 @@ rec {
true true
(final.parsed.abi.assertions or []); (final.parsed.abi.assertions or []);
final; final;
in
# Everything in this attrset is the public interface of the file.
{
inherit
architectures
doubles
elaborate
equals
examples
flakeExposed
inspect
parse
platforms
;
} }

View File

@ -1,10 +1,31 @@
{ lib }: { lib }:
with import ./parse.nix { inherit lib; };
with lib.attrsets;
with lib.lists;
let abis_ = abis; in let
let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in inherit (lib)
any
attrValues
concatMap
filter
hasPrefix
isList
mapAttrs
matchAttrs
recursiveUpdateUntil
toList
;
inherit (lib.strings) toJSON;
inherit (lib.systems.parse)
kernels
kernelFamilies
significantBytes
cpuTypes
execFormats
;
abis = mapAttrs (_: abi: removeAttrs abi [ "assertions" ]) lib.systems.parse.abis;
in
rec { rec {
# these patterns are to be matched against {host,build,target}Platform.parsed # these patterns are to be matched against {host,build,target}Platform.parsed
@ -32,8 +53,8 @@ rec {
isx86 = { cpu = { family = "x86"; }; }; isx86 = { cpu = { family = "x86"; }; };
isAarch32 = { cpu = { family = "arm"; bits = 32; }; }; isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; }) isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; })
(lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "") (filter (cpu: hasPrefix "armv7" cpu.arch or "")
(lib.attrValues cpuTypes)); (attrValues cpuTypes));
isAarch64 = { cpu = { family = "arm"; bits = 64; }; }; isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
isAarch = { cpu = { family = "arm"; }; }; isAarch = { cpu = { family = "arm"; }; };
isMicroBlaze = { cpu = { family = "microblaze"; }; }; isMicroBlaze = { cpu = { family = "microblaze"; }; };
@ -111,19 +132,19 @@ rec {
let let
# patterns can be either a list or a (bare) singleton; turn # patterns can be either a list or a (bare) singleton; turn
# them into singletons for uniform handling # them into singletons for uniform handling
pat1 = lib.toList pat1_; pat1 = toList pat1_;
pat2 = lib.toList pat2_; pat2 = toList pat2_;
in in
lib.concatMap (attr1: concatMap (attr1:
map (attr2: map (attr2:
lib.recursiveUpdateUntil recursiveUpdateUntil
(path: subattr1: subattr2: (path: subattr1: subattr2:
if (builtins.intersectAttrs subattr1 subattr2) == {} || subattr1 == subattr2 if (builtins.intersectAttrs subattr1 subattr2) == {} || subattr1 == subattr2
then true then true
else throw '' else throw ''
pattern conflict at path ${toString path}: pattern conflict at path ${toString path}:
${builtins.toJSON subattr1} ${toJSON subattr1}
${builtins.toJSON subattr2} ${toJSON subattr2}
'') '')
attr1 attr1
attr2 attr2
@ -132,7 +153,7 @@ rec {
pat1; pat1;
matchAnyAttrs = patterns: matchAnyAttrs = patterns:
if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns if isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
else matchAttrs patterns; else matchAttrs patterns;
predicates = mapAttrs (_: matchAnyAttrs) patterns; predicates = mapAttrs (_: matchAnyAttrs) patterns;

View File

@ -15,14 +15,45 @@
# systems that overlap with existing ones and won't notice something amiss. # systems that overlap with existing ones and won't notice something amiss.
# #
{ lib }: { lib }:
with lib.lists;
with lib.types;
with lib.attrsets;
with lib.strings;
with (import ./inspect.nix { inherit lib; }).predicates;
let let
inherit (lib.options) mergeOneOption; inherit (lib)
all
any
attrValues
elem
elemAt
hasPrefix
id
length
mapAttrs
mergeOneOption
optionalString
splitString
versionAtLeast
;
inherit (lib.strings) match;
inherit (lib.systems.inspect.predicates)
isAarch32
isBigEndian
isDarwin
isLinux
isPower64
isWindows
;
inherit (lib.types)
enum
float
isType
mkOptionType
number
setType
string
types
;
setTypes = type: setTypes = type:
mapAttrs (name: value: mapAttrs (name: value:
@ -33,10 +64,10 @@ let
# regex `e?abi.*$` when determining the validity of a triple. In # regex `e?abi.*$` when determining the validity of a triple. In
# other words, `i386-linuxabichickenlips` is a valid triple. # other words, `i386-linuxabichickenlips` is a valid triple.
removeAbiSuffix = x: removeAbiSuffix = x:
let match = builtins.match "(.*)e?abi.*" x; let found = match "(.*)e?abi.*" x;
in if match==null in if found == null
then x then x
else lib.elemAt match 0; else elemAt found 0;
in in
@ -76,7 +107,7 @@ rec {
types.cpuType = enum (attrValues cpuTypes); types.cpuType = enum (attrValues cpuTypes);
cpuTypes = with significantBytes; setTypes types.openCpuType { cpuTypes = let inherit (significantBytes) bigEndian littleEndian; in setTypes types.openCpuType {
arm = { bits = 32; significantByte = littleEndian; family = "arm"; }; arm = { bits = 32; significantByte = littleEndian; family = "arm"; };
armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; }; armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; };
armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; }; armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; };
@ -166,7 +197,7 @@ rec {
# Note: Since 22.11 the archs of a mode switching CPU are no longer considered # Note: Since 22.11 the archs of a mode switching CPU are no longer considered
# pairwise compatible. Mode switching implies that binaries built for A # pairwise compatible. Mode switching implies that binaries built for A
# and B respectively can't be executed at the same time. # and B respectively can't be executed at the same time.
isCompatible = a: b: with cpuTypes; lib.any lib.id [ isCompatible = with cpuTypes; a: b: any id [
# x86 # x86
(b == i386 && isCompatible a i486) (b == i386 && isCompatible a i486)
(b == i486 && isCompatible a i586) (b == i486 && isCompatible a i586)
@ -287,7 +318,10 @@ rec {
types.kernel = enum (attrValues kernels); types.kernel = enum (attrValues kernels);
kernels = with execFormats; with kernelFamilies; setTypes types.openKernel { kernels = let
inherit (execFormats) elf pe wasm unknown macho;
inherit (kernelFamilies) bsd darwin;
in setTypes types.openKernel {
# TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as # TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as
# the normalized name for macOS. # the normalized name for macOS.
macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; }; macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; };
@ -359,7 +393,7 @@ rec {
The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead. The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead.
''; '';
} }
{ assertion = platform: with platform; !(isPower64 && isBigEndian); { assertion = platform: !(platform.isPower64 && platform.isBigEndian);
message = '' message = ''
The "gnu" ABI is ambiguous on big-endian 64-bit PowerPC. Use "gnuabielfv2" or "gnuabielfv1" instead. The "gnu" ABI is ambiguous on big-endian 64-bit PowerPC. Use "gnuabielfv2" or "gnuabielfv1" instead.
''; '';
@ -480,7 +514,7 @@ rec {
/**/ if args ? abi then getAbi args.abi /**/ if args ? abi then getAbi args.abi
else if isLinux parsed || isWindows parsed then else if isLinux parsed || isWindows parsed then
if isAarch32 parsed then if isAarch32 parsed then
if lib.versionAtLeast (parsed.cpu.version or "0") "6" if versionAtLeast (parsed.cpu.version or "0") "6"
then abis.gnueabihf then abis.gnueabihf
else abis.gnueabi else abis.gnueabi
# Default ppc64 BE to ELFv2 # Default ppc64 BE to ELFv2
@ -491,7 +525,7 @@ rec {
in mkSystem parsed; in mkSystem parsed;
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s)); mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (splitString "-" s));
kernelName = kernel: kernelName = kernel:
kernel.name + toString (kernel.version or ""); kernel.name + toString (kernel.version or "");
@ -503,10 +537,10 @@ rec {
tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
optExecFormat = optExecFormat =
lib.optionalString (kernel.name == "netbsd" && optionalString (kernel.name == "netbsd" &&
gnuNetBSDDefaultExecFormat cpu != kernel.execFormat) gnuNetBSDDefaultExecFormat cpu != kernel.execFormat)
kernel.execFormat.name; kernel.execFormat.name;
optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}"; optAbi = optionalString (abi != abis.unknown) "-${abi.name}";
in "${cpu.name}-${vendor.name}-${kernelName kernel}${optExecFormat}${optAbi}"; in "${cpu.name}-${vendor.name}-${kernelName kernel}${optExecFormat}${optAbi}";
################################################################################ ################################################################################