1{ lib }:
2 let inherit (lib.attrsets) mapAttrs; in
3
4rec {
5 doubles = import ./doubles.nix { inherit lib; };
6 parse = import ./parse.nix { inherit lib; };
7 inspect = import ./inspect.nix { inherit lib; };
8 platforms = import ./platforms.nix { inherit lib; };
9 examples = import ./examples.nix { inherit lib; };
10
11 # Elaborate a `localSystem` or `crossSystem` so that it contains everything
12 # necessary.
13 #
14 # `parsed` is inferred from args, both because there are two options with one
15 # clearly prefered, and to prevent cycles. A simpler fixed point where the RHS
16 # always just used `final.*` would fail on both counts.
17 elaborate = args: let
18 final = {
19 # Prefer to parse `config` as it is strictly more informative.
20 parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
21 # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds.
22 system = parse.doubleFromSystem final.parsed;
23 config = parse.tripleFromSystem final.parsed;
24 # Just a guess, based on `system`
25 platform = platforms.selectBySystem final.system;
26 # Derived meta-data
27 libc =
28 /**/ if final.isDarwin then "libSystem"
29 else if final.isMinGW then "msvcrt"
30 else if final.isMusl then "musl"
31 else if final.isAndroid then "bionic"
32 else if final.isLinux /* default */ then "glibc"
33 # TODO(@Ericson2314) think more about other operating systems
34 else "native/impure";
35 extensions = {
36 sharedLibrary =
37 /**/ if final.isDarwin then ".dylib"
38 else if final.isWindows then ".dll"
39 else ".so";
40 executable =
41 /**/ if final.isWindows then ".exe"
42 else "";
43 };
44 # Misc boolean options
45 useAndroidPrebuilt = false;
46 } // mapAttrs (n: v: v final.parsed) inspect.predicates
47 // args;
48 in assert final.useAndroidPrebuilt -> final.isAndroid;
49 final;
50}