From 577b48177488b96a25b45a735ce63648cc309d8f Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:37:00 -0400 Subject: [PATCH 1/5] lib.systems.parse: use `builtins.head foo` instead of `elemAt foo 0` --- lib/systems/parse.nix | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 626b5bcb41ac..0e3a6c2a1239 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 @@ -791,9 +792,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 +803,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 +813,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 +841,7 @@ rec { ] then { - cpu = elemAt l 0; + cpu = head l; kernel = elemAt l 1; abi = elemAt l 2; vendor = "unknown"; @@ -862,7 +863,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 +874,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; From 7fcbff801da7e94701efd93369f090e025ee85dd Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:37:30 -0400 Subject: [PATCH 2/5] lib.systems.parse: only check condition once --- lib/systems/parse.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 0e3a6c2a1239..3f636442ee9d 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -418,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 From a9c0a094f7e4a530b4681d654d78c087b9441d52 Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Sun, 26 Apr 2026 21:12:16 -0400 Subject: [PATCH 3/5] lib.systems.elaborate: avoid optionalAttrs merge --- lib/systems/default.nix | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/systems/default.nix b/lib/systems/default.nix index f60ece0c8f5c..31bf8367462f 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -11,7 +11,6 @@ let isList mapAttrs optional - optionalAttrs optionalString removeSuffix replaceString @@ -178,21 +177,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; From 833f05d0994512c721c035c3874078973a2698f6 Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:40:11 -0400 Subject: [PATCH 4/5] lib.systems.elaborate: prevent unnecessary attrset merges --- lib/systems/default.nix | 80 +++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 31bf8367462f..fd4ed9777b52 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -83,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); @@ -370,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 @@ -553,8 +549,6 @@ let "-uefi" ]; }; - } - // { go = { # See https://pkg.go.dev/internal/platform for a list of known platforms GOARCH = From acd5585a3ba8481395f5897ba6060af176ef7539 Mon Sep 17 00:00:00 2001 From: Eman Resu <78693624+quatquatt@users.noreply.github.com> Date: Sun, 3 May 2026 16:48:10 -0400 Subject: [PATCH 5/5] lib.systems.parse: check if cpus are equal first Rather than doing this last, we do it first. Saves a little time if we're comparing to an identical platform --- lib/systems/parse.nix | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 3f636442ee9d..98db2595235f 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -444,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) @@ -482,9 +483,6 @@ rec { # SPARC (b == sparc && isCompatible a sparc64) - - # identity - (b == a) ]; ################################################################################