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