{ pkgs, lib, kernel-src, structuredExtraConfig ? { }, kernelPatches ? [ ], extraConfig ? "", sccacheDir ? "/var/cache/sccache", sccacheServerUds ? null, 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; rust = pkgs.rustc-unwrapped; buildPkgs = args.buildPackages or pkgs.buildPackages; buildLlvm = buildPkgs.llvmPackages_latest; llvmBuildPackages = buildPkgs // { stdenv = buildLlvm.stdenv; }; realClang = lib.getExe llvm.clang-unwrapped; realLd = lib.getExe' llvm.lld "ld.lld"; realAr = lib.getExe' llvm.llvm "llvm-ar"; realNm = lib.getExe' llvm.llvm "llvm-nm"; realStrip = lib.getExe' llvm.llvm "llvm-strip"; realObjcopy = lib.getExe' llvm.llvm "llvm-objcopy"; realObjdump = lib.getExe' llvm.llvm "llvm-objdump"; realReadelf = lib.getExe' llvm.llvm "llvm-readelf"; realHostCC = lib.getExe' buildLlvm.stdenv.cc "${buildLlvm.stdenv.cc.targetPrefix}cc"; realHostCXX = lib.getExe' buildLlvm.stdenv.cc "${buildLlvm.stdenv.cc.targetPrefix}c++"; realHostAr = lib.getExe' buildLlvm.llvm "llvm-ar"; realHostLd = lib.getExe' buildLlvm.lld "ld.lld"; realRustc = lib.getExe' rust "rustc"; realHostRustc = realRustc; mkSccacheWrapper = name: compiler: pkgs.writeShellScriptBin name '' set -euo pipefail export SCCACHE_DIR=${lib.escapeShellArg sccacheDir} ${lib.optionalString (sccacheServerUds != null) "export SCCACHE_SERVER_UDS=${lib.escapeShellArg sccacheServerUds}"} if [ -n "''${SCCACHE_ENFORCE_MARKER-}" ]; then : > "''${SCCACHE_ENFORCE_MARKER}" fi exec ${pkgs.sccache}/bin/sccache ${compiler} "$@" ''; clangSccache = mkSccacheWrapper "clang" realClang; hostccSccache = mkSccacheWrapper "cc" realHostCC; hostcxxSccache = mkSccacheWrapper "c++" realHostCXX; rustcSccache = pkgs.writeShellScriptBin "rustc" '' set -euo pipefail export SCCACHE_DIR=${lib.escapeShellArg sccacheDir} ${lib.optionalString (sccacheServerUds != null) "export SCCACHE_SERVER_UDS=${lib.escapeShellArg sccacheServerUds}"} if [ -n "''${SCCACHE_ENFORCE_MARKER-}" ]; then : > "''${SCCACHE_ENFORCE_MARKER}" fi exec ${pkgs.sccache}/bin/sccache ${realRustc} "$@" ''; hostrustcSccache = pkgs.writeShellScriptBin "rustc" '' set -euo pipefail export SCCACHE_DIR=${lib.escapeShellArg sccacheDir} ${lib.optionalString (sccacheServerUds != null) "export SCCACHE_SERVER_UDS=${lib.escapeShellArg sccacheServerUds}"} if [ -n "''${SCCACHE_ENFORCE_MARKER-}" ]; then : > "''${SCCACHE_ENFORCE_MARKER}" fi exec ${pkgs.sccache}/bin/sccache ${realHostRustc} "$@" ''; 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; buildPackages = llvmBuildPackages; extraMakeFlags = (args.extraMakeFlags or [ ]) ++ [ "LLVM=1" "LLVM_IAS=1" "CC=${if enforceSccache then lib.getExe clangSccache else realClang}" "LD=${realLd}" "AR=${realAr}" "NM=${realNm}" "STRIP=${realStrip}" "OBJCOPY=${realObjcopy}" "OBJDUMP=${realObjdump}" "READELF=${realReadelf}" "HOSTCC=${if enforceSccache then lib.getExe hostccSccache else realHostCC}" "HOSTCXX=${if enforceSccache then lib.getExe hostcxxSccache else realHostCXX}" "HOSTAR=${realHostAr}" "HOSTLD=${realHostLd}" "RUSTC=${if enforceSccache then lib.getExe rustcSccache else realRustc}" "HOSTRUSTC=${if enforceSccache then lib.getExe hostrustcSccache else realHostRustc}" ] ; preBuild = (args.preBuild or "") + lib.optionalString enforceSccache '' export SCCACHE_DIR=${lib.escapeShellArg sccacheDir} ${lib.optionalString (sccacheServerUds != null) "export SCCACHE_SERVER_UDS=${lib.escapeShellArg sccacheServerUds}"} ''; buildPhase = if enforceSccache then '' runHook preBuild export SCCACHE_DIR=${lib.escapeShellArg sccacheDir} ${lib.optionalString (sccacheServerUds != null) "export SCCACHE_SERVER_UDS=${lib.escapeShellArg sccacheServerUds}"} export SCCACHE_ENFORCE_MARKER="$NIX_BUILD_TOP/.sccache-used" rm -f "$SCCACHE_ENFORCE_MARKER" make "''${makeFlags[@]}" "''${buildFlags[@]}" if [ ! -e "$SCCACHE_ENFORCE_MARKER" ]; then echo "FATAL: sccache enforcement failed during buildPhase: compiler wrappers were not invoked." echo "This means the build stage did not use your CC/HOSTCC/HOSTCXX/RUSTC/HOSTRUSTC overrides." exit 1 fi ${pkgs.sccache}/bin/sccache --show-stats --stats-format text || true runHook postBuild '' else (args.buildPhase or '' runHook preBuild make "''${makeFlags[@]}" "''${buildFlags[@]}" runHook postBuild ''); postBuild = args.postBuild or ""; structuredExtraConfig = structuredExtraConfig'; ignoreConfigErrors = true; extraMeta.branch = "${V}.${P}"; } ) ) { }