2 let inherit (lib.attrsets) mapAttrs; in
5 doubles = import ./doubles.nix { inherit lib; };
6 parse = import ./parse.nix { inherit lib; };
7 inspect = import ./inspect.nix { inherit lib; };
8 platforms = import ./platforms.nix { inherit lib; };
9 examples = import ./examples.nix { inherit lib; };
10 architectures = import ./architectures.nix { inherit lib; };
12 /* List of all Nix system doubles the nixpkgs flake will expose the package set
13 for. All systems listed here must be supported by nixpkgs as `localSystem`.
15 **Warning**: This attribute is considered experimental and is subject to change.
17 flakeExposed = import ./flake-systems.nix { };
19 # Elaborate a `localSystem` or `crossSystem` so that it contains everything
22 # `parsed` is inferred from args, both because there are two options with one
23 # clearly prefered, and to prevent cycles. A simpler fixed point where the RHS
24 # always just used `final.*` would fail on both counts.
25 elaborate = args': let
26 args = if lib.isString args' then { system = args'; }
29 # Prefer to parse `config` as it is strictly more informative.
30 parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
31 # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds.
32 system = parse.doubleFromSystem final.parsed;
33 config = parse.tripleFromSystem final.parsed;
34 # Determine whether we can execute binaries built for the provided platform.
35 canExecute = platform:
36 final.isAndroid == platform.isAndroid &&
37 parse.isCompatible final.parsed.cpu platform.parsed.cpu
38 && final.parsed.kernel == platform.parsed.kernel;
39 isCompatible = _: throw "2022-05-23: isCompatible has been removed in favor of canExecute, refer to the 22.11 changelog for details";
42 /**/ if final.isDarwin then "libSystem"
43 else if final.isMinGW then "msvcrt"
44 else if final.isWasi then "wasilibc"
45 else if final.isRedox then "relibc"
46 else if final.isMusl then "musl"
47 else if final.isUClibc then "uclibc"
48 else if final.isAndroid then "bionic"
49 else if final.isLinux /* default */ then "glibc"
50 else if final.isFreeBSD then "fblibc"
51 else if final.isNetBSD then "nblibc"
52 else if final.isAvr then "avrlibc"
53 else if final.isNone then "newlib"
54 # TODO(@Ericson2314) think more about other operating systems
56 # Choose what linker we wish to use by default. Someday we might also
57 # choose the C compiler, runtime library, C++ standard library, etc. in
58 # this way, nice and orthogonally, and deprecate `useLLVM`. But due to
59 # the monolithic GCC build we cannot actually make those choices
60 # independently, so we are just doing `linker` and keeping `useLLVM` for
63 /**/ if final.useLLVM or false then "lld"
64 else if final.isDarwin then "cctools"
65 # "bfd" and "gold" both come from GNU binutils. The existance of Gold
66 # is why we use the more obscure "bfd" and not "binutils" for this
71 /**/ if final.isDarwin then ".dylib"
72 else if final.isWindows then ".dll"
75 /**/ if final.isWindows then ".lib"
78 /**/ if final.isStatic then staticLibrary
81 /**/ if final.isWindows then ".exe"
84 # Misc boolean options
85 useAndroidPrebuilt = false;
86 useiOSPrebuilt = false;
101 }.${final.parsed.kernel.name} or null;
104 processor = final.parsed.cpu.name;
109 isStatic = final.isWasm || final.isRedox;
111 # Just a guess, based on `system`
114 linux-kernel = args.linux-kernel or {};
115 gcc = args.gcc or {};
116 rustc = args.rust or {};
117 } // platforms.select final)
118 linux-kernel gcc rustc;
121 if final.isAarch32 then "arm"
122 else if final.isAarch64 then "arm64"
123 else if final.isx86_32 then "i386"
124 else if final.isx86_64 then "x86_64"
125 # linux kernel does not distinguish microblaze/microblazeel
126 else if final.isMicroBlaze then "microblaze"
127 else if final.isMips32 then "mips"
128 else if final.isMips64 then "mips" # linux kernel does not distinguish mips32/mips64
129 else if final.isPower then "powerpc"
130 else if final.isRiscV then "riscv"
131 else if final.isS390 then "s390"
132 else final.parsed.cpu.name;
135 if final.isAarch32 then "arm"
136 else if final.isx86_64 then "x86_64"
137 else if final.isx86 then "i386"
142 powerpc64le = "ppc64le";
143 }.${final.parsed.cpu.name} or final.parsed.cpu.name;
145 # Name used by UEFI for architectures.
147 if final.isx86_32 then "ia32"
148 else if final.isx86_64 then "x64"
149 else if final.isAarch32 then "arm"
150 else if final.isAarch64 then "aa64"
151 else final.parsed.cpu.name;
156 }.${final.parsed.cpu.name} or final.parsed.cpu.name;
159 if final.isMacOS then "macos"
160 else if final.isiOS then "ios"
162 # The canonical name for this attribute is darwinSdkVersion, but some
163 # platforms define the old name "sdkVer".
164 darwinSdkVersion = final.sdkVer or (if final.isAarch64 then "11.0" else "10.12");
165 darwinMinVersion = final.darwinSdkVersion;
166 darwinMinVersionVariable =
167 if final.isMacOS then "MACOSX_DEPLOYMENT_TARGET"
168 else if final.isiOS then "IPHONEOS_DEPLOYMENT_TARGET"
172 selectEmulator = pkgs:
174 qemu-user = pkgs.qemu.override {
175 smartcardSupport = false;
176 spiceSupport = false;
177 openGLSupport = false;
178 virglSupport = false;
182 pulseSupport = false;
184 seccompSupport = false;
185 hostCpuTargets = [ "${final.qemuArch}-linux-user" ];
187 wine = (pkgs.winePackagesFor "wine${toString final.parsed.cpu.bits}").minimal;
189 if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name &&
190 pkgs.stdenv.hostPlatform.canExecute final
191 then "${pkgs.runtimeShell} -c '\"$@\"' --"
192 else if final.isWindows
193 then "${wine}/bin/wine${lib.optionalString (final.parsed.cpu.bits == 64) "64"}"
194 else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
195 then "${qemu-user}/bin/qemu-${final.qemuArch}"
197 then "${pkgs.wasmtime}/bin/wasmtime"
199 then "${pkgs.mmixware}/bin/mmix"
202 emulatorAvailable = pkgs: (selectEmulator pkgs) != null;
205 if (final.emulatorAvailable pkgs)
206 then selectEmulator pkgs
207 else throw "Don't know how to run ${final.config} executables.";
209 }) // mapAttrs (n: v: v final.parsed) inspect.predicates
210 // mapAttrs (n: v: v final.gcc.arch or "default") architectures.predicates
212 in assert final.useAndroidPrebuilt -> final.isAndroid;
214 (pass: { assertion, message }:
219 (final.parsed.abi.assertions or []);