summary refs log tree commit diff
path: root/lib/systems/parse.nix
diff options
context:
space:
mode:
authorJohn Ericson <Ericson2314@Yahoo.com>2017-02-09 16:09:47 -0500
committerJohn Ericson <Ericson2314@Yahoo.com>2017-04-17 17:13:01 -0400
commit8c99aab3ea4a9ddbd3918282da7861e674b4e7c4 (patch)
tree5c8a663c775e02ad7c7c714d89095f3cd500e0a0 /lib/systems/parse.nix
parentfffcee35f9b2042d4edc5dccb3379972e03ffd84 (diff)
downloadnixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar.gz
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar.bz2
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar.lz
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar.xz
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.tar.zst
nixpkgs-8c99aab3ea4a9ddbd3918282da7861e674b4e7c4.zip
lib: Fix system parsing, and use for doubles lists
The old hard-coded lists are now used to test system parsing.

In the process, make an `assertTrue` in release lib for eval tests; also
use it in release-cross
Diffstat (limited to 'lib/systems/parse.nix')
-rw-r--r--lib/systems/parse.nix203
1 files changed, 125 insertions, 78 deletions
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index 410995f8a5d..f6315b8ad2a 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -6,11 +6,13 @@ with import ../types.nix;
 with import ../attrsets.nix;
 
 let
-  lib = import ./default.nix;
-  setTypes = type:
+  lib = import ../default.nix;
+  setTypesAssert = type: pred:
     mapAttrs (name: value:
-      setType type ({inherit name;} // value)
-    );
+      #assert pred value;
+      setType type ({ inherit name; } // value));
+  setTypes = type: setTypesAssert type (_: true);
+
 in
 
 rec {
@@ -22,20 +24,31 @@ rec {
   };
 
 
-  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; };
-    };
+  isCpuType = isType "cpu-type";
+  cpuTypes = with significantBytes; setTypesAssert "cpu-type"
+    (x: elem x.bits [8 16 32 64 128]
+        && (if 8 < x.bits
+            then isSignificantByte x.significantByte
+            else !(x ? significantByte)))
+  {
+    arm      = { bits = 32; significantByte = littleEndian; family = "arm"; };
+    armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; };
+    armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; };
+    armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; };
+    armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; };
+    aarch64  = { bits = 64; significantByte = littleEndian; family = "arm"; };
+    i686     = { bits = 32; significantByte = littleEndian; family = "x86"; };
+    x86_64   = { bits = 64; significantByte = littleEndian; family = "x86"; };
+    mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; };
+    powerpc  = { bits = 32; significantByte = bigEndian;    family = "powerpc"; };
+  };
 
