summary refs log tree commit diff
path: root/lib/systems/inspect.nix
blob: 073df78797c728b522d321571dc1d423a3fe932d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{ lib }:
with import ./parse.nix { inherit lib; };
with lib.attrsets;
with lib.lists;

let abis_ = abis; in
let abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) abis_; in

rec {
  # these patterns are to be matched against {host,build,target}Platform.parsed
  patterns = rec {
    # 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.

    isi686         = { cpu = cpuTypes.i686; };
    isx86_32       = { cpu = { family = "x86"; bits = 32; }; };
    isx86_64       = { cpu = { family = "x86"; bits = 64; }; };
    isPower        = { cpu = { family = "power"; }; };
    isPower64      = { cpu = { family = "power"; bits = 64; }; };
    # 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; }; }
    ];
    isx86          = { cpu = { family = "x86"; }; };
    isAarch32      = { cpu = { family = "arm"; bits = 32; }; };
    isArmv7        = map ({ arch, ... }: { cpu = { inherit arch; }; })
                       (lib.filter (cpu: lib.hasPrefix "armv7" cpu.arch or "")
                         (lib.attrValues cpuTypes));
    isAarch64      = { cpu = { family = "arm"; bits = 64; }; };
    isAarch        = { cpu = { family = "arm"; }; };
    isMicroBlaze   = { cpu = { family = "microblaze"; }; };
    isMips         = { cpu = { family = "mips"; }; };
    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";  }; };
    isMmix         = { cpu = { family = "mmix"; }; };
    isRiscV        = { cpu = { family = "riscv"; }; };
    isRiscV32      = { cpu = { family = "riscv"; bits = 32; }; };
    isRiscV64      = { cpu = { family = "riscv"; bits = 64; }; };
    isRx           = { cpu = { family = "rx"; }; };
    isSparc        = { cpu = { family = "sparc"; }; };
    isWasm         = { cpu = { family = "wasm"; }; };
    isMsp430       = { cpu = { family = "msp430"; }; };
    isVc4          = { cpu = { family = "vc4"; }; };
    isAvr          = { cpu = { family = "avr"; }; };
    isAlpha        = { cpu = { family = "alpha"; }; };
    isOr1k         = { cpu = { family = "or1k"; }; };
    isM68k         = { cpu = { family = "m68k"; }; };
    isS390         = { cpu = { family = "s390"; }; };
    isS390x        = { cpu = { family = "s390"; bits = 64; }; };
    isLoongArch64  = { cpu = { family = "loongarch"; bits = 64; }; };
    isJavaScript   = { cpu = cpuTypes.javascript; };

    is32bit        = { cpu = { bits = 32; }; };
    is64bit        = { cpu = { bits = 64; }; };
    isILP32        = map (a: { abi = { abi = a; }; }) [ "n32" "ilp32" "x32" ];
    isBigEndian    = { cpu = { significantByte = significantBytes.bigEndian; }; };
    isLittleEndian = { cpu = { significantByte = significantBytes.littleEndian; }; };

    isBSD          = { kernel = { families = { inherit (kernelFamilies) bsd; }; }; };
    isDarwin       = { kernel = { families = { inherit (kernelFamilies) darwin; }; }; };
    isUnix         = [ isBSD isDarwin isLinux isSunOS isCygwin isRedox ];

    isMacOS        = { kernel = kernels.macos; };
    isiOS          = { kernel = kernels.ios; };
    isLinux        = { kernel = kernels.linux; };
    isSunOS        = { kernel = kernels.solaris; };
    isFreeBSD      = { kernel = { name = "freebsd"; }; };
    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; };
    isWasi         = { kernel = kernels.wasi; };
    isRedox        = { kernel = kernels.redox; };
    isGhcjs        = { kernel = kernels.ghcjs; };
    isGenode       = { kernel = kernels.genode; };
    isNone         = { kernel = kernels.none; };

    isAndroid      = [ { abi = abis.android; } { abi = abis.androideabi; } ];
    isGnu          = with abis; map (a: { abi = a; }) [ gnuabi64 gnuabin32 gnu gnueabi gnueabihf gnuabielfv1 gnuabielfv2 ];
    isMusl         = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
    isUClibc       = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];

    isEfi = [
      { cpu = { family = "arm"; version = "6"; }; }
      { cpu = { family = "arm"; version = "7"; }; }
      { cpu = { family = "arm"; version = "8"; }; }
      { cpu = { family = "riscv"; }; }
      { cpu = { family = "x86"; }; }
    ];
  };

  # 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;

  matchAnyAttrs = patterns:
    if builtins.isList patterns then attrs: any (pattern: matchAttrs pattern attrs) patterns
    else matchAttrs patterns;

  predicates = mapAttrs (_: matchAnyAttrs) patterns;

  # 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.

  platformPatterns = mapAttrs (_: p: { parsed = {}; } // p) {
    isStatic = { isStatic = true; };
  };
}