1{ lib }:
2with import ./parse.nix { inherit lib; };
3with lib.attrsets;
4with lib.lists;
5
6let abis_ = abis; in
7let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in
8
9rec {
10 # these patterns are to be matched against {host,build,target}Platform.parsed
11 patterns = rec {
12 # The patterns below are lists in sum-of-products form.
13 #
14 # Each attribute is list of product conditions; non-list values are treated
15 # as a singleton list. If *any* product condition in the list matches then
16 # the predicate matches. Each product condition is tested by
17 # `lib.attrsets.matchAttrs`, which requires a match on *all* attributes of
18 # the product.
19
20 isi686 = { cpu = cpuTypes.i686; };
21 isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
22 isx86_64 = { cpu = { family = "x86"; bits = 64; }; };
23 isPower = { cpu = { family = "power"; }; };
24 isPower64 = { cpu = { family = "power"; bits = 64; }; };
25 # This ABI is the default in NixOS PowerPC64 BE, but not on mainline GCC,
26 # so it sometimes causes issues in certain packages that makes the wrong
27 # assumption on the used ABI.
28 isAbiElfv2 = [
29 { abi = { abi = "elfv2"; }; }
30 { abi = { name = "musl"; }; cpu = { family = "power"; bits = 64; }; }
31 ];
32 isx86 = { cpu = { family = "x86"; }; };
33 isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
34 isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; })
35 (lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "")
36 (lib.attrValues cpuTypes));
37 isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
38 isAarch = { cpu = { family = "arm"; }; };
39 isMicroBlaze = { cpu = { family = "microblaze"; }; };
40 isMips = { cpu = { family = "mips"; }; };
41 isMips32 = { cpu = { family = "mips"; bits = 32; }; };
42 isMips64 = { cpu = { family = "mips"; bits = 64; }; };
43 isMips64n32 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "n32"; }; };
44 isMips64n64 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "64"; }; };
45 isMmix = { cpu = { family = "mmix"; }; };
46 isRiscV = { cpu = { family = "riscv"; }; };
47 isRiscV32 = { cpu = { family = "riscv"; bits = 32; }; };
48 isRiscV64 = { cpu = { family = "riscv"; bits = 64; }; };
49 isRx = { cpu = { family = "rx"; }; };
50 isSparc = { cpu = { family = "sparc"; }; };
51 isWasm = { cpu = { family = "wasm"; }; };
52 isMsp430 = { cpu = { family = "msp430"; }; };
53 isVc4 = { cpu = { family = "vc4"; }; };
54 isAvr = { cpu = { family = "avr"; }; };
55 isAlpha = { cpu = { family = "alpha"; }; };
56 isOr1k = { cpu = { family = "or1k"; }; };
57 isM68k = { cpu = { family = "m68k"; }; };
58 isS390 = { cpu = { family = "s390"; }; };
59 isS390x = { cpu = { family = "s390"; bits = 64; }; };
60 isLoongArch64 = { cpu = { family = "loongarch"; bits = 64; }; };
61 isJavaScript = { cpu = cpuTypes.javascript; };
62
63 is32bit = { cpu = { bits = 32; }; };
64 is64bit = { cpu = { bits = 64; }; };
65 isILP32 = map (a: { abi = { abi = a; }; }) [ "n32" "ilp32" "x32" ];
66 isBigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
67 isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
68
69 isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
70 isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
71 isUnix = [ isBSD isDarwin isLinux isSunOS isCygwin isRedox ];
72
73 isMacOS = { kernel = kernels.macos; };
74 isiOS = { kernel = kernels.ios; };
75 isLinux = { kernel = kernels.linux; };
76 isSunOS = { kernel = kernels.solaris; };
77 isFreeBSD = { kernel = { name = "freebsd"; }; };
78 isNetBSD = { kernel = kernels.netbsd; };
79 isOpenBSD = { kernel = kernels.openbsd; };
80 isWindows = { kernel = kernels.windows; };
81 isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
82 isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
83 isWasi = { kernel = kernels.wasi; };
84 isRedox = { kernel = kernels.redox; };
85 isGhcjs = { kernel = kernels.ghcjs; };
86 isGenode = { kernel = kernels.genode; };
87 isNone = { kernel = kernels.none; };
88
89 isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
90 isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnuabin32 gnu gnueabi gnueabihf gnuabielfv1 gnuabielfv2 ];
91 isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
92 isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
93
94 isEfi = [
95 { cpu = { family = "arm"; version = "6"; }; }
96 { cpu = { family = "arm"; version = "7"; }; }
97 { cpu = { family = "arm"; version = "8"; }; }
98 { cpu = { family = "riscv"; }; }
99 { cpu = { family = "x86"; }; }
100 ];
101 };
102
103 # given two patterns, return a pattern which is their logical AND.
104 # Since a pattern is a list-of-disjuncts, this needs to
105 patternLogicalAnd = pat1_: pat2_:
106 let
107 # patterns can be either a list or a (bare) singleton; turn
108 # them into singletons for uniform handling
109 pat1 = lib.toList pat1_;
110 pat2 = lib.toList pat2_;
111 in
112 lib.concatMap (attr1:
113 map (attr2:
114 lib.recursiveUpdateUntil
115 (path: subattr1: subattr2:
116 if (builtins.intersectAttrs subattr1 subattr2) == {} || subattr1 == subattr2
117 then true
118 else throw ''
119 pattern conflict at path ${toString path}:
120 ${builtins.toJSON subattr1}
121 ${builtins.toJSON subattr2}
122 '')
123 attr1
124 attr2
125 )
126 pat2)
127 pat1;
128
129 matchAnyAttrs = patterns:
130 if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
131 else matchAttrs patterns;
132
133 predicates = mapAttrs (_: matchAnyAttrs) patterns;
134
135 # these patterns are to be matched against the entire
136 # {host,build,target}Platform structure; they include a `parsed={}` marker so
137 # that `lib.meta.availableOn` can distinguish them from the patterns which
138 # apply only to the `parsed` field.
139
140 platformPatterns = mapAttrs (_: p: { parsed = {}; } // p) {
141 isStatic = { isStatic = true; };
142 };
143}