Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 385 lines 13 kB view raw
1{ 2 buildPackages, 3 pkgsBuildBuild, 4 callPackage, 5 perl, 6 bison ? null, 7 flex ? null, 8 gmp ? null, 9 libmpc ? null, 10 mpfr ? null, 11 pahole, 12 lib, 13 stdenv, 14 rustc, 15 rustPlatform, 16 rust-bindgen, 17 # testing 18 emptyFile, 19 nixos, 20 nixosTests, 21}@args': 22 23let 24 overridableKernel = lib.makeOverridable ( 25 # The kernel source tarball. 26 { 27 src, 28 29 # The kernel version. 30 version, 31 32 # Allows overriding the default defconfig 33 defconfig ? null, 34 35 # Legacy overrides to the intermediate kernel config, as string 36 extraConfig ? "", 37 38 # Additional make flags passed to kbuild 39 extraMakeFlags ? [ ], 40 41 # enables the options in ./common-config.nix; if `false` then only 42 # `structuredExtraConfig` is used 43 enableCommonConfig ? true 44 45 , # kernel intermediate config overrides, as a set 46 structuredExtraConfig ? { }, 47 48 # The version number used for the module directory 49 # If unspecified, this is determined automatically from the version. 50 modDirVersion ? null, 51 52 # An attribute set whose attributes express the availability of 53 # certain features in this kernel. E.g. `{ia32Emulation = true;}' 54 # indicates a kernel that provides Intel wireless support. Used in 55 # NixOS to implement kernel-specific behaviour. 56 features ? { }, 57 58 # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is 59 # automatically extended with extra per-version and per-config values. 60 randstructSeed ? "", 61 62 # A list of patches to apply to the kernel. Each element of this list 63 # should be an attribute set {name, patch} where `name' is a 64 # symbolic name and `patch' is the actual patch. The patch may 65 # optionally be compressed with gzip or bzip2. 66 kernelPatches ? [ ], 67 ignoreConfigErrors ? 68 !lib.elem stdenv.hostPlatform.linux-kernel.name [ 69 "aarch64-multiplatform" 70 "pc" 71 ], 72 extraMeta ? { }, 73 extraPassthru ? { }, 74 75 isZen ? false, 76 isLibre ? false, 77 isHardened ? false, 78 79 # easy overrides to stdenv.hostPlatform.linux-kernel members 80 autoModules ? stdenv.hostPlatform.linux-kernel.autoModules, 81 preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false, 82 kernelArch ? stdenv.hostPlatform.linuxArch, 83 kernelTests ? { }, 84 85 stdenv ? args'.stdenv, 86 buildPackages ? args'.buildPackages, 87 pkgsBuildBuild ? args'.pkgsBuildBuild, 88 89 ... 90 }@args: 91 92 # Note: this package is used for bootstrapping fetchurl, and thus 93 # cannot use fetchpatch! All mutable patches (generated by GitHub or 94 # cgit) that are needed here should be included directly in Nixpkgs as 95 # files. 96 97 let 98 # Dirty hack to make sure that `version` & `src` have 99 # `<nixpkgs/pkgs/os-specific/linux/kernel/linux-x.y.nix>` as position 100 # when using `builtins.unsafeGetAttrPos`. 101 # 102 # This is to make sure that ofborg actually detects changes in the kernel derivation 103 # and pings all maintainers. 104 # 105 # For further context, see https://github.com/NixOS/nixpkgs/pull/143113#issuecomment-953319957 106 basicArgs = builtins.removeAttrs args ( 107 lib.filter ( 108 x: 109 !(builtins.elem x [ 110 "version" 111 "pname" 112 "src" 113 ]) 114 ) (lib.attrNames args) 115 ); 116 117 # Combine the `features' attribute sets of all the kernel patches. 118 kernelFeatures = lib.foldr (x: y: (x.features or { }) // y) ( 119 { 120 efiBootStub = true; 121 netfilterRPFilter = true; 122 ia32Emulation = true; 123 } 124 // features 125 ) kernelPatches; 126 127 commonStructuredConfig = import ./common-config.nix { 128 inherit lib stdenv version; 129 rustAvailable = lib.meta.availableOn stdenv.hostPlatform rustc; 130 131 features = kernelFeatures; # Ensure we know of all extra patches, etc. 132 }; 133 134 intermediateNixConfig = 135 configfile.moduleStructuredConfig.intermediateNixConfig 136 # extra config in legacy string format 137 + extraConfig 138 + stdenv.hostPlatform.linux-kernel.extraConfig or ""; 139 140 structuredConfigFromPatches = map ( 141 { 142 extraStructuredConfig ? { }, 143 ... 144 }: 145 { 146 settings = extraStructuredConfig; 147 } 148 ) kernelPatches; 149 150 # appends kernel patches extraConfig 151 kernelConfigFun = 152 baseConfigStr: 153 let 154 configFromPatches = map ( 155 { 156 extraConfig ? "", 157 ... 158 }: 159 extraConfig 160 ) kernelPatches; 161 in 162 lib.concatStringsSep "\n" ([ baseConfigStr ] ++ configFromPatches); 163 164 withRust = ((configfile.moduleStructuredConfig.settings.RUST or { }).tristate or null) == "y"; 165 166 configfile = stdenv.mkDerivation { 167 inherit 168 ignoreConfigErrors 169 autoModules 170 preferBuiltin 171 kernelArch 172 extraMakeFlags 173 ; 174 pname = "linux-config"; 175 inherit version; 176 177 generateConfig = ./generate-config.pl; 178 179 kernelConfig = kernelConfigFun intermediateNixConfig; 180 passAsFile = [ "kernelConfig" ]; 181 182 depsBuildBuild = [ buildPackages.stdenv.cc ]; 183 nativeBuildInputs = [ 184 perl 185 gmp 186 libmpc 187 mpfr 188 bison 189 flex 190 ] 191 ++ lib.optional (lib.versionAtLeast version "5.2") pahole 192 ++ lib.optionals withRust [ 193 rust-bindgen 194 rustc 195 ]; 196 197 RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc; 198 199 platformName = stdenv.hostPlatform.linux-kernel.name; 200 # e.g. "defconfig" 201 kernelBaseConfig = 202 if defconfig != null then defconfig else stdenv.hostPlatform.linux-kernel.baseConfig; 203 204 makeFlags = 205 lib.optionals ( 206 stdenv.hostPlatform.linux-kernel ? makeFlags 207 ) stdenv.hostPlatform.linux-kernel.makeFlags 208 ++ extraMakeFlags; 209 210 postPatch = kernel.postPatch + '' 211 # Patch kconfig to print "###" after every question so that 212 # generate-config.pl from the generic builder can answer them. 213 sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c 214 ''; 215 216 preUnpack = kernel.preUnpack or ""; 217 218 inherit (kernel) src patches; 219 220 buildPhase = '' 221 export buildRoot="''${buildRoot:-build}" 222 223 # Get a basic config file for later refinement with $generateConfig. 224 make $makeFlags \ 225 -C . O="$buildRoot" $kernelBaseConfig \ 226 ARCH=$kernelArch CROSS_COMPILE=${stdenv.cc.targetPrefix} \ 227 $makeFlags 228 229 # Create the config file. 230 echo "generating kernel configuration..." 231 ln -s "$kernelConfigPath" "$buildRoot/kernel-config" 232 DEBUG=1 ARCH=$kernelArch CROSS_COMPILE=${stdenv.cc.targetPrefix} \ 233 KERNEL_CONFIG="$buildRoot/kernel-config" AUTO_MODULES=$autoModules \ 234 PREFER_BUILTIN=$preferBuiltin BUILD_ROOT="$buildRoot" SRC=. MAKE_FLAGS="$makeFlags" \ 235 perl -w $generateConfig 236 ''; 237 238 installPhase = "mv $buildRoot/.config $out"; 239 240 enableParallelBuilding = true; 241 242 passthru = rec { 243 module = import ../../../../nixos/modules/system/boot/kernel_config.nix; 244 # used also in apache 245 # { modules = [ { options = res.options; config = svc.config or svc; } ]; 246 # check = false; 247 # The result is a set of two attributes 248 moduleStructuredConfig = 249 (lib.evalModules { 250 modules = [ 251 module 252 ] 253 ++ lib.optionals enableCommonConfig [ 254 { 255 settings = commonStructuredConfig; 256 _file = "pkgs/os-specific/linux/kernel/common-config.nix"; 257 } 258 ] 259 ++ [ 260 { 261 settings = structuredExtraConfig; 262 _file = "structuredExtraConfig"; 263 } 264 ] 265 ++ structuredConfigFromPatches; 266 }).config; 267 268 structuredConfig = moduleStructuredConfig.settings; 269 }; 270 }; # end of configfile derivation 271 272 kernel = (callPackage ./manual-config.nix { inherit lib stdenv buildPackages; }) ( 273 basicArgs 274 // { 275 inherit 276 kernelPatches 277 randstructSeed 278 extraMakeFlags 279 extraMeta 280 configfile 281 modDirVersion 282 ; 283 pos = builtins.unsafeGetAttrPos "version" args; 284 285 config = { 286 CONFIG_MODULES = "y"; 287 CONFIG_FW_LOADER = "y"; 288 CONFIG_RUST = if withRust then "y" else "n"; 289 }; 290 } 291 ); 292 293 in 294 kernel.overrideAttrs ( 295 finalAttrs: previousAttrs: { 296 297 passthru = 298 previousAttrs.passthru or { } 299 // extraPassthru 300 // basicArgs 301 // { 302 features = kernelFeatures; 303 inherit 304 commonStructuredConfig 305 structuredExtraConfig 306 extraMakeFlags 307 isZen 308 isHardened 309 isLibre 310 ; 311 isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true; 312 313 # Adds dependencies needed to edit the config: 314 # nix-shell '<nixpkgs>' -A linux.configEnv --command 'make nconfig' 315 configEnv = finalAttrs.finalPackage.overrideAttrs (previousAttrs: { 316 depsBuildBuild = 317 previousAttrs.depsBuildBuild or [ ] 318 ++ (with pkgsBuildBuild; [ 319 pkg-config 320 ncurses 321 ]); 322 }); 323 324 tests = 325 let 326 overridableKernel = finalAttrs.finalPackage // { 327 override = 328 args: 329 lib.warn ( 330 "override is stubbed for NixOS kernel tests, not applying changes these arguments: " 331 + toString (lib.attrNames (lib.toFunction args { })) 332 ) overridableKernel; 333 }; 334 /* 335 Certain arguments must be evaluated lazily; so that only the output(s) depend on them. 336 Original reproducer / simplified use case: 337 */ 338 versionDoesNotDependOnPatchesEtcNixOS = 339 builtins.seq 340 (nixos ( 341 { config, pkgs, ... }: 342 { 343 boot.kernelPatches = [ 344 (builtins.seq config.boot.kernelPackages.kernel.version { patch = pkgs.emptyFile; }) 345 ]; 346 } 347 )).config.boot.kernelPackages.kernel.outPath 348 emptyFile; 349 versionDoesNotDependOnPatchesEtc = 350 builtins.seq 351 (import ./generic.nix args' ( 352 args 353 // ( 354 let 355 explain = attrName: '' 356 The ${attrName} attribute must be able to access the kernel.version attribute without an infinite recursion. 357 That means that the kernel attrset (attrNames) and the kernel.version attribute must not depend on the ${attrName} argument. 358 The fact that this exception is raised shows that such a dependency does exist. 359 This is a problem for the configurability of ${attrName} in version-aware logic such as that in NixOS. 360 Strictness can creep in through optional attributes, or assertions and warnings that run as part of code that shouldn't access what is checked. 361 ''; 362 in 363 { 364 kernelPatches = throw (explain "kernelPatches"); 365 structuredExtraConfig = throw (explain "structuredExtraConfig"); 366 modDirVersion = throw (explain "modDirVersion"); 367 } 368 ) 369 )).version 370 emptyFile; 371 in 372 { 373 inherit versionDoesNotDependOnPatchesEtc; 374 testsForKernel = nixosTests.kernel-generic.passthru.testsForKernel overridableKernel; 375 # Disabled by default, because the infinite recursion is hard to understand. The other test's error is better and produces a shorter trace. 376 # inherit versionDoesNotDependOnPatchesEtcNixOS; 377 } 378 // kernelTests; 379 }; 380 381 } 382 ) 383 ); 384in 385overridableKernel