nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at r-updates 1015 lines 25 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# 8# Most of the types below come in "open" and "closed" pairs. The open ones 9# specify what information we need to know about systems in general, and the 10# closed ones are sub-types representing the whitelist of systems we support in 11# practice. 12# 13# Code in the remainder of nixpkgs shouldn't rely on the closed ones in 14# e.g. exhaustive cases. Its more a sanity check to make sure nobody defines 15# systems that overlap with existing ones and won't notice something amiss. 16# 17{ lib }: 18 19let 20 inherit (lib) 21 all 22 any 23 attrValues 24 elem 25 elemAt 26 hasPrefix 27 id 28 length 29 mapAttrs 30 mergeOneOption 31 optionalString 32 splitString 33 versionAtLeast 34 ; 35 36 inherit (lib.strings) match; 37 38 inherit (lib.systems.inspect.predicates) 39 isAarch32 40 isBigEndian 41 isDarwin 42 isLinux 43 isPower64 44 isWindows 45 isCygwin 46 ; 47 48 inherit (lib.types) 49 enum 50 isType 51 mkOptionType 52 setType 53 ; 54 55 setTypes = 56 type: 57 mapAttrs ( 58 name: value: 59 assert type.check value; 60 setType type.name ({ inherit name; } // value) 61 ); 62 63 # gnu-config will ignore the portion of a triple matching the 64 # regex `e?abi.*$` when determining the validity of a triple. In 65 # other words, `i386-linuxabichickenlips` is a valid triple. 66 removeAbiSuffix = 67 x: 68 let 69 found = match "(.*)e?abi.*" x; 70 in 71 if found == null then x else elemAt found 0; 72 73in 74 75rec { 76 77 ################################################################################ 78 79 types.openSignificantByte = mkOptionType { 80 name = "significant-byte"; 81 description = "Endianness"; 82 merge = mergeOneOption; 83 }; 84 85 types.significantByte = enum (attrValues significantBytes); 86 87 significantBytes = setTypes types.openSignificantByte { 88 bigEndian = { }; 89 littleEndian = { }; 90 }; 91 92 ################################################################################ 93 94 # Reasonable power of 2 95 types.bitWidth = enum [ 96 8 97 16 98 32 99 64 100 128 101 ]; 102 103 ################################################################################ 104 105 types.openCpuType = mkOptionType { 106 name = "cpu-type"; 107 description = "instruction set architecture name and information"; 108 merge = mergeOneOption; 109 check = 110 x: 111 types.bitWidth.check x.bits 112 && (if 8 < x.bits then types.significantByte.check x.significantByte else !(x ? significantByte)); 113 }; 114 115 types.cpuType = enum (attrValues cpuTypes); 116 117 cpuTypes = 118 let 119 inherit (significantBytes) bigEndian littleEndian; 120 in 121 setTypes types.openCpuType { 122 arm = { 123 bits = 32; 124 significantByte = littleEndian; 125 family = "arm"; 126 }; 127 armv5tel = { 128 bits = 32; 129 significantByte = littleEndian; 130 family = "arm"; 131 version = "5"; 132 arch = "armv5t"; 133 }; 134 armv6m = { 135 bits = 32; 136 significantByte = littleEndian; 137 family = "arm"; 138 version = "6"; 139 arch = "armv6-m"; 140 }; 141 armv6l = { 142 bits = 32; 143 significantByte = littleEndian; 144 family = "arm"; 145 version = "6"; 146 arch = "armv6"; 147 }; 148 armv7a = { 149 bits = 32; 150 significantByte = littleEndian; 151 family = "arm"; 152 version = "7"; 153 arch = "armv7-a"; 154 }; 155 armv7r = { 156 bits = 32; 157 significantByte = littleEndian; 158 family = "arm"; 159 version = "7"; 160 arch = "armv7-r"; 161 }; 162 armv7m = { 163 bits = 32; 164 significantByte = littleEndian; 165 family = "arm"; 166 version = "7"; 167 arch = "armv7-m"; 168 }; 169 armv7l = { 170 bits = 32; 171 significantByte = littleEndian; 172 family = "arm"; 173 version = "7"; 174 arch = "armv7"; 175 }; 176 armv8a = { 177 bits = 32; 178 significantByte = littleEndian; 179 family = "arm"; 180 version = "8"; 181 arch = "armv8-a"; 182 }; 183 armv8r = { 184 bits = 32; 185 significantByte = littleEndian; 186 family = "arm"; 187 version = "8"; 188 arch = "armv8-a"; 189 }; 190 armv8m = { 191 bits = 32; 192 significantByte = littleEndian; 193 family = "arm"; 194 version = "8"; 195 arch = "armv8-m"; 196 }; 197 aarch64 = { 198 bits = 64; 199 significantByte = littleEndian; 200 family = "arm"; 201 version = "8"; 202 arch = "armv8-a"; 203 }; 204 aarch64_be = { 205 bits = 64; 206 significantByte = bigEndian; 207 family = "arm"; 208 version = "8"; 209 arch = "armv8-a"; 210 }; 211 212 i386 = { 213 bits = 32; 214 significantByte = littleEndian; 215 family = "x86"; 216 arch = "i386"; 217 }; 218 i486 = { 219 bits = 32; 220 significantByte = littleEndian; 221 family = "x86"; 222 arch = "i486"; 223 }; 224 i586 = { 225 bits = 32; 226 significantByte = littleEndian; 227 family = "x86"; 228 arch = "i586"; 229 }; 230 i686 = { 231 bits = 32; 232 significantByte = littleEndian; 233 family = "x86"; 234 arch = "i686"; 235 }; 236 x86_64 = { 237 bits = 64; 238 significantByte = littleEndian; 239 family = "x86"; 240 arch = "x86-64"; 241 }; 242 243 microblaze = { 244 bits = 32; 245 significantByte = bigEndian; 246 family = "microblaze"; 247 }; 248 microblazeel = { 249 bits = 32; 250 significantByte = littleEndian; 251 family = "microblaze"; 252 }; 253 254 mips = { 255 bits = 32; 256 significantByte = bigEndian; 257 family = "mips"; 258 }; 259 mipsel = { 260 bits = 32; 261 significantByte = littleEndian; 262 family = "mips"; 263 }; 264 mips64 = { 265 bits = 64; 266 significantByte = bigEndian; 267 family = "mips"; 268 }; 269 mips64el = { 270 bits = 64; 271 significantByte = littleEndian; 272 family = "mips"; 273 }; 274 275 mmix = { 276 bits = 64; 277 significantByte = bigEndian; 278 family = "mmix"; 279 }; 280 281 m68k = { 282 bits = 32; 283 significantByte = bigEndian; 284 family = "m68k"; 285 }; 286 287 powerpc = { 288 bits = 32; 289 significantByte = bigEndian; 290 family = "power"; 291 }; 292 powerpc64 = { 293 bits = 64; 294 significantByte = bigEndian; 295 family = "power"; 296 }; 297 powerpc64le = { 298 bits = 64; 299 significantByte = littleEndian; 300 family = "power"; 301 }; 302 powerpcle = { 303 bits = 32; 304 significantByte = littleEndian; 305 family = "power"; 306 }; 307 308 riscv32 = { 309 bits = 32; 310 significantByte = littleEndian; 311 family = "riscv"; 312 }; 313 riscv64 = { 314 bits = 64; 315 significantByte = littleEndian; 316 family = "riscv"; 317 }; 318 319 s390 = { 320 bits = 32; 321 significantByte = bigEndian; 322 family = "s390"; 323 }; 324 s390x = { 325 bits = 64; 326 significantByte = bigEndian; 327 family = "s390"; 328 }; 329 330 sparc = { 331 bits = 32; 332 significantByte = bigEndian; 333 family = "sparc"; 334 }; 335 sparc64 = { 336 bits = 64; 337 significantByte = bigEndian; 338 family = "sparc"; 339 }; 340 341 wasm32 = { 342 bits = 32; 343 significantByte = littleEndian; 344 family = "wasm"; 345 }; 346 wasm64 = { 347 bits = 64; 348 significantByte = littleEndian; 349 family = "wasm"; 350 }; 351 352 alpha = { 353 bits = 64; 354 significantByte = littleEndian; 355 family = "alpha"; 356 }; 357 358 rx = { 359 bits = 32; 360 significantByte = littleEndian; 361 family = "rx"; 362 }; 363 msp430 = { 364 bits = 16; 365 significantByte = littleEndian; 366 family = "msp430"; 367 }; 368 avr = { 369 bits = 8; 370 family = "avr"; 371 }; 372 373 vc4 = { 374 bits = 32; 375 significantByte = littleEndian; 376 family = "vc4"; 377 }; 378 379 or1k = { 380 bits = 32; 381 significantByte = bigEndian; 382 family = "or1k"; 383 }; 384 385 loongarch64 = { 386 bits = 64; 387 significantByte = littleEndian; 388 family = "loongarch"; 389 }; 390 391 javascript = { 392 bits = 32; 393 significantByte = littleEndian; 394 family = "javascript"; 395 }; 396 } 397 // { 398 # aliases 399 # Apple architecture name, as used by `darwinArch`; required by 400 # LLVM ≥ 20. 401 arm64 = cpuTypes.aarch64; 402 }; 403 404 # GNU build systems assume that older NetBSD architectures are using a.out. 405 gnuNetBSDDefaultExecFormat = 406 cpu: 407 if 408 (cpu.family == "arm" && cpu.bits == 32) 409 || (cpu.family == "sparc" && cpu.bits == 32) 410 || (cpu.family == "m68k" && cpu.bits == 32) 411 || (cpu.family == "x86" && cpu.bits == 32) 412 then 413 execFormats.aout 414 else 415 execFormats.elf; 416 417 # Determine when two CPUs are compatible with each other. That is, 418 # can code built for system B run on system A? For that to happen, 419 # the programs that system B accepts must be a subset of the 420 # programs that system A accepts. 421 # 422 # We have the following properties of the compatibility relation, 423 # which must be preserved when adding compatibility information for 424 # additional CPUs. 425 # - (reflexivity) 426 # Every CPU is compatible with itself. 427 # - (transitivity) 428 # If A is compatible with B and B is compatible with C then A is compatible with C. 429 # 430 # Note: Since 22.11 the archs of a mode switching CPU are no longer considered 431 # pairwise compatible. Mode switching implies that binaries built for A 432 # and B respectively can't be executed at the same time. 433 isCompatible = 434 with cpuTypes; 435 a: b: 436 any id [ 437 # x86 438 (b == i386 && isCompatible a i486) 439 (b == i486 && isCompatible a i586) 440 (b == i586 && isCompatible a i686) 441 442 # XXX: Not true in some cases. Like in WSL mode. 443 (b == i686 && isCompatible a x86_64) 444 445 # ARMv4 446 (b == arm && isCompatible a armv5tel) 447 448 # ARMv5 449 (b == armv5tel && isCompatible a armv6l) 450 451 # ARMv6 452 (b == armv6l && isCompatible a armv6m) 453 (b == armv6m && isCompatible a armv7l) 454 455 # ARMv7 456 (b == armv7l && isCompatible a armv7a) 457 (b == armv7l && isCompatible a armv7r) 458 (b == armv7l && isCompatible a armv7m) 459 460 # ARMv8 461 (b == aarch64 && a == armv8a) 462 (b == armv8a && isCompatible a aarch64) 463 (b == armv8r && isCompatible a armv8a) 464 (b == armv8m && isCompatible a armv8a) 465 466 # PowerPC 467 (b == powerpc && isCompatible a powerpc64) 468 (b == powerpcle && isCompatible a powerpc64le) 469 470 # MIPS 471 (b == mips && isCompatible a mips64) 472 (b == mipsel && isCompatible a mips64el) 473 474 # RISCV 475 (b == riscv32 && isCompatible a riscv64) 476 477 # SPARC 478 (b == sparc && isCompatible a sparc64) 479 480 # WASM 481 (b == wasm32 && isCompatible a wasm64) 482 483 # identity 484 (b == a) 485 ]; 486 487 ################################################################################ 488 489 types.openVendor = mkOptionType { 490 name = "vendor"; 491 description = "vendor for the platform"; 492 merge = mergeOneOption; 493 }; 494 495 types.vendor = enum (attrValues vendors); 496 497 vendors = setTypes types.openVendor { 498 apple = { }; 499 pc = { }; 500 knuth = { }; 501 502 # Actually matters, unlocking some MinGW-w64-specific options in GCC. See 503 # bottom of https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/ 504 w64 = { }; 505 506 none = { }; 507 unknown = { }; 508 }; 509 510 ################################################################################ 511 512 types.openExecFormat = mkOptionType { 513 name = "exec-format"; 514 description = "executable container used by the kernel"; 515 merge = mergeOneOption; 516 }; 517 518 types.execFormat = enum (attrValues execFormats); 519 520 execFormats = setTypes types.openExecFormat { 521 aout = { }; # a.out 522 elf = { }; 523 macho = { }; 524 pe = { }; 525 wasm = { }; 526 527 unknown = { }; 528 }; 529 530 ################################################################################ 531 532 types.openKernelFamily = mkOptionType { 533 name = "exec-format"; 534 description = "executable container used by the kernel"; 535 merge = mergeOneOption; 536 }; 537 538 types.kernelFamily = enum (attrValues kernelFamilies); 539 540 kernelFamilies = setTypes types.openKernelFamily { 541 bsd = { }; 542 darwin = { }; 543 }; 544 545 ################################################################################ 546 547 types.openKernel = mkOptionType { 548 name = "kernel"; 549 description = "kernel name and information"; 550 merge = mergeOneOption; 551 check = 552 x: types.execFormat.check x.execFormat && all types.kernelFamily.check (attrValues x.families); 553 }; 554 555 types.kernel = enum (attrValues kernels); 556 557 kernels = 558 let 559 inherit (execFormats) 560 elf 561 pe 562 wasm 563 unknown 564 macho 565 ; 566 inherit (kernelFamilies) bsd darwin; 567 in 568 setTypes types.openKernel { 569 # TODO(@Ericson2314): Don't want to mass-rebuild yet to keeping 'darwin' as 570 # the normalized name for macOS. 571 macos = { 572 execFormat = macho; 573 families = { inherit darwin; }; 574 name = "darwin"; 575 }; 576 ios = { 577 execFormat = macho; 578 families = { inherit darwin; }; 579 }; 580 freebsd = { 581 execFormat = elf; 582 families = { inherit bsd; }; 583 name = "freebsd"; 584 }; 585 linux = { 586 execFormat = elf; 587 families = { }; 588 }; 589 netbsd = { 590 execFormat = elf; 591 families = { inherit bsd; }; 592 }; 593 none = { 594 execFormat = unknown; 595 families = { }; 596 }; 597 openbsd = { 598 execFormat = elf; 599 families = { inherit bsd; }; 600 }; 601 solaris = { 602 execFormat = elf; 603 families = { }; 604 }; 605 wasi = { 606 execFormat = wasm; 607 families = { }; 608 }; 609 redox = { 610 execFormat = elf; 611 families = { }; 612 }; 613 windows = { 614 execFormat = pe; 615 families = { }; 616 }; 617 cygwin = { 618 execFormat = pe; 619 families = { }; 620 }; 621 ghcjs = { 622 execFormat = unknown; 623 families = { }; 624 }; 625 genode = { 626 execFormat = elf; 627 families = { }; 628 }; 629 mmixware = { 630 execFormat = unknown; 631 families = { }; 632 }; 633 uefi = { 634 execFormat = pe; 635 families = { }; 636 }; 637 } 638 // { 639 # aliases 640 # 'darwin' is the kernel for all of them. We choose macOS by default. 641 darwin = kernels.macos; 642 watchos = kernels.ios; 643 tvos = kernels.ios; 644 win32 = kernels.windows; 645 }; 646 647 ################################################################################ 648 649 types.openAbi = mkOptionType { 650 name = "abi"; 651 description = "binary interface for compiled code and syscalls"; 652 merge = mergeOneOption; 653 }; 654 655 types.abi = enum (attrValues abis); 656 657 abis = setTypes types.openAbi { 658 msvc = { }; 659 660 # Note: eabi is specific to ARM and PowerPC. 661 # On PowerPC, this corresponds to PPCEABI. 662 # On ARM, this corresponds to ARMEABI. 663 eabi = { 664 float = "soft"; 665 eabi = true; 666 }; 667 eabihf = { 668 float = "hard"; 669 eabi = true; 670 }; 671 672 # Other architectures should use ELF in embedded situations. 673 elf = { }; 674 675 androideabi = { 676 eabi = true; 677 }; 678 android = { 679 assertions = [ 680 { 681 assertion = platform: !platform.isAarch32; 682 message = '' 683 The "android" ABI is not for 32-bit ARM. Use "androideabi" instead. 684 ''; 685 } 686 ]; 687 }; 688 689 gnueabi = { 690 float = "soft"; 691 eabi = true; 692 }; 693 gnueabihf = { 694 float = "hard"; 695 eabi = true; 696 }; 697 gnu = { 698 assertions = [ 699 { 700 assertion = platform: !platform.isAarch32; 701 message = '' 702 The "gnu" ABI is ambiguous on 32-bit ARM. Use "gnueabi" or "gnueabihf" instead. 703 ''; 704 } 705 { 706 assertion = platform: !(platform.isPower64 && platform.isBigEndian); 707 message = '' 708 The "gnu" ABI is ambiguous on big-endian 64-bit PowerPC. Use "gnuabielfv2" or "gnuabielfv1" instead. 709 ''; 710 } 711 ]; 712 }; 713 gnuabi64 = { 714 abi = "64"; 715 }; 716 muslabi64 = { 717 abi = "64"; 718 }; 719 720 # NOTE: abi=n32 requires a 64-bit MIPS chip! That is not a typo. 721 # It is basically the 64-bit abi with 32-bit pointers. Details: 722 # https://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf 723 gnuabin32 = { 724 abi = "n32"; 725 }; 726 muslabin32 = { 727 abi = "n32"; 728 }; 729 730 gnuabielfv2 = { 731 abi = "elfv2"; 732 }; 733 gnuabielfv1 = { 734 abi = "elfv1"; 735 }; 736 737 musleabi = { 738 float = "soft"; 739 eabi = true; 740 }; 741 musleabihf = { 742 float = "hard"; 743 eabi = true; 744 }; 745 musl = { }; 746 747 uclibceabi = { 748 float = "soft"; 749 eabi = true; 750 }; 751 uclibceabihf = { 752 float = "hard"; 753 eabi = true; 754 }; 755 uclibc = { }; 756 757 unknown = { }; 758 }; 759 760 ################################################################################ 761 762 types.parsedPlatform = mkOptionType { 763 name = "system"; 764 description = "fully parsed representation of llvm- or nix-style platform tuple"; 765 merge = mergeOneOption; 766 check = 767 { 768 cpu, 769 vendor, 770 kernel, 771 abi, 772 }: 773 types.cpuType.check cpu 774 && types.vendor.check vendor 775 && types.kernel.check kernel 776 && types.abi.check abi; 777 }; 778 779 isSystem = isType "system"; 780 781 mkSystem = 782 components: 783 assert types.parsedPlatform.check components; 784 setType "system" components; 785 786 mkSkeletonFromList = 787 l: 788 { 789 "1" = 790 if elemAt l 0 == "avr" then 791 { 792 cpu = elemAt l 0; 793 kernel = "none"; 794 abi = "unknown"; 795 } 796 else 797 throw "system string '${lib.concatStringsSep "-" l}' with 1 component is ambiguous"; 798 "2" = # We only do 2-part hacks for things Nix already supports 799 if elemAt l 1 == "cygwin" then 800 mkSkeletonFromList [ 801 (elemAt l 0) 802 "pc" 803 "cygwin" 804 ] 805 # MSVC ought to be the default ABI so this case isn't needed. But then it 806 # becomes difficult to handle the gnu* variants for Aarch32 correctly for 807 # minGW. So it's easier to make gnu* the default for the MinGW, but 808 # hack-in MSVC for the non-MinGW case right here. 809 else if elemAt l 1 == "windows" then 810 { 811 cpu = elemAt l 0; 812 kernel = "windows"; 813 abi = "msvc"; 814 } 815 else if (elemAt l 1) == "elf" then 816 { 817 cpu = elemAt l 0; 818 vendor = "unknown"; 819 kernel = "none"; 820 abi = elemAt l 1; 821 } 822 else 823 { 824 cpu = elemAt l 0; 825 kernel = elemAt l 1; 826 }; 827 "3" = 828 # cpu-kernel-environment 829 if 830 elemAt l 1 == "linux" 831 || elem (elemAt l 2) [ 832 "eabi" 833 "eabihf" 834 "elf" 835 "gnu" 836 ] 837 then 838 { 839 cpu = elemAt l 0; 840 kernel = elemAt l 1; 841 abi = elemAt l 2; 842 vendor = "unknown"; 843 } 844 # cpu-vendor-os 845 else if 846 elemAt l 1 == "apple" 847 || elem (elemAt l 2) [ 848 "redox" 849 "mmixware" 850 "ghcjs" 851 "mingw32" 852 "uefi" 853 ] 854 || hasPrefix "freebsd" (elemAt l 2) 855 || hasPrefix "netbsd" (elemAt l 2) 856 || hasPrefix "openbsd" (elemAt l 2) 857 || hasPrefix "genode" (elemAt l 2) 858 || hasPrefix "wasm32" (elemAt l 0) 859 then 860 { 861 cpu = elemAt l 0; 862 vendor = elemAt l 1; 863 kernel = 864 if elemAt l 2 == "mingw32" then 865 "windows" # autotools breaks on -gnu for window 866 else 867 elemAt l 2; 868 } 869 # lots of tools expect a triplet for Cygwin, even though the vendor is just "pc" 870 else if elemAt l 2 == "cygwin" then 871 { 872 cpu = elemAt l 0; 873 vendor = elemAt l 1; 874 kernel = "cygwin"; 875 } 876 else 877 throw "system string '${lib.concatStringsSep "-" l}' with 3 components is ambiguous"; 878 "4" = { 879 cpu = elemAt l 0; 880 vendor = elemAt l 1; 881 kernel = elemAt l 2; 882 abi = elemAt l 3; 883 }; 884 } 885 .${toString (length l)} 886 or (throw "system string '${lib.concatStringsSep "-" l}' has invalid number of hyphen-separated components"); 887 888 # This should revert the job done by config.guess from the gcc compiler. 889 mkSystemFromSkeleton = 890 { 891 cpu, 892 # Optional, but fallback too complex for here. 893 # Inferred below instead. 894 vendor ? 895 assert false; 896 null, 897 kernel, 898 # Also inferred below 899 abi ? 900 assert false; 901 null, 902 }@args: 903 let 904 getCpu = name: cpuTypes.${name} or (throw "Unknown CPU type: ${name}"); 905 getVendor = name: vendors.${name} or (throw "Unknown vendor: ${name}"); 906 getKernel = name: kernels.${name} or (throw "Unknown kernel: ${name}"); 907 getAbi = name: abis.${name} or (throw "Unknown ABI: ${name}"); 908 909 parsed = { 910 cpu = getCpu args.cpu; 911 vendor = 912 if args ? vendor then 913 getVendor args.vendor 914 else if isDarwin parsed then 915 vendors.apple 916 else if (isWindows parsed || isCygwin parsed) then 917 vendors.pc 918 else 919 vendors.unknown; 920 kernel = 921 if hasPrefix "darwin" args.kernel then 922 getKernel "darwin" 923 else if hasPrefix "netbsd" args.kernel then 924 getKernel "netbsd" 925 else 926 getKernel (removeAbiSuffix args.kernel); 927 abi = 928 if args ? abi then 929 getAbi args.abi 930 else if isLinux parsed || isWindows parsed then 931 if isAarch32 parsed then 932 if versionAtLeast (parsed.cpu.version or "0") "6" then abis.gnueabihf else abis.gnueabi 933 # Default ppc64 BE to ELFv1 934 else if isPower64 parsed && isBigEndian parsed then 935 abis.gnuabielfv1 936 else 937 abis.gnu 938 else 939 abis.unknown; 940 }; 941 942 in 943 mkSystem parsed; 944 945 mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (splitString "-" s)); 946 947 kernelName = kernel: kernel.name + toString (kernel.version or ""); 948 949 darwinArch = cpu: if cpu.name == "aarch64" then "arm64" else cpu.name; 950 951 doubleFromSystem = 952 { 953 cpu, 954 kernel, 955 abi, 956 ... 957 }: 958 if kernel.families ? darwin then "${cpu.name}-darwin" else "${cpu.name}-${kernelName kernel}"; 959 960 tripleFromSystem = 961 { 962 cpu, 963 vendor, 964 kernel, 965 abi, 966 ... 967 }@sys: 968 assert isSystem sys; 969 let 970 optExecFormat = optionalString ( 971 kernel.name == "netbsd" && gnuNetBSDDefaultExecFormat cpu != kernel.execFormat 972 ) kernel.execFormat.name; 973 optAbi = optionalString (abi != abis.unknown) "-${abi.name}"; 974 cpuName = if kernel.families ? darwin then darwinArch cpu else cpu.name; 975 in 976 "${cpuName}-${vendor.name}-${kernelName kernel}${optExecFormat}${optAbi}"; 977 978 # This is a function from parsed platforms (like stdenv.hostPlatform.parsed) 979 # to parsed platforms. 980 mkMuslSystem = 981 parsed: 982 # The following line guarantees that the output of this function 983 # is a well-formed platform with no missing fields. 984 ( 985 x: 986 lib.trivial.pipe x [ 987 (x: removeAttrs x [ "_type" ]) 988 mkSystem 989 ] 990 ) 991 ( 992 parsed 993 // { 994 abi = 995 { 996 gnu = abis.musl; 997 gnueabi = abis.musleabi; 998 gnueabihf = abis.musleabihf; 999 gnuabin32 = abis.muslabin32; 1000 gnuabi64 = abis.muslabi64; 1001 gnuabielfv2 = abis.musl; 1002 gnuabielfv1 = abis.musl; 1003 # The following entries ensure that this function is idempotent. 1004 musleabi = abis.musleabi; 1005 musleabihf = abis.musleabihf; 1006 muslabin32 = abis.muslabin32; 1007 muslabi64 = abis.muslabi64; 1008 } 1009 .${parsed.abi.name} or abis.musl; 1010 } 1011 ); 1012 1013 ################################################################################ 1014 1015}