summaryrefslogtreecommitdiffstats
path: root/lib/systems
diff options
context:
space:
mode:
authorJohn Ericson <git@JohnEricson.me>2019-09-02 01:57:01 -0400
committerJohn Ericson <git@JohnEricson.me>2019-09-02 01:57:01 -0400
commitc2b34b2b57f1b789cc2a468ff8e75a0da71349c4 (patch)
tree1c59fb79b1d1be4a6de37d6ba8f44dadfaaa4305 /lib/systems
parenta77a2cfe4a61c8fda4108fb3670605f04246f857 (diff)
parentd2d107c4de7f5b36eb82e6884a90c144e9014e5a (diff)
Merge remote-tracking branch 'upstream/master' into js-unknown-ghcjs
Diffstat (limited to 'lib/systems')
-rw-r--r--lib/systems/default.nix31
-rw-r--r--lib/systems/doubles.nix18
-rw-r--r--lib/systems/examples.nix49
-rw-r--r--lib/systems/for-meta.nix37
-rw-r--r--lib/systems/inspect.nix4
-rw-r--r--lib/systems/parse.nix123
-rw-r--r--lib/systems/platforms.nix11
7 files changed, 182 insertions, 91 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index 77f200952958..8aa413f53817 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -3,7 +3,6 @@
rec {
doubles = import ./doubles.nix { inherit lib; };
- forMeta = import ./for-meta.nix { inherit lib; };
parse = import ./parse.nix { inherit lib; };
inspect = import ./inspect.nix { inherit lib; };
platforms = import ./platforms.nix { inherit lib; };
@@ -15,7 +14,9 @@ rec {
# `parsed` is inferred from args, both because there are two options with one
# clearly prefered, and to prevent cycles. A simpler fixed point where the RHS
# always just used `final.*` would fail on both counts.
- elaborate = args: let
+ elaborate = args': let
+ args = if lib.isString args' then { system = args'; }
+ else args';
final = {
# Prefer to parse `config` as it is strictly more informative.
parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
@@ -24,15 +25,20 @@ 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"
else if final.isMinGW then "msvcrt"
+ else if final.isWasi then "wasilibc"
else if final.isMusl then "musl"
else if final.isUClibc then "uclibc"
else if final.isAndroid then "bionic"
else if final.isLinux /* default */ then "glibc"
+ else if final.isMsp430 then "newlib"
else if final.isAvr then "avrlibc"
+ else if final.isNetBSD then "nblibc"
# TODO(@Ericson2314) think more about other operating systems
else "native/impure";
extensions = {
@@ -58,7 +64,7 @@ rec {
"netbsd" = "NetBSD";
"freebsd" = "FreeBSD";
"openbsd" = "OpenBSD";
- "wasm" = "Wasm";
+ "wasi" = "Wasi";
}.${final.parsed.kernel.name} or null;
# uname -p
@@ -68,16 +74,22 @@ rec {
release = null;
};
+ kernelArch =
+ if final.isAarch32 then "arm"
+ else if final.isAarch64 then "arm64"
+ else if final.isx86_32 then "x86"
+ else if final.isx86_64 then "ia64"
+ else final.parsed.cpu.name;
+
qemuArch =
if final.isArm then "arm"
else if final.isx86_64 then "x86_64"
else if final.isx86 then "i386"
else {
"powerpc" = "ppc";
+ "powerpcle" = "ppc";
"powerpc64" = "ppc64";
- "powerpc64le" = "ppc64";
- "mips64" = "mips";
- "mipsel64" = "mipsel";
+ "powerpc64le" = "ppc64le";
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
emulator = pkgs: let
@@ -98,13 +110,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))
- then pkgs.runtimeShell
+ pkgs.stdenv.hostPlatform.isCompatible final
+ then "${pkgs.runtimeShell} -c '\"$@\"' --"
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.isWasi
+ then "${pkgs.wasmtime}/bin/wasmtime"
else throw "Don't know how to run ${final.config} executables.";
} // mapAttrs (n: v: v final.parsed) inspect.predicates
diff --git a/lib/systems/doubles.nix b/lib/systems/doubles.nix
index 58677c0bdd90..823f6a915d6e 100644
--- a/lib/systems/doubles.nix
+++ b/lib/systems/doubles.nix
@@ -13,10 +13,20 @@ let
"i686-cygwin" "i686-freebsd" "i686-linux" "i686-netbsd" "i686-openbsd"
- "x86_64-cygwin" "x86_64-darwin" "x86_64-freebsd" "x86_64-linux"
+ "x86_64-cygwin" "x86_64-freebsd" "x86_64-linux"
"x86_64-netbsd" "x86_64-openbsd" "x86_64-solaris"
+ "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin"
+
"x86_64-windows" "i686-windows"
+
+ "wasm64-wasi" "wasm32-wasi"
+
+ "powerpc64le-linux"
+
+ "riscv32-linux" "riscv64-linux"
+
+ "aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none"
];
allParsed = map parse.mkSystemFromString all;
@@ -34,6 +44,7 @@ in rec {
i686 = filterDoubles predicates.isi686;
x86_64 = filterDoubles predicates.isx86_64;
mips = filterDoubles predicates.isMips;
+ riscv = filterDoubles predicates.isRiscV;
cygwin = filterDoubles predicates.isCygwin;
darwin = filterDoubles predicates.isDarwin;
@@ -45,7 +56,10 @@ in rec {
netbsd = filterDoubles predicates.isNetBSD;
openbsd = filterDoubles predicates.isOpenBSD;
unix = filterDoubles predicates.isUnix;
+ wasi = filterDoubles predicates.isWasi;
windows = filterDoubles predicates.isWindows;
- mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" "powerpc64le-linux"];
+ embedded = filterDoubles predicates.isNone;
+
+ mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux" "armv7l-linux" "armv7a-linux" "aarch64-linux" "powerpc64le-linux"];
}
diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix
index 90068f566ed0..4861fe634a02 100644
--- a/lib/systems/examples.nix
+++ b/lib/systems/examples.nix
@@ -44,14 +44,6 @@ rec {
platform = platforms.aarch64-multiplatform;
};
- armv5te-android-prebuilt = rec {
- config = "armv5tel-unknown-linux-androideabi";
- sdkVer = "21";
- ndkVer = "18b";
- platform = platforms.armv5te-android;
- useAndroidPrebuilt = true;
- };
-
armv7a-android-prebuilt = rec {
config = "armv7a-unknown-linux-androideabi";
sdkVer = "24";
@@ -96,12 +88,32 @@ rec {
config = "aarch64-unknown-linux-musl";
};
+ gnu64 = { config = "x86_64-unknown-linux-gnu"; };
+ gnu32 = { config = "i686-unknown-linux-gnu"; };
+
musl64 = { config = "x86_64-unknown-linux-musl"; };
musl32 = { config = "i686-unknown-linux-musl"; };
riscv64 = riscv "64";
riscv32 = riscv "32";
+ riscv64-embedded = {
+ config = "riscv64-none-elf";
+ libc = "newlib";
+ platform = platforms.riscv-multiplatform "64";
+ };
+
+ riscv32-embedded = {
+ config = "riscv32-none-elf";
+ libc = "newlib";
+ platform = platforms.riscv-multiplatform "32";
+ };
+
+ msp430 = {
+ config = "msp430-elf";
+ libc = "newlib";
+ };
+
avr = {
config = "avr";
};
@@ -135,11 +147,6 @@ rec {
libc = "newlib";
};
- alpha-embedded = {
- config = "alpha-elf";
- libc = "newlib";
- };
-
i686-embedded = {
config = "i686-elf";
libc = "newlib";
@@ -213,6 +220,22 @@ rec {
platform = {};
};
+ # BSDs
+
+ amd64-netbsd = {
+ config = "x86_64-unknown-netbsd";
+ libc = "nblibc";
+ };
+
+ #
+ # WASM
+ #
+
+ wasi32 = {
+ config = "wasm32-unknown-wasi";
+ useLLVM = true;
+ };
+
# Ghcjs
ghcjs = {
config = "js-unknown-ghcjs";
diff --git a/lib/systems/for-meta.nix b/lib/systems/for-meta.nix
deleted file mode 100644
index 51fb6ae760d1..000000000000
--- a/lib/systems/for-meta.nix
+++ /dev/null
@@ -1,37 +0,0 @@
-{ lib }:
-let
- inherit (lib.systems) parse;
- inherit (lib.systems.inspect) patterns;
-
- abis = lib.mapAttrs (_: abi: builtins.removeAttrs abi [ "assertions" ]) parse.abis;
-
-in rec {
- all = [ {} ]; # `{}` matches anything
- none = [];
-
- arm = [ patterns.isAarch32 ];
- aarch64 = [ patterns.isAarch64 ];
- x86 = [ patterns.isx86 ];
- i686 = [ patterns.isi686 ];
- x86_64 = [ patterns.isx86_64 ];
- mips = [ patterns.isMips ];
- riscv = [ patterns.isRiscV ];
-
- cygwin = [ patterns.isCygwin ];
- darwin = [ patterns.isDarwin ];
- freebsd = [ patterns.isFreeBSD ];
- # Should be better, but MinGW is unclear.
- gnu = [
- { kernel = parse.kernels.linux; abi = abis.gnu; }
- { kernel = parse.kernels.linux; abi = abis.gnueabi; }
- { kernel = parse.kernels.linux; abi = abis.gnueabihf; }
- ];
- illumos = [ patterns.isSunOS ];
- linux = [ patterns.isLinux ];
- netbsd = [ patterns.isNetBSD ];
- openbsd = [ patterns.isOpenBSD ];
- unix = patterns.isUnix; # Actually a list
- windows = [ patterns.isWindows ];
-
- inherit (lib.systems.doubles) mesaPlatforms;
-}
diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix
index 129c7a94d3db..8a983b3d3637 100644
--- a/lib/systems/inspect.nix
+++ b/lib/systems/inspect.nix
@@ -20,7 +20,9 @@ rec {
isRiscV = { cpu = { family = "riscv"; }; };
isSparc = { cpu = { family = "sparc"; }; };
isWasm = { cpu = { family = "wasm"; }; };
+ isMsp430 = { cpu = { family = "msp430"; }; };
isAvr = { cpu = { family = "avr"; }; };
+ isAlpha = { cpu = { family = "alpha"; }; };
isJavaScript = { cpu = cpuTypes.js; };
is32bit = { cpu = { bits = 32; }; };
@@ -42,7 +44,9 @@ rec {
isWindows = { kernel = kernels.windows; };
isCygwin = { kernel = kernels.windows; abi = abis.cygnus; };
isMinGW = { kernel = kernels.windows; abi = abis.gnu; };
+ isWasi = { kernel = kernels.wasi; };
isGhcjs = { kernel = kernels.ghcjs; };
+ isNone = { kernel = kernels.none; };
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index a20b334311ef..0c42689a9b13 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -69,24 +69,24 @@ rec {
cpuTypes = with significantBytes; setTypes types.openCpuType {
arm = { bits = 32; significantByte = littleEndian; family = "arm"; };
- armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; };
- armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
- armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
- armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
- armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
- armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
- armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
- armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
- armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
- armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
- aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
- aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; };
-
- i386 = { bits = 32; significantByte = littleEndian; family = "x86"; };
- i486 = { bits = 32; significantByte = littleEndian; family = "x86"; };
- i586 = { bits = 32; significantByte = littleEndian; family = "x86"; };
- i686 = { bits = 32; significantByte = littleEndian; family = "x86"; };
- x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; };
+ armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; };
+ armv6m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; };
+ armv6l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6"; };
+ armv7a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-a"; };
+ armv7r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-r"; };
+ armv7m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-m"; };
+ armv7l = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7"; };
+ armv8a = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+ armv8r = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+ armv8m = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-m"; };
+ aarch64 = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+ aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+
+ i386 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i386"; };
+ i486 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i486"; };
+ i586 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i586"; };
+ i686 = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i686"; };
+ x86_64 = { bits = 64; significantByte = littleEndian; family = "x86"; arch = "x86-64"; };
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
@@ -109,11 +109,92 @@ rec {
alpha = { bits = 64; significantByte = littleEndian; family = "alpha"; };
+ msp430 = { bits = 16; significantByte = littleEndian; family = "msp430"; };
avr = { bits = 8; family = "avr"; };
js = { bits = 32; significantByte = littleEndian; family = "js"; };
};
+ # 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)
+
+ # XXX: Not true in some cases. Like in WSL mode.
+ (b == i686 && isCompatible a x86_64)
+
+ # ARMv4
+ (b == arm && isCompatible a armv5tel)
+
+ # ARMv5
+ (b == armv5tel && isCompatible a armv6l)
+
+ # ARMv6
+ (b == armv6l && isCompatible a armv6m)
+ (b == armv6m && isCompatible a armv7l)
+
+ # ARMv7
+ (b == armv7l && isCompatible a armv7a)
+ (b == armv7l && isCompatible a armv7r)
+ (b == armv7l && isCompatible a armv7m)
+ (b == armv7a && isCompatible a armv8a)
+ (b == armv7r && isCompatible a armv8a)
+ (b == armv7m && isCompatible a armv8a)
+ (b == armv7a && isCompatible a armv8r)
+ (b == armv7r && isCompatible a armv8r)
+ (b == armv7m && isCompatible a armv8r)
+ (b == armv7a && isCompatible a armv8m)
+ (b == armv7r && isCompatible a armv8m)
+ (b == armv7m && isCompatible a armv8m)
+
+ # ARMv8
+ (b == armv8r && isCompatible a armv8a)
+ (b == armv8m && isCompatible a armv8a)
+
+ # XXX: not always true! Some arm64 cpus don’t support arm32 mode.
+ (b == aarch64 && a == armv8a)
+ (b == armv8a && 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 {
@@ -147,6 +228,7 @@ rec {
elf = {};
macho = {};
pe = {};
+ wasm = {};
unknown = {};
};
@@ -189,6 +271,7 @@ rec {
none = { execFormat = unknown; families = { }; };
openbsd = { execFormat = elf; families = { inherit bsd; }; };
solaris = { execFormat = elf; families = { }; };
+ wasi = { execFormat = wasm; families = { }; };
windows = { execFormat = pe; families = { }; };
ghcjs = { execFormat = unknown; families = { }; };
} // { # aliases
@@ -298,6 +381,8 @@ rec {
then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; }
else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; }
+ else if (elemAt l 2 == "wasi")
+ then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi"; }
else if hasPrefix "netbsd" (elemAt l 2)
then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; }
else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
@@ -348,7 +433,7 @@ rec {
mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
- doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
+ doubleFromSystem = { cpu, kernel, abi, ... }:
/**/ if abi == abis.cygnus then "${cpu.name}-cygwin"
else if kernel.families ? darwin then "${cpu.name}-darwin"
else "${cpu.name}-${kernel.name}";
diff --git a/lib/systems/platforms.nix b/lib/systems/platforms.nix
index 03bfce256103..a2b43c970a41 100644
--- a/lib/systems/platforms.nix
+++ b/lib/systems/platforms.nix
@@ -253,22 +253,11 @@ rec {
kernelTarget = "zImage";
};
- # https://developer.android.com/ndk/guides/abis#armeabi
- armv5te-android = {
- name = "armeabi";
- gcc = {
- arch = "armv5te";
- float = "soft";
- float-abi = "soft";
- };
- };
-
# https://developer.android.com/ndk/guides/abis#v7a
armv7a-android = {
name = "armeabi-v7a";
gcc = {
arch = "armv7-a";
- float = "hard";
float-abi = "softfp";
fpu = "vfpv3-d16";
};