2017-07-29 00:05:35 +00:00
|
|
|
{ lib }:
|
|
|
|
let inherit (lib.attrsets) mapAttrs; in
|
2017-05-21 17:39:23 +00:00
|
|
|
|
2017-02-09 02:27:22 +00:00
|
|
|
rec {
|
2017-07-29 00:05:35 +00:00
|
|
|
doubles = import ./doubles.nix { inherit lib; };
|
|
|
|
parse = import ./parse.nix { inherit lib; };
|
|
|
|
inspect = import ./inspect.nix { inherit lib; };
|
|
|
|
platforms = import ./platforms.nix { inherit lib; };
|
|
|
|
examples = import ./examples.nix { inherit lib; };
|
2017-03-24 00:49:28 +00:00
|
|
|
|
|
|
|
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
|
|
|
# necessary.
|
|
|
|
#
|
|
|
|
# `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.
|
2019-06-04 15:10:03 +00:00
|
|
|
elaborate = args': let
|
|
|
|
args = if lib.isString args' then { system = args'; }
|
|
|
|
else args';
|
2017-03-24 00:49:28 +00:00
|
|
|
final = {
|
|
|
|
# Prefer to parse `config` as it is strictly more informative.
|
|
|
|
parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
|
|
|
|
# Either of these can be losslessly-extracted from `parsed` iff parsing succeeds.
|
|
|
|
system = parse.doubleFromSystem final.parsed;
|
|
|
|
config = parse.tripleFromSystem final.parsed;
|
|
|
|
# Just a guess, based on `system`
|
|
|
|
platform = platforms.selectBySystem final.system;
|
2019-02-22 03:17:51 +00:00
|
|
|
# Determine whether we are compatible with the provided CPU
|
|
|
|
isCompatible = platform: parse.isCompatible final.parsed.cpu platform.parsed.cpu;
|
2017-02-17 05:36:10 +00:00
|
|
|
# Derived meta-data
|
2017-05-21 18:02:19 +00:00
|
|
|
libc =
|
2017-02-17 05:36:10 +00:00
|
|
|
/**/ if final.isDarwin then "libSystem"
|
|
|
|
else if final.isMinGW then "msvcrt"
|
2019-01-30 02:01:24 +00:00
|
|
|
else if final.isWasi then "wasilibc"
|
2017-02-17 05:36:10 +00:00
|
|
|
else if final.isMusl then "musl"
|
2018-05-10 03:33:31 +00:00
|
|
|
else if final.isUClibc then "uclibc"
|
2017-02-17 05:36:10 +00:00
|
|
|
else if final.isAndroid then "bionic"
|
|
|
|
else if final.isLinux /* default */ then "glibc"
|
2019-03-26 03:33:39 +00:00
|
|
|
else if final.isMsp430 then "newlib"
|
2018-10-15 01:41:33 +00:00
|
|
|
else if final.isAvr then "avrlibc"
|
2018-07-28 16:29:02 +00:00
|
|
|
else if final.isNetBSD then "nblibc"
|
2017-05-21 18:02:19 +00:00
|
|
|
# TODO(@Ericson2314) think more about other operating systems
|
2017-02-17 05:36:10 +00:00
|
|
|
else "native/impure";
|
2017-09-12 19:24:03 +00:00
|
|
|
extensions = {
|
|
|
|
sharedLibrary =
|
|
|
|
/**/ if final.isDarwin then ".dylib"
|
|
|
|
else if final.isWindows then ".dll"
|
|
|
|
else ".so";
|
|
|
|
executable =
|
|
|
|
/**/ if final.isWindows then ".exe"
|
|
|
|
else "";
|
|
|
|
};
|
2017-02-17 05:36:10 +00:00
|
|
|
# Misc boolean options
|
|
|
|
useAndroidPrebuilt = false;
|
2018-04-15 23:21:45 +00:00
|
|
|
useiOSPrebuilt = false;
|
2018-10-17 02:48:43 +00:00
|
|
|
|
|
|
|
# Output from uname
|
|
|
|
uname = {
|
|
|
|
# uname -s
|
2018-10-17 19:43:49 +00:00
|
|
|
system = {
|
2019-08-13 21:52:01 +00:00
|
|
|
linux = "Linux";
|
|
|
|
windows = "Windows";
|
|
|
|
darwin = "Darwin";
|
|
|
|
netbsd = "NetBSD";
|
|
|
|
freebsd = "FreeBSD";
|
|
|
|
openbsd = "OpenBSD";
|
|
|
|
wasi = "Wasi";
|
2018-10-17 19:43:49 +00:00
|
|
|
}.${final.parsed.kernel.name} or null;
|
2018-10-17 02:48:43 +00:00
|
|
|
|
|
|
|
# uname -p
|
|
|
|
processor = final.parsed.cpu.name;
|
|
|
|
|
|
|
|
# uname -r
|
|
|
|
release = null;
|
|
|
|
};
|
2018-11-13 22:54:08 +00:00
|
|
|
|
2019-04-19 18:51:25 +00:00
|
|
|
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;
|
|
|
|
|
2018-11-13 22:54:08 +00:00
|
|
|
qemuArch =
|
|
|
|
if final.isArm then "arm"
|
|
|
|
else if final.isx86_64 then "x86_64"
|
|
|
|
else if final.isx86 then "i386"
|
|
|
|
else {
|
2019-08-13 21:52:01 +00:00
|
|
|
powerpc = "ppc";
|
|
|
|
powerpcle = "ppc";
|
|
|
|
powerpc64 = "ppc64";
|
|
|
|
powerpc64le = "ppc64le";
|
2018-11-13 22:54:08 +00:00
|
|
|
}.${final.parsed.cpu.name} or final.parsed.cpu.name;
|
|
|
|
|
|
|
|
emulator = pkgs: let
|
|
|
|
qemu-user = pkgs.qemu.override {
|
|
|
|
smartcardSupport = false;
|
|
|
|
spiceSupport = false;
|
|
|
|
openGLSupport = false;
|
|
|
|
virglSupport = false;
|
|
|
|
vncSupport = false;
|
|
|
|
gtkSupport = false;
|
|
|
|
sdlSupport = false;
|
|
|
|
pulseSupport = false;
|
|
|
|
smbdSupport = false;
|
|
|
|
seccompSupport = false;
|
|
|
|
hostCpuTargets = ["${final.qemuArch}-linux-user"];
|
|
|
|
};
|
|
|
|
wine-name = "wine${toString final.parsed.cpu.bits}";
|
|
|
|
wine = (pkgs.winePackagesFor wine-name).minimal;
|
|
|
|
in
|
|
|
|
if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name &&
|
2019-02-22 03:17:51 +00:00
|
|
|
pkgs.stdenv.hostPlatform.isCompatible final
|
2019-04-17 20:41:33 +00:00
|
|
|
then "${pkgs.runtimeShell} -c '\"$@\"' --"
|
2018-11-13 22:54:08 +00:00
|
|
|
else if final.isWindows
|
|
|
|
then "${wine}/bin/${wine-name}"
|
|
|
|
else if final.isLinux && pkgs.stdenv.hostPlatform.isLinux
|
|
|
|
then "${qemu-user}/bin/qemu-${final.qemuArch}"
|
2019-04-16 02:22:16 +00:00
|
|
|
else if final.isWasi
|
|
|
|
then "${pkgs.wasmtime}/bin/wasmtime"
|
2018-11-13 22:54:08 +00:00
|
|
|
else throw "Don't know how to run ${final.config} executables.";
|
|
|
|
|
2017-05-21 17:39:23 +00:00
|
|
|
} // mapAttrs (n: v: v final.parsed) inspect.predicates
|
|
|
|
// args;
|
2017-02-17 05:36:10 +00:00
|
|
|
in assert final.useAndroidPrebuilt -> final.isAndroid;
|
2018-05-09 22:50:51 +00:00
|
|
|
assert lib.foldl
|
|
|
|
(pass: { assertion, message }:
|
|
|
|
if assertion final
|
|
|
|
then pass
|
|
|
|
else throw message)
|
|
|
|
true
|
|
|
|
(final.parsed.abi.assertions or []);
|
2017-02-17 05:36:10 +00:00
|
|
|
final;
|
2017-02-09 02:27:22 +00:00
|
|
|
}
|