+  isVendor = isType "vendor";
+  vendors = setTypes "vendor" {
+    apple = {};
+    pc = {};
+    unknown = {};
+  };
 
   isExecFormat = isType "exec-format";
   execFormats = setTypes "exec-format" {
@@ -43,84 +56,118 @@ rec {
     elf = {};
     macho = {};
     pe = {};
-    unknow = {};
+    unknown = {};
   };
 
-
-  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 = {};
+  isKernelFamily = isType "kernel-family";
+  kernelFamilies = setTypes "kernel-family" {
+    bsd = {};
+    unix = {};
+    windows-nt = {};
+    dos = {};
   };
 
+  isKernel = x: isType "kernel" x;
+  kernels = with execFormats; with kernelFamilies; setTypesAssert "kernel"
+    (x: isExecFormat x.execFormat && all isKernelFamily (attrValues x.families))
+  {
+    cygwin  = { execFormat = pe;      families = { inherit /*unix*/ windows-nt; }; };
+    darwin  = { execFormat = macho;   families = { inherit unix; }; };
+    freebsd = { execFormat = elf;     families = { inherit unix bsd; }; };
+    linux   = { execFormat = elf;     families = { inherit unix; }; };
+    netbsd  = { execFormat = elf;     families = { inherit unix bsd; }; };
+    none    = { execFormat = unknown; families = { inherit unix; }; };
+    openbsd = { execFormat = elf;     families = { inherit unix bsd; }; };
+    solaris = { execFormat = elf;     families = { inherit unix; }; };
+    win32   = { execFormat = pe;      families = { inherit dos; }; };
+  };
 
-  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;
+  isAbi = isType "abi";
+  abis = setTypes "abi" {
+    gnu = {};
+    msvc = {};
+    eabi = {};
+    androideabi = {};
+    unknown = {};
   };
 
+  isSystem = isType "system";
+  mkSystem = { cpu, vendor, kernel, abi }:
+    assert isCpuType cpu && isVendor vendor && isKernel kernel && isAbi abi;
+    setType "system" {
+      inherit cpu vendor kernel abi;
+    };
 
   is64Bit = matchAttrs { cpu = { bits = 64; }; };
-  isDarwin = matchAttrs { kernel = kernels.darwin; };
+  is32Bit = matchAttrs { cpu = { bits = 32; }; };
   isi686 = matchAttrs { cpu = cpuTypes.i686; };
-  isLinux = matchAttrs { kernel = kernels.linux; };
+  isx86_64 = matchAttrs { cpu = cpuTypes.x86_64; };
 
+  isDarwin = matchAttrs { kernel = kernels.darwin; };
+  isLinux = matchAttrs { kernel = kernels.linux; };
+  isUnix = matchAttrs { kernel = { families = { inherit (kernelFamilies) unix; }; }; };
+  isWindows = s: matchAttrs { kernel = { families = { inherit (kernelFamilies) windows-nt; }; }; } s
+              || matchAttrs { kernel = { families = { inherit (kernelFamilies) dos; }; }; } s;
+
+
+  mkSkeletonFromList = l: {
+    "2" =    { cpu = elemAt l 0;                      kernel = elemAt l 1;                   };
+    "4" =    { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; };
+    "3" = # Awkwards hacks, beware!
+      if elemAt l 1 == "apple"
+        then { cpu = elemAt l 0; vendor = "apple";    kernel = elemAt l 2;                   }
+      else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu")
+        then { cpu = elemAt l 0;                      kernel = elemAt l 1; abi = elemAt l 2; }
+      else throw "Target specification with 3 components is ambiguous";
+  }.${toString (length l)}
+    or (throw "system string has invalid number of hyphen-separated components");
 
   # This should revert the job done by config.guess from the gcc compiler.
-  mkSystemFromString = s: let
-    l = lib.splitString "-" s;
-
+  mkSystemFromSkeleton = { cpu
+                         , # Optional, but fallback too complex for here.
+                           # Inferred below instead.
+                           vendor ? assert false; null
+                         , kernel
+                         , # Also inferred below
+                           abi    ? assert false; null
+                         } @ args: let
     getCpu = name:
-      attrByPath [name] (throw "Unknow cpuType `${name}'.")
+      attrByPath [name] (throw "Unknown CPU type: ${name}")
         cpuTypes;
-    getArch = name:
-      attrByPath [name] (throw "Unknow architecture `${name}'.")
-        architectures;
+    getVendor = name:
+      attrByPath [name] (throw "Unknown vendor: ${name}")
+        vendors;
     getKernel = name:
-      attrByPath [name] (throw "Unknow kernel `${name}'.")
+      attrByPath [name] (throw "Unknown kernel: ${name}")
         kernels;
+    getAbi = name:
+      attrByPath [name] (throw "Unknown ABI: ${name}")
+        abis;
+
+    system = rec {
+      cpu = getCpu args.cpu;
+      vendor =
+        /**/ if args ? vendor    then getVendor args.vendor
+        else if isDarwin  system then vendors.apple
+        else if isWindows system then vendors.pc
+        else                     vendors.unknown;
+      kernel = getKernel args.kernel;
+      abi =
+        /**/ if args ? abi       then getAbi args.abi
+        else if isLinux   system then abis.gnu
+        else if isWindows system then abis.gnu
+        else                     abis.unknown;
+    };
+
+  in mkSystem system;
+
+  mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
+
+  doubleFromSystem = { cpu, vendor, kernel, abi, ... }: "${cpu.name}-${kernel.name}";
+
+  tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let
+    optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}";
+  in "${cpu.name}-${vendor.name}-${kernel.name}${optAbi}";
 
-    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;
 }