aboutsummaryrefslogtreecommitdiffstats
path: root/tests/indent/nix/general.nix
blob: f79214bad79667411bc46a3131cf1a9d9faef220 (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
{ lib }:
with lib.lists;
with lib.types;
with lib.attrsets;
with lib.strings;
with (import ./inspect.nix { inherit lib; }).predicates;

let
  inherit (lib.options) mergeOneOption;

  setTypes = type:
    mapAttrs (name: value:
      assert type.check value;
      setType type.name ({ inherit name; } // value));

in rec {

  ################################################################################

  types.openSignificantByte = mkOptionType {
    name = "significant-byte";
    description = "Endianness";
    merge = mergeOneOption;
  };

  types.significantByte = enum (attrValues significantBytes);

  significantBytes = setTypes types.openSignificantByte {
    bigEndian = { };
    littleEndian = { };
  };

  ################################################################################

  # Reasonable power of 2
  types.bitWidth = enum [ 8 16 32 64 128 ];

  ################################################################################

  types.openCpuType = mkOptionType {
    name = "cpu-type";
    description = "instruction set architecture name and information";
    merge = mergeOneOption;
    check = x:
      types.bitWidth.check x.bits && (if 8 < x.bits then
        types.significantByte.check x.significantByte
      else
        !(x ? significantByte));
  };

  types.cpuType = enum (attrValues cpuTypes);

  cpuTypes = with significantBytes;
    setTypes types.openCpuType {
      arm = {
        bits = 32;
        significantByte = littleEndian;
        family = "arm";
      };
      armv5tel = {
        bits = 32;
        significantByte = littleEndian;
        family = "arm";
        version = "5";
        arch = "armv5t";
      };
    };

  isCompatible = a: b:
    with cpuTypes;
    lib.any lib.id [
      # x86
      (b == i386 && isCompatible a i486)
      (b == i486 && isCompatible a i586)
      (b == i586 && isCompatible a i686)

      # ARMv6
      (b == armv6l && isCompatible a armv6m)
      (b == armv6m && isCompatible a armv7l)
    ];

  ################################################################################

  types.openVendor = mkOptionType {
    name = "vendor";
    description = "vendor for the platform";
    merge = mergeOneOption;
  };

  abis = setTypes types.openAbi {
    cygnus = { };
    msvc = { };

    # Other architectures should use ELF in embedded situations.
    elf = { };

    androideabi = { };
    android = {
      assertions = [{
        assertion = platform: !platform.isAarch32;
        message = ''
          The "android" ABI is not for 32-bit ARM. Use "androideabi" instead.
        '';
      }];
    };
  };

  ################################################################################

  types.parsedPlatform = mkOptionType {
    name = "system";
    description =
      "fully parsed representation of llvm- or nix-style platform tuple";
    merge = mergeOneOption;
    check = { cpu, vendor, kernel, abi, }:
      types.cpuType.check cpu && types.vendor.check vendor
      && types.kernel.check kernel && types.abi.check abi;
  };

  isSystem = isType "system";

  mkSystem = components:
    assert types.parsedPlatform.check components;
    setType "system" components;

  mkSystemFromString = s:
    mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));

  ################################################################################
}