Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at python-updates 262 lines 7.3 kB view raw
1{ 2 supportedSystems, 3 system ? builtins.currentSystem, 4 packageSet ? (import ../..), 5 scrubJobs ? true, 6 # Attributes passed to nixpkgs. Don't build packages marked as unfree. 7 nixpkgsArgs ? { 8 config = { 9 allowAliases = false; 10 allowUnfree = false; 11 inHydra = true; 12 }; 13 __allowFileset = false; 14 }, 15}: 16 17let 18 lib = import ../../lib; 19 20 inherit (lib) 21 addMetaAttrs 22 any 23 derivations 24 filter 25 flip 26 genAttrs 27 getAttrFromPath 28 hydraJob 29 id 30 isDerivation 31 lists 32 maintainers 33 mapAttrs 34 mapAttrs' 35 mapAttrsRecursive 36 matchAttrs 37 meta 38 nameValuePair 39 platforms 40 recursiveUpdate 41 subtractLists 42 systems 43 ; 44 45 pkgs = packageSet ( 46 recursiveUpdate { 47 inherit system; 48 config.allowUnsupportedSystem = true; 49 } nixpkgsArgs 50 ); 51 52 hydraJob' = if scrubJobs then hydraJob else id; 53 54 /* 55 !!! Hack: poor man's memoisation function. Necessary to prevent 56 Nixpkgs from being evaluated again and again for every 57 job/platform pair. 58 */ 59 mkPkgsFor = 60 crossSystem: 61 let 62 packageSet' = args: packageSet (args // { inherit crossSystem; } // nixpkgsArgs); 63 64 pkgs_x86_64_linux = packageSet' { system = "x86_64-linux"; }; 65 pkgs_i686_linux = packageSet' { system = "i686-linux"; }; 66 pkgs_aarch64_linux = packageSet' { system = "aarch64-linux"; }; 67 pkgs_riscv64_linux = packageSet' { system = "riscv64-linux"; }; 68 pkgs_aarch64_darwin = packageSet' { system = "aarch64-darwin"; }; 69 pkgs_armv6l_linux = packageSet' { system = "armv6l-linux"; }; 70 pkgs_armv7l_linux = packageSet' { system = "armv7l-linux"; }; 71 pkgs_x86_64_darwin = packageSet' { system = "x86_64-darwin"; }; 72 pkgs_x86_64_freebsd = packageSet' { system = "x86_64-freebsd"; }; 73 pkgs_i686_freebsd = packageSet' { system = "i686-freebsd"; }; 74 pkgs_i686_cygwin = packageSet' { system = "i686-cygwin"; }; 75 pkgs_x86_64_cygwin = packageSet' { system = "x86_64-cygwin"; }; 76 77 in 78 system: 79 if system == "x86_64-linux" then 80 pkgs_x86_64_linux 81 else if system == "i686-linux" then 82 pkgs_i686_linux 83 else if system == "aarch64-linux" then 84 pkgs_aarch64_linux 85 else if system == "riscv64-linux" then 86 pkgs_riscv64_linux 87 else if system == "aarch64-darwin" then 88 pkgs_aarch64_darwin 89 else if system == "armv6l-linux" then 90 pkgs_armv6l_linux 91 else if system == "armv7l-linux" then 92 pkgs_armv7l_linux 93 else if system == "x86_64-darwin" then 94 pkgs_x86_64_darwin 95 else if system == "x86_64-freebsd" then 96 pkgs_x86_64_freebsd 97 else if system == "i686-freebsd" then 98 pkgs_i686_freebsd 99 else if system == "i686-cygwin" then 100 pkgs_i686_cygwin 101 else if system == "x86_64-cygwin" then 102 pkgs_x86_64_cygwin 103 else 104 abort "unsupported system type: ${system}"; 105 106 pkgsFor = pkgsForCross null; 107 108 # More poor man's memoisation 109 pkgsForCross = 110 let 111 examplesByConfig = flip mapAttrs' systems.examples ( 112 _: crossSystem: 113 nameValuePair crossSystem.config { 114 inherit crossSystem; 115 pkgsFor = mkPkgsFor crossSystem; 116 } 117 ); 118 native = mkPkgsFor null; 119 in 120 crossSystem: 121 let 122 candidate = examplesByConfig.${crossSystem.config} or null; 123 in 124 if crossSystem == null then 125 native 126 else if candidate != null && matchAttrs crossSystem candidate.crossSystem then 127 candidate.pkgsFor 128 else 129 mkPkgsFor crossSystem; # uncached fallback 130 131 # Given a list of 'meta.platforms'-style patterns, return the sublist of 132 # `supportedSystems` containing systems that matches at least one of the given 133 # patterns. 134 # 135 # This is written in a funny way so that we only elaborate the systems once. 136 supportedMatches = 137 let 138 supportedPlatforms = map (system: systems.elaborate { inherit system; }) supportedSystems; 139 in 140 metaPatterns: 141 let 142 anyMatch = platform: any (meta.platformMatch platform) metaPatterns; 143 matchingPlatforms = filter anyMatch supportedPlatforms; 144 in 145 map ({ system, ... }: system) matchingPlatforms; 146 147 assertTrue = 148 bool: 149 if bool then 150 pkgs.runCommand "evaluated-to-true" { } "touch $out" 151 else 152 pkgs.runCommand "evaluated-to-false" { } "false"; 153 154 /* 155 The working or failing mails for cross builds will be sent only to 156 the following maintainers, as most package maintainers will not be 157 interested in the result of cross building a package. 158 */ 159 crossMaintainers = [ ]; 160 161 # Generate attributes for all supported systems. 162 forAllSystems = genAttrs supportedSystems; 163 164 # Generate attributes for all systems matching at least one of the given 165 # patterns 166 forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns); 167 168 /* 169 Build a package on the given set of platforms. The function `f' 170 is called for each supported platform with Nixpkgs for that 171 platform as an argument . We return an attribute set containing 172 a derivation for each supported platform, i.e. { x86_64-linux = 173 f pkgs_x86_64_linux; i686-linux = f pkgs_i686_linux; ... }. 174 */ 175 testOn = testOnCross null; 176 177 /* 178 Similar to the testOn function, but with an additional 179 'crossSystem' parameter for packageSet', defining the target 180 platform for cross builds. 181 */ 182 testOnCross = 183 crossSystem: metaPatterns: f: 184 forMatchingSystems metaPatterns (system: hydraJob' (f (pkgsForCross crossSystem system))); 185 186 /* 187 Given a nested set where the leaf nodes are lists of platforms, 188 map each leaf node to `testOn [platforms...] (pkgs: 189 pkgs.<attrPath>)'. 190 */ 191 mapTestOn = _mapTestOnHelper id null; 192 193 _mapTestOnHelper = 194 f: crossSystem: 195 mapAttrsRecursive ( 196 path: metaPatterns: testOnCross crossSystem metaPatterns (pkgs: f (getAttrFromPath path pkgs)) 197 ); 198 199 /* 200 Similar to the testOn function, but with an additional 'crossSystem' 201 parameter for packageSet', defining the target platform for cross builds, 202 and triggering the build of the host derivation. 203 */ 204 mapTestOnCross = _mapTestOnHelper (addMetaAttrs { 205 maintainers = crossMaintainers; 206 }); 207 208 # Recursive for packages and apply a function to them 209 recursiveMapPackages = 210 f: 211 mapAttrs ( 212 name: value: 213 if isDerivation value then 214 f value 215 else if value.recurseForDerivations or false || value.recurseForRelease or false then 216 recursiveMapPackages f value 217 else 218 [ ] 219 ); 220 221 # Gets the list of Hydra platforms for a derivation 222 getPlatforms = 223 drv: 224 drv.meta.hydraPlatforms 225 or (subtractLists (drv.meta.badPlatforms or [ ]) (drv.meta.platforms or supportedSystems)); 226 227 /* 228 Recursively map a (nested) set of derivations to an isomorphic 229 set of meta.platforms values. 230 */ 231 packagePlatforms = recursiveMapPackages getPlatforms; 232 233in 234{ 235 # Common platform groups on which to test packages. 236 inherit (platforms) 237 unix 238 linux 239 darwin 240 cygwin 241 all 242 ; 243 244 inherit 245 assertTrue 246 forAllSystems 247 forMatchingSystems 248 hydraJob' 249 lib 250 mapTestOn 251 mapTestOnCross 252 recursiveMapPackages 253 getPlatforms 254 packagePlatforms 255 pkgs 256 pkgsFor 257 pkgsForCross 258 supportedMatches 259 testOn 260 testOnCross 261 ; 262}