nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
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}