at 17.09-beta 6.6 kB view raw
1# Define the list of system with their properties. 2# 3# See https://clang.llvm.org/docs/CrossCompilation.html and 4# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially 5# Triple::normalize. Parsing should essentially act as a more conservative 6# version of that last function. 7 8with import ../lists.nix; 9with import ../types.nix; 10with import ../attrsets.nix; 11with (import ./inspect.nix).predicates; 12 13let 14 lib = import ../default.nix; 15 setTypesAssert = type: pred: 16 mapAttrs (name: value: 17 assert pred value; 18 setType type ({ inherit name; } // value)); 19 setTypes = type: setTypesAssert type (_: true); 20 21in 22 23rec { 24 25 isSignificantByte = isType "significant-byte"; 26 significantBytes = setTypes "significant-byte" { 27 bigEndian = {}; 28 littleEndian = {}; 29 }; 30 31 isCpuType = isType "cpu-type"; 32 cpuTypes = with significantBytes; setTypesAssert "cpu-type" 33 (x: elem x.bits [8 16 32 64 128] 34 && (if 8 < x.bits 35 then isSignificantByte x.significantByte 36 else !(x ? significantByte))) 37 { 38 arm = { bits = 32; significantByte = littleEndian; family = "arm"; }; 39 armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; }; 40 armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; }; 41 armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; }; 42 armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; }; 43 aarch64 = { bits = 64; significantByte = littleEndian; family = "aarch64"; }; 44 i686 = { bits = 32; significantByte = littleEndian; family = "x86"; }; 45 x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; }; 46 mips64el = { bits = 32; significantByte = littleEndian; family = "mips"; }; 47 powerpc = { bits = 32; significantByte = bigEndian; family = "power"; }; 48 }; 49 50 isVendor = isType "vendor"; 51 vendors = setTypes "vendor" { 52 apple = {}; 53 pc = {}; 54 55 unknown = {}; 56 }; 57 58 isExecFormat = isType "exec-format"; 59 execFormats = setTypes "exec-format" { 60 aout = {}; # a.out 61 elf = {}; 62 macho = {}; 63 pe = {}; 64 65 unknown = {}; 66 }; 67 68 isKernelFamily = isType "kernel-family"; 69 kernelFamilies = setTypes "kernel-family" { 70 bsd = {}; 71 }; 72 73 isKernel = x: isType "kernel" x; 74 kernels = with execFormats; with kernelFamilies; setTypesAssert "kernel" 75 (x: isExecFormat x.execFormat && all isKernelFamily (attrValues x.families)) 76 { 77 darwin = { execFormat = macho; families = { }; }; 78 freebsd = { execFormat = elf; families = { inherit bsd; }; }; 79 hurd = { execFormat = elf; families = { }; }; 80 linux = { execFormat = elf; families = { }; }; 81 netbsd = { execFormat = elf; families = { inherit bsd; }; }; 82 none = { execFormat = unknown; families = { }; }; 83 openbsd = { execFormat = elf; families = { inherit bsd; }; }; 84 solaris = { execFormat = elf; families = { }; }; 85 windows = { execFormat = pe; families = { }; }; 86 } // { # aliases 87 # TODO(@Ericson2314): Handle these Darwin version suffixes more generally. 88 darwin10 = kernels.darwin; 89 darwin14 = kernels.darwin; 90 win32 = kernels.windows; 91 }; 92 93 isAbi = isType "abi"; 94 abis = setTypes "abi" { 95 cygnus = {}; 96 gnu = {}; 97 msvc = {}; 98 eabi = {}; 99 androideabi = {}; 100 gnueabi = {}; 101 gnueabihf = {}; 102 103 unknown = {}; 104 }; 105 106 isSystem = isType "system"; 107 mkSystem = { cpu, vendor, kernel, abi }: 108 assert isCpuType cpu && isVendor vendor && isKernel kernel && isAbi abi; 109 setType "system" { 110 inherit cpu vendor kernel abi; 111 }; 112 113 mkSkeletonFromList = l: { 114 "2" = # We only do 2-part hacks for things Nix already supports 115 if elemAt l 1 == "cygwin" 116 then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; } 117 else if elemAt l 1 == "gnu" 118 then { cpu = elemAt l 0; kernel = "hurd"; abi = "gnu"; } 119 else { cpu = elemAt l 0; kernel = elemAt l 1; }; 120 "3" = # Awkwards hacks, beware! 121 if elemAt l 1 == "apple" 122 then { cpu = elemAt l 0; vendor = "apple"; kernel = elemAt l 2; } 123 else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu") 124 then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; } 125 else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window 126 then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; } 127 else throw "Target specification with 3 components is ambiguous"; 128 "4" = { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; }; 129 }.${toString (length l)} 130 or (throw "system string has invalid number of hyphen-separated components"); 131 132 # This should revert the job done by config.guess from the gcc compiler. 133 mkSystemFromSkeleton = { cpu 134 , # Optional, but fallback too complex for here. 135 # Inferred below instead. 136 vendor ? assert false; null 137 , kernel 138 , # Also inferred below 139 abi ? assert false; null 140 } @ args: let 141 getCpu = name: cpuTypes.${name} or (throw "Unknown CPU type: ${name}"); 142 getVendor = name: vendors.${name} or (throw "Unknown vendor: ${name}"); 143 getKernel = name: kernels.${name} or (throw "Unknown kernel: ${name}"); 144 getAbi = name: abis.${name} or (throw "Unknown ABI: ${name}"); 145 146 parsed = rec { 147 cpu = getCpu args.cpu; 148 vendor = 149 /**/ if args ? vendor then getVendor args.vendor 150 else if isDarwin parsed then vendors.apple 151 else if isWindows parsed then vendors.pc 152 else vendors.unknown; 153 kernel = getKernel args.kernel; 154 abi = 155 /**/ if args ? abi then getAbi args.abi 156 else if isLinux parsed then abis.gnu 157 else if isWindows parsed then abis.gnu 158 else abis.unknown; 159 }; 160 161 in mkSystem parsed; 162 163 mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s)); 164 165 doubleFromSystem = { cpu, vendor, kernel, abi, ... }: 166 if abi == abis.cygnus 167 then "${cpu.name}-cygwin" 168 else "${cpu.name}-${kernel.name}"; 169 170 tripleFromSystem = { cpu, vendor, kernel, abi, ... } @ sys: assert isSystem sys; let 171 optAbi = lib.optionalString (abi != abis.unknown) "-${abi.name}"; 172 in "${cpu.name}-${vendor.name}-${kernel.name}${optAbi}"; 173 174}