1{ supportedSystems
2, packageSet ? (import ../..)
3, scrubJobs ? true
4, # Attributes passed to nixpkgs. Don't build packages marked as unfree.
5 nixpkgsArgs ? { config = { allowUnfree = false; inHydra = true; }; }
6}:
7
8let
9 lib = import ../../lib;
10in with lib;
11
12rec {
13
14 pkgs = packageSet (lib.recursiveUpdate { system = "x86_64-linux"; config.allowUnsupportedSystem = true; } nixpkgsArgs);
15 inherit lib;
16
17
18 hydraJob' = if scrubJobs then hydraJob else id;
19
20
21 /* !!! Hack: poor man's memoisation function. Necessary to prevent
22 Nixpkgs from being evaluated again and again for every
23 job/platform pair. */
24 mkPkgsFor = crossSystem: let
25 packageSet' = args: packageSet (args // { inherit crossSystem; } // nixpkgsArgs);
26
27 pkgs_x86_64_linux = packageSet' { system = "x86_64-linux"; };
28 pkgs_i686_linux = packageSet' { system = "i686-linux"; };
29 pkgs_aarch64_linux = packageSet' { system = "aarch64-linux"; };
30 pkgs_riscv64_linux = packageSet' { system = "riscv64-linux"; };
31 pkgs_aarch64_darwin = packageSet' { system = "aarch64-darwin"; };
32 pkgs_armv6l_linux = packageSet' { system = "armv6l-linux"; };
33 pkgs_armv7l_linux = packageSet' { system = "armv7l-linux"; };
34 pkgs_x86_64_darwin = packageSet' { system = "x86_64-darwin"; };
35 pkgs_x86_64_freebsd = packageSet' { system = "x86_64-freebsd"; };
36 pkgs_i686_freebsd = packageSet' { system = "i686-freebsd"; };
37 pkgs_i686_cygwin = packageSet' { system = "i686-cygwin"; };
38 pkgs_x86_64_cygwin = packageSet' { system = "x86_64-cygwin"; };
39
40 in system:
41 if system == "x86_64-linux" then pkgs_x86_64_linux
42 else if system == "i686-linux" then pkgs_i686_linux
43 else if system == "aarch64-linux" then pkgs_aarch64_linux
44 else if system == "riscv64-linux" then pkgs_riscv64_linux
45 else if system == "aarch64-darwin" then pkgs_aarch64_darwin
46 else if system == "armv6l-linux" then pkgs_armv6l_linux
47 else if system == "armv7l-linux" then pkgs_armv7l_linux
48 else if system == "x86_64-darwin" then pkgs_x86_64_darwin
49 else if system == "x86_64-freebsd" then pkgs_x86_64_freebsd
50 else if system == "i686-freebsd" then pkgs_i686_freebsd
51 else if system == "i686-cygwin" then pkgs_i686_cygwin
52 else if system == "x86_64-cygwin" then pkgs_x86_64_cygwin
53 else abort "unsupported system type: ${system}";
54
55 pkgsFor = pkgsForCross null;
56
57
58 # More poor man's memoisation
59 pkgsForCross = let
60 examplesByConfig = lib.flip lib.mapAttrs'
61 lib.systems.examples
62 (_: crossSystem: nameValuePair crossSystem.config {
63 inherit crossSystem;
64 pkgsFor = mkPkgsFor crossSystem;
65 });
66 native = mkPkgsFor null;
67 in crossSystem: let
68 candidate = examplesByConfig.${crossSystem.config} or null;
69 in if crossSystem == null
70 then native
71 else if candidate != null && lib.matchAttrs crossSystem candidate.crossSystem
72 then candidate.pkgsFor
73 else mkPkgsFor crossSystem; # uncached fallback
74
75
76 # Given a list of 'meta.platforms'-style patterns, return the sublist of
77 # `supportedSystems` containing systems that matches at least one of the given
78 # patterns.
79 #
80 # This is written in a funny way so that we only elaborate the systems once.
81 supportedMatches = let
82 supportedPlatforms = map
83 (system: lib.systems.elaborate { inherit system; })
84 supportedSystems;
85 in metaPatterns: let
86 anyMatch = platform:
87 lib.any (lib.meta.platformMatch platform) metaPatterns;
88 matchingPlatforms = lib.filter anyMatch supportedPlatforms;
89 in map ({ system, ...}: system) matchingPlatforms;
90
91
92 assertTrue = bool:
93 if bool
94 then pkgs.runCommand "evaluated-to-true" {} "touch $out"
95 else pkgs.runCommand "evaluated-to-false" {} "false";
96
97
98 /* The working or failing mails for cross builds will be sent only to
99 the following maintainers, as most package maintainers will not be
100 interested in the result of cross building a package. */
101 crossMaintainers = [ maintainers.viric ];
102
103
104 # Generate attributes for all supported systems.
105 forAllSystems = genAttrs supportedSystems;
106
107
108 # Generate attributes for all systems matching at least one of the given
109 # patterns
110 forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns);
111
112
113 /* Build a package on the given set of platforms. The function `f'
114 is called for each supported platform with Nixpkgs for that
115 platform as an argument . We return an attribute set containing
116 a derivation for each supported platform, i.e. ‘{ x86_64-linux =
117 f pkgs_x86_64_linux; i686-linux = f pkgs_i686_linux; ... }’. */
118 testOn = testOnCross null;
119
120
121 /* Similar to the testOn function, but with an additional
122 'crossSystem' parameter for packageSet', defining the target
123 platform for cross builds. */
124 testOnCross = crossSystem: metaPatterns: f: forMatchingSystems metaPatterns
125 (system: hydraJob' (f (pkgsForCross crossSystem system)));
126
127
128 /* Given a nested set where the leaf nodes are lists of platforms,
129 map each leaf node to `testOn [platforms...] (pkgs:
130 pkgs.<attrPath>)'. */
131 mapTestOn = _mapTestOnHelper id null;
132
133
134 _mapTestOnHelper = f: crossSystem: mapAttrsRecursive
135 (path: metaPatterns: testOnCross crossSystem metaPatterns
136 (pkgs: f (getAttrFromPath path pkgs)));
137
138
139 /* Similar to the testOn function, but with an additional 'crossSystem'
140 * parameter for packageSet', defining the target platform for cross builds,
141 * and triggering the build of the host derivation. */
142 mapTestOnCross = _mapTestOnHelper
143 (addMetaAttrs { maintainers = crossMaintainers; });
144
145
146 /* Recursively map a (nested) set of derivations to an isomorphic
147 set of meta.platforms values. */
148 packagePlatforms = mapAttrs (name: value:
149 if isDerivation value then
150 value.meta.hydraPlatforms
151 or (lib.subtractLists (value.meta.badPlatforms or [])
152 (value.meta.platforms or [ "x86_64-linux" ]))
153 else if value.recurseForDerivations or false || value.recurseForRelease or false then
154 packagePlatforms value
155 else
156 []
157 );
158
159
160 /* Common platform groups on which to test packages. */
161 inherit (platforms) unix linux darwin cygwin all mesaPlatforms;
162
163}