2017-07-29 01:05:35 +01:00
|
|
|
{ lib }:
|
2024-03-12 15:37:53 +00:00
|
|
|
with lib.systems.parse;
|
2017-07-29 01:05:35 +01:00
|
|
|
with lib.attrsets;
|
|
|
|
with lib.lists;
|
2017-05-21 18:39:23 +01:00
|
|
|
|
2018-05-11 23:30:38 +01:00
|
|
|
let abis_ = abis; in
|
|
|
|
let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in
|
|
|
|
|
2017-05-21 18:39:23 +01:00
|
|
|
rec {
|
2023-01-27 10:19:54 +00:00
|
|
|
# these patterns are to be matched against {host,build,target}Platform.parsed
|
2017-06-12 18:27:10 +01:00
|
|
|
patterns = rec {
|
2022-09-20 03:12:19 +01:00
|
|
|
# The patterns below are lists in sum-of-products form.
|
|
|
|
#
|
|
|
|
# Each attribute is list of product conditions; non-list values are treated
|
|
|
|
# as a singleton list. If *any* product condition in the list matches then
|
|
|
|
# the predicate matches. Each product condition is tested by
|
|
|
|
# `lib.attrsets.matchAttrs`, which requires a match on *all* attributes of
|
|
|
|
# the product.
|
|
|
|
|
2018-03-20 02:14:45 +00:00
|
|
|
isi686 = { cpu = cpuTypes.i686; };
|
2019-01-06 18:57:36 +00:00
|
|
|
isx86_32 = { cpu = { family = "x86"; bits = 32; }; };
|
|
|
|
isx86_64 = { cpu = { family = "x86"; bits = 64; }; };
|
2019-09-02 06:55:38 +01:00
|
|
|
isPower = { cpu = { family = "power"; }; };
|
2022-04-10 09:56:28 +01:00
|
|
|
isPower64 = { cpu = { family = "power"; bits = 64; }; };
|
2022-07-25 11:23:13 +01:00
|
|
|
# This ABI is the default in NixOS PowerPC64 BE, but not on mainline GCC,
|
|
|
|
# so it sometimes causes issues in certain packages that makes the wrong
|
|
|
|
# assumption on the used ABI.
|
|
|
|
isAbiElfv2 = [
|
|
|
|
{ abi = { abi = "elfv2"; }; }
|
|
|
|
{ abi = { name = "musl"; }; cpu = { family = "power"; bits = 64; }; }
|
|
|
|
];
|
2018-03-20 02:14:45 +00:00
|
|
|
isx86 = { cpu = { family = "x86"; }; };
|
treewide: isArm -> isAarch32
Following legacy packing conventions, `isArm` was defined just for
32-bit ARM instruction set. This is confusing to non packagers though,
because Aarch64 is an ARM instruction set.
The official ARM overview for ARMv8[1] is surprisingly not confusing,
given the overall state of affairs for ARM naming conventions, and
offers us a solution. It divides the nomenclature into three levels:
```
ISA: ARMv8 {-A, -R, -M}
/ \
Mode: Aarch32 Aarch64
| / \
Encoding: A64 A32 T32
```
At the top is the overall v8 instruction set archicture. Second are the
two modes, defined by bitwidth but differing in other semantics too, and
buttom are the encodings, (hopefully?) isomorphic if they encode the
same mode.
The 32 bit encodings are mostly backwards compatible with previous
non-Thumb and Thumb encodings, and if so we can pun the mode names to
instead mean "sets of compatable or isomorphic encodings", and then
voilà we have nice names for 32-bit and 64-bit arm instruction sets
which do not use the word ARM so as to not confused either laymen or
experienced ARM packages.
[1]: https://developer.arm.com/products/architecture/a-profile
(cherry picked from commit ba52ae50488de85a9cf60a3a04f1c9ca7122ec74)
2018-03-20 02:41:06 +00:00
|
|
|
isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
|
2023-01-19 16:39:30 +00:00
|
|
|
isArmv7 = map ({ arch, ... }: { cpu = { inherit arch; }; })
|
|
|
|
(lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "")
|
|
|
|
(lib.attrValues cpuTypes));
|
treewide: isArm -> isAarch32
Following legacy packing conventions, `isArm` was defined just for
32-bit ARM instruction set. This is confusing to non packagers though,
because Aarch64 is an ARM instruction set.
The official ARM overview for ARMv8[1] is surprisingly not confusing,
given the overall state of affairs for ARM naming conventions, and
offers us a solution. It divides the nomenclature into three levels:
```
ISA: ARMv8 {-A, -R, -M}
/ \
Mode: Aarch32 Aarch64
| / \
Encoding: A64 A32 T32
```
At the top is the overall v8 instruction set archicture. Second are the
two modes, defined by bitwidth but differing in other semantics too, and
buttom are the encodings, (hopefully?) isomorphic if they encode the
same mode.
The 32 bit encodings are mostly backwards compatible with previous
non-Thumb and Thumb encodings, and if so we can pun the mode names to
instead mean "sets of compatable or isomorphic encodings", and then
voilà we have nice names for 32-bit and 64-bit arm instruction sets
which do not use the word ARM so as to not confused either laymen or
experienced ARM packages.
[1]: https://developer.arm.com/products/architecture/a-profile
(cherry picked from commit ba52ae50488de85a9cf60a3a04f1c9ca7122ec74)
2018-03-20 02:41:06 +00:00
|
|
|
isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
|
2022-07-28 12:43:30 +01:00
|
|
|
isAarch = { cpu = { family = "arm"; }; };
|
2022-06-20 08:56:34 +01:00
|
|
|
isMicroBlaze = { cpu = { family = "microblaze"; }; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isMips = { cpu = { family = "mips"; }; };
|
lib/systems: add mips64el definitions
MIPS has a large space of {architecture,abi,endianness}; this commit
adds all of them to lib/systems/platforms.nix so we can be done with
it.
Currently lib/systems/inspect.nix has a single "isMips" predicate,
which is a bit ambiguous now that we will have both mips32 and mips64
support, with the latter having two ABIs. Let's add four new
predicates (isMips32, isMips64, isMips64n32, and isMips64n64) and
treat the now-ambiguous isMips as deprecated in favor of the
more-specific predicates. These predicates are used mainly for
enabling/disabling target-specific workarounds, and it is extremely
rare that a platform-specific workaround is needed, and both mips32
and mips64 need exactly the same workaround.
The separate predicates (isMips64n32 and isMips64n64) for ABI
distinctions are, unfortunately, useful. Boost's user-scheduled
threading (used by nix) does does not currently supports mips64n32,
which is a very desirable ABI on routers since they rarely have
more than 2**32 bytes of DRAM.
2022-02-21 04:32:52 +00:00
|
|
|
isMips32 = { cpu = { family = "mips"; bits = 32; }; };
|
|
|
|
isMips64 = { cpu = { family = "mips"; bits = 64; }; };
|
|
|
|
isMips64n32 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "n32"; }; };
|
|
|
|
isMips64n64 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "64"; }; };
|
2020-11-04 14:13:06 +00:00
|
|
|
isMmix = { cpu = { family = "mmix"; }; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isRiscV = { cpu = { family = "riscv"; }; };
|
2022-04-27 15:04:08 +01:00
|
|
|
isRiscV32 = { cpu = { family = "riscv"; bits = 32; }; };
|
|
|
|
isRiscV64 = { cpu = { family = "riscv"; bits = 64; }; };
|
2022-05-23 01:52:36 +01:00
|
|
|
isRx = { cpu = { family = "rx"; }; };
|
2018-07-26 14:33:36 +01:00
|
|
|
isSparc = { cpu = { family = "sparc"; }; };
|
2023-07-21 20:34:47 +01:00
|
|
|
isSparc64 = { cpu = { family = "sparc"; bits = 64; }; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isWasm = { cpu = { family = "wasm"; }; };
|
2019-03-26 02:17:37 +00:00
|
|
|
isMsp430 = { cpu = { family = "msp430"; }; };
|
2019-11-02 15:47:38 +00:00
|
|
|
isVc4 = { cpu = { family = "vc4"; }; };
|
2018-10-12 21:09:59 +01:00
|
|
|
isAvr = { cpu = { family = "avr"; }; };
|
2019-02-20 19:27:47 +00:00
|
|
|
isAlpha = { cpu = { family = "alpha"; }; };
|
2020-11-09 20:06:44 +00:00
|
|
|
isOr1k = { cpu = { family = "or1k"; }; };
|
2021-07-23 19:20:02 +01:00
|
|
|
isM68k = { cpu = { family = "m68k"; }; };
|
2021-07-23 19:20:02 +01:00
|
|
|
isS390 = { cpu = { family = "s390"; }; };
|
2023-01-19 16:40:01 +00:00
|
|
|
isS390x = { cpu = { family = "s390"; bits = 64; }; };
|
2023-04-27 18:04:17 +01:00
|
|
|
isLoongArch64 = { cpu = { family = "loongarch"; bits = 64; }; };
|
2023-02-19 15:21:57 +00:00
|
|
|
isJavaScript = { cpu = cpuTypes.javascript; };
|
2018-03-20 02:14:45 +00:00
|
|
|
|
|
|
|
is32bit = { cpu = { bits = 32; }; };
|
|
|
|
is64bit = { cpu = { bits = 64; }; };
|
2023-11-21 03:31:21 +00:00
|
|
|
isILP32 = [ { cpu = { family = "wasm"; bits = 32; }; } ] ++
|
|
|
|
map (a: { abi = { abi = a; }; }) [ "n32" "ilp32" "x32" ];
|
2018-03-20 02:14:45 +00:00
|
|
|
isBigEndian = { cpu = { significantByte = significantBytes.bigEndian; }; };
|
|
|
|
isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };
|
|
|
|
|
|
|
|
isBSD = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isDarwin = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
|
2020-07-21 21:11:36 +01:00
|
|
|
isUnix = [ isBSD isDarwin isLinux isSunOS isCygwin isRedox ];
|
2018-03-20 02:14:45 +00:00
|
|
|
|
2018-03-20 02:14:45 +00:00
|
|
|
isMacOS = { kernel = kernels.macos; };
|
|
|
|
isiOS = { kernel = kernels.ios; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isLinux = { kernel = kernels.linux; };
|
|
|
|
isSunOS = { kernel = kernels.solaris; };
|
2022-10-31 12:35:51 +00:00
|
|
|
isFreeBSD = { kernel = { name = "freebsd"; }; };
|
2018-03-20 02:14:45 +00:00
|
|
|
isNetBSD = { kernel = kernels.netbsd; };
|
|
|
|
isOpenBSD = { kernel = kernels.openbsd; };
|
|
|
|
isWindows = { kernel = kernels.windows; };
|
|
|
|
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
|
|
|
|
isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
|
2019-01-30 02:01:24 +00:00
|
|
|
isWasi = { kernel = kernels.wasi; };
|
2020-07-21 21:11:36 +01:00
|
|
|
isRedox = { kernel = kernels.redox; };
|
2019-09-02 06:55:38 +01:00
|
|
|
isGhcjs = { kernel = kernels.ghcjs; };
|
2020-03-24 08:02:18 +00:00
|
|
|
isGenode = { kernel = kernels.genode; };
|
2019-09-02 06:57:01 +01:00
|
|
|
isNone = { kernel = kernels.none; };
|
2018-03-20 02:14:45 +00:00
|
|
|
|
|
|
|
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
|
2023-06-29 20:24:17 +01:00
|
|
|
isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnuabin32 gnu gnueabi gnueabihf gnuabielfv1 gnuabielfv2 ];
|
lib/systems: add mips64el definitions
MIPS has a large space of {architecture,abi,endianness}; this commit
adds all of them to lib/systems/platforms.nix so we can be done with
it.
Currently lib/systems/inspect.nix has a single "isMips" predicate,
which is a bit ambiguous now that we will have both mips32 and mips64
support, with the latter having two ABIs. Let's add four new
predicates (isMips32, isMips64, isMips64n32, and isMips64n64) and
treat the now-ambiguous isMips as deprecated in favor of the
more-specific predicates. These predicates are used mainly for
enabling/disabling target-specific workarounds, and it is extremely
rare that a platform-specific workaround is needed, and both mips32
and mips64 need exactly the same workaround.
The separate predicates (isMips64n32 and isMips64n64) for ABI
distinctions are, unfortunately, useful. Boost's user-scheduled
threading (used by nix) does does not currently supports mips64n32,
which is a very desirable ABI on routers since they rarely have
more than 2**32 bytes of DRAM.
2022-02-21 04:32:52 +00:00
|
|
|
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
|
2018-05-10 04:33:31 +01:00
|
|
|
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
|
2018-03-20 02:14:45 +00:00
|
|
|
|
2023-01-29 14:44:42 +00:00
|
|
|
isEfi = [
|
|
|
|
{ cpu = { family = "arm"; version = "6"; }; }
|
|
|
|
{ cpu = { family = "arm"; version = "7"; }; }
|
|
|
|
{ cpu = { family = "arm"; version = "8"; }; }
|
|
|
|
{ cpu = { family = "riscv"; }; }
|
|
|
|
{ cpu = { family = "x86"; }; }
|
|
|
|
];
|
2021-10-18 04:48:47 +01:00
|
|
|
|
|
|
|
isElf = { kernel.execFormat = execFormats.elf; };
|
|
|
|
isMacho = { kernel.execFormat = execFormats.macho; };
|
2017-05-21 18:39:23 +01:00
|
|
|
};
|
|
|
|
|
2023-08-21 22:38:53 +01:00
|
|
|
# given two patterns, return a pattern which is their logical AND.
|
|
|
|
# Since a pattern is a list-of-disjuncts, this needs to
|
|
|
|
patternLogicalAnd = pat1_: pat2_:
|
|
|
|
let
|
|
|
|
# patterns can be either a list or a (bare) singleton; turn
|
|
|
|
# them into singletons for uniform handling
|
|
|
|
pat1 = lib.toList pat1_;
|
|
|
|
pat2 = lib.toList pat2_;
|
|
|
|
in
|
|
|
|
lib.concatMap (attr1:
|
|
|
|
map (attr2:
|
|
|
|
lib.recursiveUpdateUntil
|
|
|
|
(path: subattr1: subattr2:
|
|
|
|
if (builtins.intersectAttrs subattr1 subattr2) == {} || subattr1 == subattr2
|
|
|
|
then true
|
|
|
|
else throw ''
|
|
|
|
pattern conflict at path ${toString path}:
|
|
|
|
${builtins.toJSON subattr1}
|
|
|
|
${builtins.toJSON subattr2}
|
|
|
|
'')
|
|
|
|
attr1
|
|
|
|
attr2
|
|
|
|
)
|
|
|
|
pat2)
|
|
|
|
pat1;
|
|
|
|
|
2017-06-12 18:27:10 +01:00
|
|
|
matchAnyAttrs = patterns:
|
|
|
|
if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
|
|
|
|
else matchAttrs patterns;
|
|
|
|
|
2018-03-20 02:14:45 +00:00
|
|
|
predicates = mapAttrs (_: matchAnyAttrs) patterns;
|
2023-01-27 10:19:54 +00:00
|
|
|
|
|
|
|
# these patterns are to be matched against the entire
|
|
|
|
# {host,build,target}Platform structure; they include a `parsed={}` marker so
|
|
|
|
# that `lib.meta.availableOn` can distinguish them from the patterns which
|
|
|
|
# apply only to the `parsed` field.
|
|
|
|
|
2023-01-27 11:56:20 +00:00
|
|
|
platformPatterns = mapAttrs (_: p: { parsed = {}; } // p) {
|
|
|
|
isStatic = { isStatic = true; };
|
2023-01-27 10:19:54 +00:00
|
|
|
};
|
2017-05-21 18:39:23 +01:00
|
|
|
}
|