From f455a07f13934285931c8bfc97fe10a3f0f3430d Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Thu, 21 Feb 2019 22:17:51 -0500 Subject: systems: add isCompatible handling --- lib/systems/default.nix | 5 +++-- lib/systems/parse.nix | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 77f20095295..b24eb4245ff 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -24,6 +24,8 @@ rec { config = parse.tripleFromSystem final.parsed; # Just a guess, based on `system` platform = platforms.selectBySystem final.system; + # Determine whether we are compatible with the provided CPU + isCompatible = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu; # Derived meta-data libc = /**/ if final.isDarwin then "libSystem" @@ -98,8 +100,7 @@ rec { wine = (pkgs.winePackagesFor wine-name).minimal; in if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name && - (final.parsed.cpu.name == pkgs.stdenv.hostPlatform.parsed.cpu.name || - (final.isi686 && pkgs.stdenv.hostPlatform.isx86_64)) + pkgs.stdenv.hostPlatform.isCompatible final then pkgs.runtimeShell else if final.isWindows then "${wine}/bin/${wine-name}" diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 6947d41419e..fab50bc0ebd 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -112,6 +112,66 @@ rec { avr = { bits = 8; family = "avr"; }; }; + # Determine where two CPUs are compatible with each other. That is, + # can we run code built for system b on system a? For that to + # happen, then the set of all possible possible programs that system + # b accepts must be a subset of the set of all programs that system + # a accepts. This compatibility relation forms a category where each + # CPU is an object and each arrow from a to b represents + # compatibility. CPUs with multiple modes of Endianness are + # isomorphic while all CPUs are endomorphic because any program + # built for a CPU can run on that CPU. + isCompatible = a: b: with cpuTypes; lib.any lib.id [ + # x86 + (b == i386 && isCompatible a i486) + (b == i486 && isCompatible a i586) + (b == i586 && isCompatible a i686) + # NOTE: Not true in some cases. Like in WSL mode. + (b == i686 && isCompatible a x86_64) + + # ARM + (b == arm && isCompatible a armv5tel) + (b == armv5tel && isCompatible a armv6m) + (b == armv6m && isCompatible a armv6l) + (b == armv6l && isCompatible a armv7a) + (b == armv7a && isCompatible a armv7r) + (b == armv7r && isCompatible a armv7m) + (b == armv7m && isCompatible a armv7l) + (b == armv7l && isCompatible a armv8a) + (b == armv8a && isCompatible a armv8r) + (b == armv8r && isCompatible a armv8m) + # NOTE: not always true! Some arm64 cpus don’t support arm32 mode. + (b == armv8m && isCompatible a aarch64) + (b == aarch64 && a == aarch64_be) + (b == aarch64_be && isCompatible a aarch64) + + # PowerPC + (b == powerpc && isCompatible a powerpc64) + (b == powerpcle && isCompatible a powerpc) + (b == powerpc && a == powerpcle) + (b == powerpc64le && isCompatible a powerpc64) + (b == powerpc64 && a == powerpc64le) + + # MIPS + (b == mips && isCompatible a mips64) + (b == mips && a == mipsel) + (b == mipsel && isCompatible a mips) + (b == mips64 && a == mips64el) + (b == mips64el && isCompatible a mips64) + + # RISCV + (b == riscv32 && isCompatible a riscv64) + + # SPARC + (b == sparc && isCompatible a sparc64) + + # WASM + (b == wasm32 && isCompatible a wasm64) + + # identity + (b == a) + ]; + ################################################################################ types.openVendor = mkOptionType { -- cgit 1.4.1