| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  | # Define the list of system with their properties. | 
					
						
							|  |  |  |  | # | 
					
						
							|  |  |  |  | # See https://clang.llvm.org/docs/CrossCompilation.html and | 
					
						
							|  |  |  |  | # http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially | 
					
						
							|  |  |  |  | # Triple::normalize. Parsing should essentially act as a more conservative | 
					
						
							|  |  |  |  | # version of that last function. | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  | # | 
					
						
							|  |  |  |  | # Most of the types below come in "open" and "closed" pairs. The open ones | 
					
						
							|  |  |  |  | # specify what information we need to know about systems in general, and the | 
					
						
							|  |  |  |  | # closed ones are sub-types representing the whitelist of systems we support in | 
					
						
							|  |  |  |  | # practice. | 
					
						
							|  |  |  |  | # | 
					
						
							|  |  |  |  | # Code in the remainder of nixpkgs shouldn't rely on the closed ones in | 
					
						
							|  |  |  |  | # e.g. exhaustive cases. Its more a sanity check to make sure nobody defines | 
					
						
							|  |  |  |  | # systems that overlap with existing ones and won't notice something amiss. | 
					
						
							|  |  |  |  | # | 
					
						
							| 
									
										
										
										
											2017-07-28 20:05:35 -04:00
										 |  |  |  | { lib }: | 
					
						
							|  |  |  |  | with lib.lists; | 
					
						
							|  |  |  |  | with lib.types; | 
					
						
							|  |  |  |  | with lib.attrsets; | 
					
						
							| 
									
										
										
										
											2018-07-24 21:02:46 -04:00
										 |  |  |  | with lib.strings; | 
					
						
							| 
									
										
										
										
											2017-07-28 20:05:35 -04:00
										 |  |  |  | with (import ./inspect.nix { inherit lib; }).predicates; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | let | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   inherit (lib.options) mergeOneOption; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   setTypes = type: | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |     mapAttrs (name: value: | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |       assert type.check value; | 
					
						
							|  |  |  |  |       setType type.name ({ inherit name; } // value)); | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | in | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | rec { | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-13 18:41:04 -07:00
										 |  |  |  |   types.openSignificantByte = mkOptionType { | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |     name = "significant-byte"; | 
					
						
							|  |  |  |  |     description = "Endianness"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.significantByte = enum (attrValues significantBytes); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-13 18:41:04 -07:00
										 |  |  |  |   significantBytes = setTypes types.openSignificantByte { | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |     bigEndian = {}; | 
					
						
							|  |  |  |  |     littleEndian = {}; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   # 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 { | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     arm      = { bits = 32; significantByte = littleEndian; family = "arm"; }; | 
					
						
							| 
									
										
										
										
											2018-05-12 15:07:31 -04:00
										 |  |  |  |     armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; }; | 
					
						
							|  |  |  |  |     armv6m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; }; | 
					
						
							|  |  |  |  |     armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; }; | 
					
						
							|  |  |  |  |     armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; | 
					
						
							|  |  |  |  |     armv7r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; | 
					
						
							|  |  |  |  |     armv7m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; | 
					
						
							|  |  |  |  |     armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; }; | 
					
						
							|  |  |  |  |     armv8a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; | 
					
						
							|  |  |  |  |     armv8r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; | 
					
						
							|  |  |  |  |     armv8m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; }; | 
					
						
							|  |  |  |  |     aarch64  = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; }; | 
					
						
							| 
									
										
										
										
											2018-11-01 11:14:18 -04:00
										 |  |  |  |     aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; }; | 
					
						
							| 
									
										
										
										
											2018-05-11 15:02:18 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 20:33:25 -06:00
										 |  |  |  |     i386     = { bits = 32; significantByte = littleEndian; family = "x86"; }; | 
					
						
							|  |  |  |  |     i486     = { bits = 32; significantByte = littleEndian; family = "x86"; }; | 
					
						
							|  |  |  |  |     i586     = { bits = 32; significantByte = littleEndian; family = "x86"; }; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     i686     = { bits = 32; significantByte = littleEndian; family = "x86"; }; | 
					
						
							|  |  |  |  |     x86_64   = { bits = 64; significantByte = littleEndian; family = "x86"; }; | 
					
						
							| 
									
										
										
										
											2018-05-11 15:02:18 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 10:27:45 +00:00
										 |  |  |  |     mips     = { bits = 32; significantByte = bigEndian;    family = "mips"; }; | 
					
						
							|  |  |  |  |     mipsel   = { bits = 32; significantByte = littleEndian; family = "mips"; }; | 
					
						
							|  |  |  |  |     mips64   = { bits = 64; significantByte = bigEndian;    family = "mips"; }; | 
					
						
							|  |  |  |  |     mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; }; | 
					
						
							| 
									
										
										
										
											2018-05-11 15:02:18 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-09 15:12:32 -04:00
										 |  |  |  |     powerpc  = { bits = 32; significantByte = bigEndian;    family = "power"; }; | 
					
						
							| 
									
										
										
										
											2018-08-21 21:31:34 +02:00
										 |  |  |  |     powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; }; | 
					
						
							|  |  |  |  |     powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; }; | 
					
						
							| 
									
										
										
										
											2018-11-01 10:00:55 -04:00
										 |  |  |  |     powerpcle = { bits = 32; significantByte = littleEndian; family = "power"; }; | 
					
						
							| 
									
										
										
										
											2018-05-11 15:02:18 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 16:30:03 -05:00
										 |  |  |  |     riscv32  = { bits = 32; significantByte = littleEndian; family = "riscv"; }; | 
					
						
							|  |  |  |  |     riscv64  = { bits = 64; significantByte = littleEndian; family = "riscv"; }; | 
					
						
							| 
									
										
										
										
											2018-05-11 15:02:18 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 09:33:36 -04:00
										 |  |  |  |     sparc    = { bits = 32; significantByte = bigEndian;    family = "sparc"; }; | 
					
						
							|  |  |  |  |     sparc64  = { bits = 64; significantByte = bigEndian;    family = "sparc"; }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 16:30:03 -05:00
										 |  |  |  |     wasm32   = { bits = 32; significantByte = littleEndian; family = "wasm"; }; | 
					
						
							|  |  |  |  |     wasm64   = { bits = 64; significantByte = littleEndian; family = "wasm"; }; | 
					
						
							| 
									
										
										
										
											2018-11-01 10:00:55 -04:00
										 |  |  |  |      | 
					
						
							| 
									
										
										
										
											2018-11-02 09:38:47 -04:00
										 |  |  |  |     alpha    = { bits = 64; significantByte = littleEndian; family = "alpha"; }; | 
					
						
							| 
									
										
										
										
											2018-10-12 15:09:59 -05:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     avr      = { bits = 8; family = "avr"; }; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-21 22:17:51 -05:00
										 |  |  |  |   # Determine where two CPUs are compatible with each other. That is, | 
					
						
							|  |  |  |  |   # can we run code built for system b on system a? For that to | 
					
						
							|  |  |  |  |   # happen, then the set of all possible possible programs that system | 
					
						
							|  |  |  |  |   # b accepts must be a subset of the set of all programs that system | 
					
						
							|  |  |  |  |   # a accepts. This compatibility relation forms a category where each | 
					
						
							|  |  |  |  |   # CPU is an object and each arrow from a to b represents | 
					
						
							|  |  |  |  |   # compatibility. CPUs with multiple modes of Endianness are | 
					
						
							|  |  |  |  |   # isomorphic while all CPUs are endomorphic because any program | 
					
						
							|  |  |  |  |   # built for a CPU can run on that CPU. | 
					
						
							|  |  |  |  |   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) | 
					
						
							|  |  |  |  |     # NOTE: Not true in some cases. Like in WSL mode. | 
					
						
							|  |  |  |  |     (b == i686 && isCompatible a x86_64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # ARM | 
					
						
							|  |  |  |  |     (b == arm && isCompatible a armv5tel) | 
					
						
							|  |  |  |  |     (b == armv5tel && isCompatible a armv6m) | 
					
						
							|  |  |  |  |     (b == armv6m && isCompatible a armv6l) | 
					
						
							|  |  |  |  |     (b == armv6l && isCompatible a armv7a) | 
					
						
							|  |  |  |  |     (b == armv7a && isCompatible a armv7r) | 
					
						
							|  |  |  |  |     (b == armv7r && isCompatible a armv7m) | 
					
						
							|  |  |  |  |     (b == armv7m && isCompatible a armv7l) | 
					
						
							|  |  |  |  |     (b == armv7l && isCompatible a armv8a) | 
					
						
							|  |  |  |  |     (b == armv8a && isCompatible a armv8r) | 
					
						
							|  |  |  |  |     (b == armv8r && isCompatible a armv8m) | 
					
						
							|  |  |  |  |     # NOTE: not always true! Some arm64 cpus don’t support arm32 mode. | 
					
						
							|  |  |  |  |     (b == armv8m && isCompatible a aarch64) | 
					
						
							|  |  |  |  |     (b == aarch64 && a == aarch64_be) | 
					
						
							|  |  |  |  |     (b == aarch64_be && isCompatible a aarch64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # PowerPC | 
					
						
							|  |  |  |  |     (b == powerpc && isCompatible a powerpc64) | 
					
						
							|  |  |  |  |     (b == powerpcle && isCompatible a powerpc) | 
					
						
							|  |  |  |  |     (b == powerpc && a == powerpcle) | 
					
						
							|  |  |  |  |     (b == powerpc64le && isCompatible a powerpc64) | 
					
						
							|  |  |  |  |     (b == powerpc64 && a == powerpc64le) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # MIPS | 
					
						
							|  |  |  |  |     (b == mips && isCompatible a mips64) | 
					
						
							|  |  |  |  |     (b == mips && a == mipsel) | 
					
						
							|  |  |  |  |     (b == mipsel && isCompatible a mips) | 
					
						
							|  |  |  |  |     (b == mips64 && a == mips64el) | 
					
						
							|  |  |  |  |     (b == mips64el && isCompatible a mips64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # RISCV | 
					
						
							|  |  |  |  |     (b == riscv32 && isCompatible a riscv64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # SPARC | 
					
						
							|  |  |  |  |     (b == sparc && isCompatible a sparc64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # WASM | 
					
						
							|  |  |  |  |     (b == wasm32 && isCompatible a wasm64) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # identity | 
					
						
							|  |  |  |  |     (b == a) | 
					
						
							|  |  |  |  |   ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.openVendor = mkOptionType { | 
					
						
							|  |  |  |  |     name = "vendor"; | 
					
						
							|  |  |  |  |     description = "vendor for the platform"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.vendor = enum (attrValues vendors); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   vendors = setTypes types.openVendor { | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     apple = {}; | 
					
						
							|  |  |  |  |     pc = {}; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-19 11:47:43 -05:00
										 |  |  |  |     none = {}; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     unknown = {}; | 
					
						
							|  |  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.openExecFormat = mkOptionType { | 
					
						
							|  |  |  |  |     name = "exec-format"; | 
					
						
							|  |  |  |  |     description = "executable container used by the kernel"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.execFormat = enum (attrValues execFormats); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   execFormats = setTypes types.openExecFormat { | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |     aout = {}; # a.out | 
					
						
							|  |  |  |  |     elf = {}; | 
					
						
							|  |  |  |  |     macho = {}; | 
					
						
							|  |  |  |  |     pe = {}; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     unknown = {}; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.openKernelFamily = mkOptionType { | 
					
						
							|  |  |  |  |     name = "exec-format"; | 
					
						
							|  |  |  |  |     description = "executable container used by the kernel"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.kernelFamily = enum (attrValues kernelFamilies); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   kernelFamilies = setTypes types.openKernelFamily { | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     bsd = {}; | 
					
						
							| 
									
										
										
										
											2018-03-19 00:16:25 -04:00
										 |  |  |  |     darwin = {}; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.openKernel = mkOptionType { | 
					
						
							|  |  |  |  |     name = "kernel"; | 
					
						
							|  |  |  |  |     description = "kernel name and information"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |     check = x: types.execFormat.check x.execFormat | 
					
						
							|  |  |  |  |         && all types.kernelFamily.check (attrValues x.families); | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.kernel = enum (attrValues kernels); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   kernels = with execFormats; with kernelFamilies; setTypes types.openKernel { | 
					
						
							| 
									
										
										
										
											2018-03-19 00:16:25 -04:00
										 |  |  |  |     # TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as | 
					
						
							|  |  |  |  |     # the nnormalized name for macOS. | 
					
						
							|  |  |  |  |     macos   = { execFormat = macho;   families = { inherit darwin; }; name = "darwin"; }; | 
					
						
							|  |  |  |  |     ios     = { execFormat = macho;   families = { inherit darwin; }; }; | 
					
						
							| 
									
										
										
										
											2017-06-12 14:27:10 -03:00
										 |  |  |  |     freebsd = { execFormat = elf;     families = { inherit bsd; }; }; | 
					
						
							|  |  |  |  |     linux   = { execFormat = elf;     families = { }; }; | 
					
						
							|  |  |  |  |     netbsd  = { execFormat = elf;     families = { inherit bsd; }; }; | 
					
						
							|  |  |  |  |     none    = { execFormat = unknown; families = { }; }; | 
					
						
							|  |  |  |  |     openbsd = { execFormat = elf;     families = { inherit bsd; }; }; | 
					
						
							|  |  |  |  |     solaris = { execFormat = elf;     families = { }; }; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     windows = { execFormat = pe;      families = { }; }; | 
					
						
							|  |  |  |  |   } // { # aliases | 
					
						
							| 
									
										
										
										
											2018-03-19 00:16:25 -04:00
										 |  |  |  |     # 'darwin' is the kernel for all of them. We choose macOS by default. | 
					
						
							|  |  |  |  |     darwin = kernels.macos; | 
					
						
							|  |  |  |  |     watchos = kernels.ios; | 
					
						
							|  |  |  |  |     tvos = kernels.ios; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     win32 = kernels.windows; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.openAbi = mkOptionType { | 
					
						
							|  |  |  |  |     name = "abi"; | 
					
						
							|  |  |  |  |     description = "binary interface for compiled code and syscalls"; | 
					
						
							|  |  |  |  |     merge = mergeOneOption; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   types.abi = enum (attrValues abis); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   abis = setTypes types.openAbi { | 
					
						
							| 
									
										
										
										
											2018-05-10 17:31:07 -04:00
										 |  |  |  |     cygnus       = {}; | 
					
						
							|  |  |  |  |     msvc         = {}; | 
					
						
							| 
									
										
										
										
											2018-12-02 17:47:53 -06:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # Note: eabi is specific to ARM and PowerPC. | 
					
						
							|  |  |  |  |     # On PowerPC, this corresponds to PPCEABI. | 
					
						
							|  |  |  |  |     # On ARM, this corresponds to ARMEABI. | 
					
						
							|  |  |  |  |     eabi         = { float = "soft"; }; | 
					
						
							|  |  |  |  |     eabihf       = { float = "hard"; }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # Other architectures should use ELF in embedded situations. | 
					
						
							|  |  |  |  |     elf          = {}; | 
					
						
							| 
									
										
										
										
											2018-05-10 17:31:07 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 20:14:38 -04:00
										 |  |  |  |     androideabi  = {}; | 
					
						
							| 
									
										
										
										
											2018-05-11 17:35:56 -04:00
										 |  |  |  |     android      = { | 
					
						
							|  |  |  |  |       assertions = [ | 
					
						
							|  |  |  |  |         { assertion = platform: !platform.isAarch32; | 
					
						
							|  |  |  |  |           message = ''
 | 
					
						
							|  |  |  |  |             The "android" ABI is not for 32-bit ARM. Use "androideabi" instead. | 
					
						
							|  |  |  |  |           '';
 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       ]; | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-05-10 17:31:07 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     gnueabi      = { float = "soft"; }; | 
					
						
							|  |  |  |  |     gnueabihf    = { float = "hard"; }; | 
					
						
							| 
									
										
										
										
											2018-05-10 18:13:00 -04:00
										 |  |  |  |     gnu          = { | 
					
						
							| 
									
										
										
										
											2018-05-09 18:50:51 -04:00
										 |  |  |  |       assertions = [ | 
					
						
							|  |  |  |  |         { assertion = platform: !platform.isAarch32; | 
					
						
							|  |  |  |  |           message = ''
 | 
					
						
							|  |  |  |  |             The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead. | 
					
						
							|  |  |  |  |           '';
 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       ]; | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-05-10 17:31:07 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     musleabi     = { float = "soft"; }; | 
					
						
							|  |  |  |  |     musleabihf   = { float = "hard"; }; | 
					
						
							|  |  |  |  |     musl         = {}; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     uclibceabihf = { float = "soft"; }; | 
					
						
							|  |  |  |  |     uclibceabi   = { float = "hard"; }; | 
					
						
							|  |  |  |  |     uclibc       = {}; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     unknown = {}; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-05 15:22:45 -04:00
										 |  |  |  |   types.parsedPlatform = mkOptionType { | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |     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; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   isSystem = isType "system"; | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   mkSystem = components: | 
					
						
							| 
									
										
										
										
											2018-04-05 15:22:45 -04:00
										 |  |  |  |     assert types.parsedPlatform.check components; | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |     setType "system" components; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   mkSkeletonFromList = l: { | 
					
						
							| 
									
										
										
										
											2018-10-12 15:09:59 -05:00
										 |  |  |  |     "1" = if elemAt l 0 == "avr" | 
					
						
							|  |  |  |  |       then { cpu = elemAt l 0; kernel = "none"; abi = "unknown"; } | 
					
						
							|  |  |  |  |       else throw "Target specification with 1 components is ambiguous"; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     "2" = # We only do 2-part hacks for things Nix already supports | 
					
						
							|  |  |  |  |       if elemAt l 1 == "cygwin" | 
					
						
							| 
									
										
										
										
											2017-05-22 12:42:03 -04:00
										 |  |  |  |         then { cpu = elemAt l 0;                      kernel = "windows";  abi = "cygnus";   } | 
					
						
							| 
									
										
										
										
											2018-12-29 03:25:20 -05:00
										 |  |  |  |       # MSVC ought to be the default ABI so this case isn't needed. But then it | 
					
						
							|  |  |  |  |       # becomes difficult to handle the gnu* variants for Aarch32 correctly for | 
					
						
							|  |  |  |  |       # minGW. So it's easier to make gnu* the default for the MinGW, but | 
					
						
							|  |  |  |  |       # hack-in MSVC for the non-MinGW case right here. | 
					
						
							|  |  |  |  |       else if elemAt l 1 == "windows" | 
					
						
							|  |  |  |  |         then { cpu = elemAt l 0;                      kernel = "windows";  abi = "msvc";     } | 
					
						
							| 
									
										
										
										
											2018-12-02 17:47:53 -06:00
										 |  |  |  |       else if (elemAt l 1) == "elf" | 
					
						
							| 
									
										
										
										
											2018-12-29 03:25:20 -05:00
										 |  |  |  |         then { cpu = elemAt l 0; vendor = "unknown";  kernel = "none";     abi = elemAt l 1; } | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |       else   { cpu = elemAt l 0;                      kernel = elemAt l 1;                   }; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |     "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; } | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |       else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window | 
					
						
							| 
									
										
										
										
											2018-12-29 03:25:20 -05:00
										 |  |  |  |         then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows";                    } | 
					
						
							| 
									
										
										
										
											2018-07-24 21:02:46 -04:00
										 |  |  |  |       else if hasPrefix "netbsd" (elemAt l 2) | 
					
						
							|  |  |  |  |         then { cpu = elemAt l 0; vendor = elemAt l 1;    kernel = elemAt l 2;                } | 
					
						
							| 
									
										
										
										
											2018-12-02 17:47:53 -06:00
										 |  |  |  |       else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"]) | 
					
						
							|  |  |  |  |         then { cpu = elemAt l 0; vendor = "unknown"; kernel = elemAt l 1; abi = elemAt l 2; } | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |       else throw "Target specification with 3 components is ambiguous"; | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     "4" =    { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3; }; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   }.${toString (length l)} | 
					
						
							|  |  |  |  |     or (throw "system string has invalid number of hyphen-separated components"); | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   # This should revert the job done by config.guess from the gcc compiler. | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     getCpu    = name: cpuTypes.${name} or (throw "Unknown CPU type: ${name}"); | 
					
						
							|  |  |  |  |     getVendor = name:  vendors.${name} or (throw "Unknown vendor: ${name}"); | 
					
						
							|  |  |  |  |     getKernel = name:  kernels.${name} or (throw "Unknown kernel: ${name}"); | 
					
						
							|  |  |  |  |     getAbi    = name:     abis.${name} or (throw "Unknown ABI: ${name}"); | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 13:39:23 -04:00
										 |  |  |  |     parsed = rec { | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |       cpu = getCpu args.cpu; | 
					
						
							|  |  |  |  |       vendor = | 
					
						
							|  |  |  |  |         /**/ if args ? vendor    then getVendor args.vendor | 
					
						
							| 
									
										
										
										
											2017-05-21 13:39:23 -04:00
										 |  |  |  |         else if isDarwin  parsed then vendors.apple | 
					
						
							|  |  |  |  |         else if isWindows parsed then vendors.pc | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |         else                     vendors.unknown; | 
					
						
							| 
									
										
										
										
											2018-07-24 21:02:46 -04:00
										 |  |  |  |       kernel = if hasPrefix "darwin" args.kernel      then getKernel "darwin" | 
					
						
							|  |  |  |  |                else if hasPrefix "netbsd" args.kernel then getKernel "netbsd" | 
					
						
							|  |  |  |  |                else                                   getKernel args.kernel; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |       abi = | 
					
						
							|  |  |  |  |         /**/ if args ? abi       then getAbi args.abi | 
					
						
							| 
									
										
										
										
											2018-12-29 03:25:20 -05:00
										 |  |  |  |         else if isLinux parsed || isWindows parsed then | 
					
						
							| 
									
										
										
										
											2018-05-12 15:07:31 -04:00
										 |  |  |  |           if isAarch32 parsed then | 
					
						
							|  |  |  |  |             if lib.versionAtLeast (parsed.cpu.version or "0") "6" | 
					
						
							|  |  |  |  |             then abis.gnueabihf | 
					
						
							|  |  |  |  |             else abis.gnueabi | 
					
						
							|  |  |  |  |           else abis.gnu | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  |         else                     abis.unknown; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 13:39:23 -04:00
										 |  |  |  |   in mkSystem parsed; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |   doubleFromSystem = { cpu, vendor, kernel, abi, ... }: | 
					
						
							| 
									
										
										
										
											2018-03-19 00:16:25 -04:00
										 |  |  |  |     /**/ if abi == abis.cygnus       then "${cpu.name}-cygwin" | 
					
						
							|  |  |  |  |     else if kernel.families ? darwin then "${cpu.name}-darwin" | 
					
						
							| 
									
										
										
										
											2017-05-17 11:04:27 -04:00
										 |  |  |  |     else "${cpu.name}-${kernel.name}"; | 
					
						
							| 
									
										
										
										
											2017-02-09 16:09:47 -05:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   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}"; | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 17:50:13 -05:00
										 |  |  |  |   ################################################################################ | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-19 17:19:39 +00:00
										 |  |  |  | } |