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