From f71277d66db862f2cef133e9d63cb858f38d0a0c Mon Sep 17 00:00:00 2001 From: Jared Baur Date: Fri, 25 Jul 2025 16:07:58 -0700 Subject: [PATCH] linux: install kernel modules to separate output The kernel image is not functionally required at runtime in the same output where the kernel modules are, and we can save space by removing it. Co-authored-by: Emily --- doc/release-notes/rl-2511.section.md | 2 ++ .../linux/kernel/manual-config.nix | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/release-notes/rl-2511.section.md b/doc/release-notes/rl-2511.section.md index 202ee003ead1..145185bdf26e 100644 --- a/doc/release-notes/rl-2511.section.md +++ b/doc/release-notes/rl-2511.section.md @@ -52,6 +52,8 @@ - `fetchtorrent`, when using the "rqbit" backend, erroneously started fetching files into a subdirectory in Nixpkgs 24.11. The original behaviour – which matches the behaviour using the "transmission" backend – has now been restored. Users reliant on the erroneous behaviour can temporarily maintain it by adding `flatten = false` to the `fetchtorrent` arguments; Nix will produce an evaluation warning for anyone using `backend = "rqbit"` without `flatten = true`. +- `linux` and all other Linux kernel packages have moved all in-tree kernel modules into a new `modules` output. + - `webfontkitgenerator` has been renamed to `webfont-bundler`, following the rename of the upstream project. The binary name remains `webfontkitgenerator`. The `webfontkitgenerator` package is an alias to `webfont-bundler`. diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index 2bc2004a22e6..02a9c3f78f7c 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -178,6 +178,7 @@ lib.makeOverridable ( outputs = [ "out" "dev" + "modules" ]; }) // { @@ -336,12 +337,12 @@ lib.makeOverridable ( ++ extraMakeFlags; installFlags = [ - "INSTALL_PATH=$(out)" + "INSTALL_PATH=${placeholder "out"}" ] - ++ (optional isModular "INSTALL_MOD_PATH=$(out)") + ++ (optional isModular "INSTALL_MOD_PATH=${placeholder "modules"}") ++ optionals buildDTBs [ "dtbs_install" - "INSTALL_DTBS_PATH=$(out)/dtbs" + "INSTALL_DTBS_PATH=${placeholder "out"}/dtbs" ]; preInstall = @@ -438,8 +439,7 @@ lib.makeOverridable ( installFlags+=("INSTALL_MOD_STRIP=1") fi make modules_install "''${makeFlags[@]}" "''${installFlags[@]}" - unlink $out/lib/modules/${modDirVersion}/build - rm -f $out/lib/modules/${modDirVersion}/source + unlink $modules/lib/modules/${modDirVersion}/build mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} @@ -567,6 +567,20 @@ lib.makeOverridable ( makeFlags = [ "O=$(buildRoot)" + + # We have a `modules` variable in the environment for our + # split output, but the kernel Makefiles also define their + # own `modules` variable. Their definition wins, but Make + # remembers that the variable was originally from the + # environment and exports it to all the build recipes. This + # breaks the build with an “Argument list too long” error due + # to passing the huge list of every module object file in the + # environment of every process invoked by every build recipe. + # + # We use `--eval` here to undefine the inherited environment + # variable before any Makefiles are read, ensuring that the + # kernel’s definition creates a new, unexported variable. + "--eval=undefine modules" ] ++ commonMakeFlags;