at 21.11-pre 7.1 kB view raw
1{ lib }: 2 let inherit (lib.attrsets) mapAttrs; in 3 4rec { 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; }; 11 12 # Elaborate a `localSystem` or `crossSystem` so that it contains everything 13 # necessary. 14 # 15 # `parsed` is inferred from args, both because there are two options with one 16 # clearly prefered, and to prevent cycles. A simpler fixed point where the RHS 17 # always just used `final.*` would fail on both counts. 18 elaborate = args': let 19 args = if lib.isString args' then { system = args'; } 20 else args'; 21 final = { 22 # Prefer to parse `config` as it is strictly more informative. 23 parsed = parse.mkSystemFromString (if args ? config then args.config else args.system); 24 # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds. 25 system = parse.doubleFromSystem final.parsed; 26 config = parse.tripleFromSystem final.parsed; 27 # Determine whether we are compatible with the provided CPU 28 isCompatible = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu; 29 # Derived meta-data 30 libc = 31 /**/ if final.isDarwin then "libSystem" 32 else if final.isMinGW then "msvcrt" 33 else if final.isWasi then "wasilibc" 34 else if final.isRedox then "relibc" 35 else if final.isMusl then "musl" 36 else if final.isUClibc then "uclibc" 37 else if final.isAndroid then "bionic" 38 else if final.isLinux /* default */ then "glibc" 39 else if final.isAvr then "avrlibc" 40 else if final.isNone then "newlib" 41 else if final.isNetBSD then "nblibc" 42 # TODO(@Ericson2314) think more about other operating systems 43 else "native/impure"; 44 # Choose what linker we wish to use by default. Someday we might also 45 # choose the C compiler, runtime library, C++ standard library, etc. in 46 # this way, nice and orthogonally, and deprecate `useLLVM`. But due to 47 # the monolithic GCC build we cannot actually make those choices 48 # independently, so we are just doing `linker` and keeping `useLLVM` for 49 # now. 50 linker = 51 /**/ if final.useLLVM or false then "lld" 52 else if final.isDarwin then "cctools" 53 # "bfd" and "gold" both come from GNU binutils. The existance of Gold 54 # is why we use the more obscure "bfd" and not "binutils" for this 55 # choice. 56 else "bfd"; 57 extensions = { 58 sharedLibrary = 59 /**/ if final.isDarwin then ".dylib" 60 else if final.isWindows then ".dll" 61 else ".so"; 62 executable = 63 /**/ if final.isWindows then ".exe" 64 else ""; 65 }; 66 # Misc boolean options 67 useAndroidPrebuilt = false; 68 useiOSPrebuilt = false; 69 70 # Output from uname 71 uname = { 72 # uname -s 73 system = { 74 linux = "Linux"; 75 windows = "Windows"; 76 darwin = "Darwin"; 77 netbsd = "NetBSD"; 78 freebsd = "FreeBSD"; 79 openbsd = "OpenBSD"; 80 wasi = "Wasi"; 81 redox = "Redox"; 82 genode = "Genode"; 83 }.${final.parsed.kernel.name} or null; 84 85 # uname -p 86 processor = final.parsed.cpu.name; 87 88 # uname -r 89 release = null; 90 }; 91 isStatic = final.isWasm || final.isRedox; 92 93 # Just a guess, based on `system` 94 inherit 95 ({ 96 linux-kernel = args.linux-kernel or {}; 97 gcc = args.gcc or {}; 98 rustc = args.rust or {}; 99 } // platforms.select final) 100 linux-kernel gcc rustc; 101 102 linuxArch = 103 if final.isAarch32 then "arm" 104 else if final.isAarch64 then "arm64" 105 else if final.isx86_32 then "i386" 106 else if final.isx86_64 then "x86_64" 107 else if final.isMips then "mips" 108 else if final.isPower then "powerpc" 109 else if final.isRiscV then "riscv" 110 else final.parsed.cpu.name; 111 112 qemuArch = 113 if final.isAarch32 then "arm" 114 else if final.isx86_64 then "x86_64" 115 else if final.isx86 then "i386" 116 else { 117 powerpc = "ppc"; 118 powerpcle = "ppc"; 119 powerpc64 = "ppc64"; 120 powerpc64le = "ppc64le"; 121 }.${final.parsed.cpu.name} or final.parsed.cpu.name; 122 123 darwinArch = { 124 armv7a = "armv7"; 125 aarch64 = "arm64"; 126 }.${final.parsed.cpu.name} or final.parsed.cpu.name; 127 128 darwinPlatform = 129 if final.isMacOS then "macos" 130 else if final.isiOS then "ios" 131 else null; 132 # The canonical name for this attribute is darwinSdkVersion, but some 133 # platforms define the old name "sdkVer". 134 darwinSdkVersion = final.sdkVer or (if final.isAarch64 then "11.0" else "10.12"); 135 darwinMinVersion = final.darwinSdkVersion; 136 darwinMinVersionVariable = 137 if final.isMacOS then "MACOSX_DEPLOYMENT_TARGET" 138 else if final.isiOS then "IPHONEOS_DEPLOYMENT_TARGET" 139 else null; 140 141 emulator = pkgs: let 142 qemu-user = pkgs.qemu.override { 143 smartcardSupport = false; 144 spiceSupport = false; 145 openGLSupport = false; 146 virglSupport = false; 147 vncSupport = false; 148 gtkSupport = false; 149 sdlSupport = false; 150 pulseSupport = false; 151 smbdSupport = false; 152 seccompSupport = false; 153 hostCpuTargets = ["${final.qemuArch}-linux-user"]; 154 }; 155 wine-name = "wine${toString final.parsed.cpu.bits}"; 156 wine = (pkgs.winePackagesFor wine-name).minimal; 157 in 158 if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name && 159 pkgs.stdenv.hostPlatform.isCompatible final 160 then "${pkgs.runtimeShell} -c '\"$@\"' --" 161 else if final.isWindows 162 then "${wine}/bin/${wine-name}" 163 else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux 164 then "${qemu-user}/bin/qemu-${final.qemuArch}" 165 else if final.isWasi 166 then "${pkgs.wasmtime}/bin/wasmtime" 167 else if final.isMmix 168 then "${pkgs.mmixware}/bin/mmix" 169 else throw "Don't know how to run ${final.config} executables."; 170 171 } // mapAttrs (n: v: v final.parsed) inspect.predicates 172 // mapAttrs (n: v: v final.gcc.arch or "default") architectures.predicates 173 // args; 174 in assert final.useAndroidPrebuilt -> final.isAndroid; 175 assert lib.foldl 176 (pass: { assertion, message }: 177 if assertion final 178 then pass 179 else throw message) 180 true 181 (final.parsed.abi.assertions or []); 182 final; 183}