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