summary refs log tree commit diff
path: root/lib/systems.nix
blob: 92d8bdf892b418457eeeadb79851259c07e52de0 (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
# Define the list of system with their properties.  Only systems tested for
# Nixpkgs are listed below

with import ./lists.nix;
with import ./types.nix;
with import ./attrsets.nix;

let
  lib = import ./default.nix;
  setTypes = type:
    mapAttrs (name: value:
      setType type ({inherit name;} // value)
    );
in

rec {

  isSignificantByte = isType "significant-byte";
  significantBytes = setTypes "significant-byte" {
    bigEndian = {};
    littleEndian = {};
  };


  isCpuType = x: isType "cpu-type" x
    && elem x.bits [8 16 32 64 128]
    && (8 < x.bits -> isSignificantByte x.significantByte);

  cpuTypes = with significantBytes;
    setTypes "cpu-type" {
      arm =      { bits = 32; significantByte = littleEndian; };
      armv5tel = { bits = 32; significantByte = littleEndian; };
      armv7l   = { bits = 32; significantByte = littleEndian; };
      i686 =     { bits = 32; significantByte = littleEndian; };
      powerpc =  { bits = 32; significantByte = bigEndian; };
      x86_64 =   { bits = 64; significantByte = littleEndian; };
    };


  isExecFormat = isType "exec-format";
  execFormats = setTypes "exec-format" {
    aout = {}; # a.out
    elf = {};
    macho = {};
    pe = {};
    unknow = {};
  };


  isKernel = isType "kernel";
  kernels = with execFormats;
    setTypes "kernel" {
      cygwin =  { execFormat = pe; };
      darwin =  { execFormat = macho; };
      freebsd = { execFormat = elf; };
      linux =   { execFormat = elf; };
      netbsd =  { execFormat = elf; };
      none =    { execFormat = unknow; };
      openbsd = { execFormat = elf; };
      win32 =   { execFormat = pe; };
    };


  isArchitecture = isType "architecture";
  architectures = setTypes "architecture" {
    apple = {};
    pc = {};
    unknow = {};
  };


  isSystem = x: isType "system" x
    && isCpuType x.cpu
    && isArchitecture x.arch
    && isKernel x.kernel;

  mkSystem = {
    cpu ? cpuTypes.i686,
    arch ? architectures.pc,
    kernel ? kernels.linux,
    name ? "${cpu.name}-${arch.name}-${kernel.name}"
  }: setType "system" {
    inherit name cpu arch kernel;
  };


  is64Bit = matchAttrs { cpu = { bits = 64; }; };
  isDarwin = matchAttrs { kernel = kernels.darwin; };
  isi686 = matchAttrs { cpu = cpuTypes.i686; };
  isLinux = matchAttrs { kernel = kernels.linux; };


  # This should revert the job done by config.guess from the gcc compiler.
  mkSystemFromString = s: let
    l = lib.splitString "-" s;

    getCpu = name:
      attrByPath [name] (throw "Unknow cpuType `${name}'.")
        cpuTypes;
    getArch = name:
      attrByPath [name] (throw "Unknow architecture `${name}'.")
        architectures;
    getKernel = name:
      attrByPath [name] (throw "Unknow kernel `${name}'.")
        kernels;

    system =
      if builtins.length l == 2 then
        mkSystem rec {
          name = s;
          cpu = getCpu (head l);
          arch =
            if isDarwin system
            then architectures.apple
            else architectures.pc;
          kernel = getKernel (head (tail l));
        }
      else
        mkSystem {
          name = s;
          cpu = getCpu (head l);
          arch = getArch (head (tail l));
          kernel = getKernel (head (tail (tail l)));
        };
  in assert isSystem system; system;
}