diff --git a/lib/systems/default.nix b/lib/systems/default.nix index f60ece0c8f5c..fd4ed9777b52 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -11,7 +11,6 @@ let isList mapAttrs optional - optionalAttrs optionalString removeSuffix replaceString @@ -84,6 +83,29 @@ let # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL. rust = args.rust or args.rustc or { }; + selectEmulator = + pkgs: + let + wine = (pkgs.winePackagesFor "wine${toString final.parsed.cpu.bits}").minimal; + in + # Note: we guarantee that the return value is either `null` or a path + # to an emulator program. That is, if an emulator requires additional + # arguments, a wrapper should be used. + if pkgs.stdenv.hostPlatform.canExecute final then + lib.getExe (pkgs.writeShellScriptBin "exec" ''exec "$@"'') + else if final.isWindows then + "${wine}/bin/wine" + else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux && final.qemuArch != null then + "${pkgs.qemu-user}/bin/qemu-${final.qemuArch}" + else if final.isWasi then + "${pkgs.wasmtime}/bin/wasmtime" + else if final.isGhcjs then + "${pkgs.nodejs-slim}/bin/node" + else if final.isMmix then + "${pkgs.mmixware}/bin/mmix" + else + null; + final = { # Prefer to parse `config` as it is strictly more informative. parsed = parse.mkSystemFromString (args.config or allArgs.system); @@ -178,21 +200,19 @@ let if final.isx86_64 || final.isMips64 || final.isPower64 then "lib64" else "lib" else null; - extensions = - optionalAttrs final.hasSharedLibraries { - sharedLibrary = - if final.isDarwin then - ".dylib" - else if (final.isWindows || final.isCygwin) then - ".dll" - else - ".so"; - } - // { - staticLibrary = if final.isWindows then ".lib" else ".a"; - library = if final.isStatic then final.extensions.staticLibrary else final.extensions.sharedLibrary; - executable = if (final.isWindows || final.isCygwin) then ".exe" else ""; - }; + extensions = { + staticLibrary = if final.isWindows then ".lib" else ".a"; + library = if final.isStatic then final.extensions.staticLibrary else final.extensions.sharedLibrary; + executable = if (final.isWindows || final.isCygwin) then ".exe" else ""; + + ${if final.hasSharedLibraries then "sharedLibrary" else null} = + if final.isDarwin then + ".dylib" + else if (final.isWindows || final.isCygwin) then + ".dll" + else + ".so"; + }; # Misc boolean options useAndroidPrebuilt = false; useiOSPrebuilt = false; @@ -373,48 +393,21 @@ let # Handle Android SDK and NDK versions. androidSdkVersion = args.androidSdkVersion or null; androidNdkVersion = args.androidNdkVersion or null; + + emulatorAvailable = pkgs: selectEmulator pkgs != null; + + # whether final.emulator pkgs.pkgsStatic works + staticEmulatorAvailable = + pkgs: final.emulatorAvailable pkgs && (final.isLinux || final.isWasi || final.isMmix); + + emulator = + pkgs: + if (final.emulatorAvailable pkgs) then + selectEmulator pkgs + else + throw "Don't know how to run ${final.config} executables."; + } - // ( - let - selectEmulator = - pkgs: - let - wine = (pkgs.winePackagesFor "wine${toString final.parsed.cpu.bits}").minimal; - in - # Note: we guarantee that the return value is either `null` or a path - # to an emulator program. That is, if an emulator requires additional - # arguments, a wrapper should be used. - if pkgs.stdenv.hostPlatform.canExecute final then - lib.getExe (pkgs.writeShellScriptBin "exec" ''exec "$@"'') - else if final.isWindows then - "${wine}/bin/wine" - else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux && final.qemuArch != null then - "${pkgs.qemu-user}/bin/qemu-${final.qemuArch}" - else if final.isWasi then - "${pkgs.wasmtime}/bin/wasmtime" - else if final.isGhcjs then - "${pkgs.nodejs-slim}/bin/node" - else if final.isMmix then - "${pkgs.mmixware}/bin/mmix" - else - null; - in - { - emulatorAvailable = pkgs: (selectEmulator pkgs) != null; - - # whether final.emulator pkgs.pkgsStatic works - staticEmulatorAvailable = - pkgs: final.emulatorAvailable pkgs && (final.isLinux || final.isWasi || final.isMmix); - - emulator = - pkgs: - if (final.emulatorAvailable pkgs) then - selectEmulator pkgs - else - throw "Don't know how to run ${final.config} executables."; - - } - ) // mapAttrs (n: v: v final.parsed) inspect.predicates // mapAttrs (n: v: v final.gcc.arch or "default") architectures.predicates // args @@ -556,8 +549,6 @@ let "-uefi" ]; }; - } - // { go = { # See https://pkg.go.dev/internal/platform for a list of known platforms GOARCH = diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 626b5bcb41ac..98db2595235f 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -24,6 +24,7 @@ let elem elemAt hasPrefix + head id length mapAttrs @@ -68,7 +69,7 @@ let let found = match "(.*)e?abi.*" x; in - if found == null then x else elemAt found 0; + if found == null then x else head found; in @@ -417,10 +418,8 @@ rec { gnuNetBSDDefaultExecFormat = cpu: if - (cpu.family == "arm" && cpu.bits == 32) - || (cpu.family == "sparc" && cpu.bits == 32) - || (cpu.family == "m68k" && cpu.bits == 32) - || (cpu.family == "x86" && cpu.bits == 32) + cpu.bits == 32 + && (cpu.family == "arm" || cpu.family == "sparc" || cpu.family == "m68k" || cpu.family == "x86") then execFormats.aout else @@ -445,7 +444,8 @@ rec { isCompatible = with cpuTypes; a: b: - any id [ + b == a + || any id [ # x86 (b == i386 && isCompatible a i486) (b == i486 && isCompatible a i586) @@ -483,9 +483,6 @@ rec { # SPARC (b == sparc && isCompatible a sparc64) - - # identity - (b == a) ]; ################################################################################ @@ -791,9 +788,9 @@ rec { l: { "1" = - if elemAt l 0 == "avr" then + if head l == "avr" then { - cpu = elemAt l 0; + cpu = head l; kernel = "none"; abi = "unknown"; } @@ -802,7 +799,7 @@ rec { "2" = # We only do 2-part hacks for things Nix already supports if elemAt l 1 == "cygwin" then mkSkeletonFromList [ - (elemAt l 0) + (head l) "pc" "cygwin" ] @@ -812,20 +809,20 @@ rec { # hack-in MSVC for the non-MinGW case right here. else if elemAt l 1 == "windows" then { - cpu = elemAt l 0; + cpu = head l; kernel = "windows"; abi = "msvc"; } else if (elemAt l 1) == "elf" then { - cpu = elemAt l 0; + cpu = head l; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; } else { - cpu = elemAt l 0; + cpu = head l; kernel = elemAt l 1; }; "3" = @@ -840,7 +837,7 @@ rec { ] then { - cpu = elemAt l 0; + cpu = head l; kernel = elemAt l 1; abi = elemAt l 2; vendor = "unknown"; @@ -862,7 +859,7 @@ rec { || hasPrefix "wasm32" (elemAt l 0) then { - cpu = elemAt l 0; + cpu = head l; vendor = elemAt l 1; kernel = if elemAt l 2 == "mingw32" then @@ -873,14 +870,14 @@ rec { # lots of tools expect a triplet for Cygwin, even though the vendor is just "pc" else if elemAt l 2 == "cygwin" then { - cpu = elemAt l 0; + cpu = head l; vendor = elemAt l 1; kernel = "cygwin"; } else throw "system string '${lib.concatStringsSep "-" l}' with 3 components is ambiguous"; "4" = { - cpu = elemAt l 0; + cpu = head l; vendor = elemAt l 1; kernel = elemAt l 2; abi = elemAt l 3;