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