summaryrefslogtreecommitdiffstats
path: root/lib/systems
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2019-02-26 16:39:08 -0500
committerGitHub <noreply@github.com>2019-02-26 16:39:08 -0500
commit3c8b75f536e3ea40c926905478f2f03afaf9a8b5 (patch)
treefbc7e4424db3953f29c6c54876222f15d6e57d6d /lib/systems
parent1a95a36dbf15161d15ca2b2f7d5e3ccbb83093d3 (diff)
parent20a4bbe23b3039f26f739b026f90e4613a20a98c (diff)
Merge pull request #56393 from matthewbauer/is-compatible
systems: add isCompatible handling
Diffstat (limited to 'lib/systems')
-rw-r--r--lib/systems/default.nix7
-rw-r--r--lib/systems/parse.nix60
2 files changed, 65 insertions, 2 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index 77f200952958..e4629fc9bf80 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,13 +100,14 @@ 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}"
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
then "${qemu-user}/bin/qemu-${final.qemuArch}"
+ else if final.isWasm
+ then "${pkgs.v8}/bin/d8"
else throw "Don't know how to run ${final.config} executables.";
} // mapAttrs (n: v: v final.parsed) inspect.predicates
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index 6947d41419e3..fab50bc0ebd7 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 {