nixos-conf/custom/modules/kernel.nix
2026-03-07 10:53:27 +02:00

131 lines
4 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
pkgs,
lib,
kernel-src,
structuredExtraConfig ? { },
kernelPatches ? [ ],
extraConfig ? "",
sccacheDir ? "/var/cache/sccache",
enforceSccache ? true,
}:
let
makefile = builtins.readFile "${kernel-src}/Makefile";
lines = lib.splitString "\n" makefile;
get =
name:
let
line = lib.findFirst (
l: lib.hasPrefix "${name} =" (lib.strings.trim l)
) (throw "Makefile missing ${name}") lines;
in
lib.strings.trim (lib.removePrefix "${name} =" (lib.strings.trim line));
V = get "VERSION";
P = get "PATCHLEVEL";
S = get "SUBLEVEL";
E = get "EXTRAVERSION";
kver = "${V}.${P}.${S}${E}";
in
pkgs.callPackage (
{ buildLinux, ... }@args:
let
llvm = pkgs.llvmPackages_latest;
# buildLinux uses common-flags.nix which sets CC to the *unwrapped* compiler:
# CC=${lib.getExe stdenv.cc.cc}
# and appends extraMakeFlags at the end. :contentReference[oaicite:1]{index=1}
realClang = lib.getExe llvm.clang-unwrapped;
# Host tools are built with buildPackages.stdenv.cc (see common-flags HOSTCC). :contentReference[oaicite:2]{index=2}
buildPkgs = args.buildPackages or pkgs.buildPackages;
realHostCC = lib.getExe' buildPkgs.stdenv.cc "${buildPkgs.stdenv.cc.targetPrefix}cc";
realHostCXX = lib.getExe' buildPkgs.stdenv.cc "${buildPkgs.stdenv.cc.targetPrefix}c++";
clangSccache = pkgs.writeShellScriptBin "clang" ''
set -euo pipefail
: "''${SCCACHE_ENFORCE_MARKER:?SCCACHE_ENFORCE_MARKER is not set}"
: > "''${SCCACHE_ENFORCE_MARKER}"
export SCCACHE_DIR=${lib.escapeShellArg sccacheDir}
exec ${pkgs.sccache}/bin/sccache ${realClang} "$@"
'';
hostccSccache = pkgs.writeShellScriptBin "cc" ''
set -euo pipefail
: "''${SCCACHE_ENFORCE_MARKER:?SCCACHE_ENFORCE_MARKER is not set}"
: > "''${SCCACHE_ENFORCE_MARKER}"
export SCCACHE_DIR=${lib.escapeShellArg sccacheDir}
exec ${pkgs.sccache}/bin/sccache ${realHostCC} "$@"
'';
hostcxxSccache = pkgs.writeShellScriptBin "c++" ''
set -euo pipefail
: "''${SCCACHE_ENFORCE_MARKER:?SCCACHE_ENFORCE_MARKER is not set}"
: > "''${SCCACHE_ENFORCE_MARKER}"
export SCCACHE_DIR=${lib.escapeShellArg sccacheDir}
exec ${pkgs.sccache}/bin/sccache ${realHostCXX} "$@"
'';
structuredExtraConfig' =
(with lib.kernel; {
LTO_CLANG_THIN = yes;
# LTO_CLANG_FULL = no;
# LTO_NONE = no;
})
// structuredExtraConfig;
in
buildLinux (
args
// {
inherit kernelPatches extraConfig;
version = kver;
modDirVersion = kver;
src = kernel-src;
stdenv = llvm.stdenv;
extraMakeFlags =
(args.extraMakeFlags or [ ])
++ [
"LLVM=1"
"LLVM_IAS=1"
]
++ lib.optionals enforceSccache [
"CC=${lib.getExe clangSccache}"
"HOSTCC=${lib.getExe hostccSccache}"
"HOSTCXX=${lib.getExe hostcxxSccache}"
];
# Enforce that the wrappers were actually invoked at least once.
# sccache is a compiler wrapper; this is the contract were enforcing. :contentReference[oaicite:4]{index=4}
preBuild =
(args.preBuild or "")
+ lib.optionalString enforceSccache ''
export SCCACHE_ENFORCE_MARKER="$NIX_BUILD_TOP/.sccache-used"
rm -f "$SCCACHE_ENFORCE_MARKER"
${pkgs.sccache}/bin/sccache --start-server || true
${pkgs.sccache}/bin/sccache --zero-stats || true
'';
postBuild =
(args.postBuild or "")
+ lib.optionalString enforceSccache ''
if [ ! -e "$SCCACHE_ENFORCE_MARKER" ]; then
echo "FATAL: sccache enforcement failed: compiler wrappers were not invoked."
echo "This means buildLinux did not use your CC/HOSTCC overrides."
exit 1
fi
${pkgs.sccache}/bin/sccache --show-stats --stats-format text || true
'';
structuredExtraConfig = structuredExtraConfig';
ignoreConfigErrors = true;
extraMeta.branch = "${V}.${P}";
}
)
) { }