Compile Linux with Clang on NixOS

Posted:
Updated:

Overview

This short guide will teach you how to compile the Linux kernel with Clang and LLVM on NixOS. This guide is best viewed on a tablet, laptop, or desktop.

NixOS configuration

The configuration needed is minimal:

# configuration.nix
{
  lib,
  pkgs,
  ...
}:
# ...
{
  # Select our kernel packages (kernel and modules).
  boot.kernelPackages =
    with pkgs; # Cut down on repeated `pkgs.` declarations
    let
      # Choose whichever LLVM version you please. `llvmPackages` is the
      # default version, `llvmPackages_latest` is the latest (at the time of
      # writing, LLVM 17.0.6 and 18.1.8 respectively).
      llvm = llvmPackages_latest;
      # Same deal as LLVM; choose whichever kernel version you like.
      # `linux` is the latest LTS, `linux_latest` is the latest stable.
      kernel = linux_latest;
    in
    # Generate kernel modules for our custom kernel.
    linuxPackagesFor (
      # Override our chosen kernel version with our custom settings.
      (kernel.override {
        # Set our chosen version of LLVM as our standard environment.
        stdenv = overrideCC llvm.stdenv (
          # Tell our C compiler (Clang) to use LLVM bintools--normally GNU
          # binutils are used even with Clang as the compiler.
          llvm.stdenv.cc.override {
            bintools = llvm.bintools;
          }
        );

        # Tell Linux that we're compiling with Clang and LLVM.
        extraMakeFlags = [ "LLVM=1" ];

        # If you'd like to edit your kernel configuration, use
        # `structuredExtraConfig`. For example, some options available to us
        # when compiling with Clang and linking with LLD:
        structuredExtraConfig = {
          CFI_CLANG = lib.kernel.yes;
          LTO_CLANG_THIN = lib.kernel.yes;
        };
      }
    ).overrideAttrs
      # Work around another NixOS specific issue where builds with WERROR=y
      # are stopped by a benign error. See reference 1 below for details.
      # Technically, this fix is only necessary with WERROR=y but the issue
      # still causes a warning on builds where WERROR is unset.
      { env.NIX_CFLAGS_COMPILE = "-Wno-unused-command-line-argument"; }
    );
# ...
}

Compiling

All that’s left to do is rebuild the system. Run sudo nixos-rebuild boot and let it finish. Once it’s done, reboot and, assuming all went well, you should be booted into NixOS with your shiny new Clang-built Linux!

References


  1. Comment on “kernel built in NixOS failed to boot”, GitHub, 2024-01-22. Accessed 2024-07-20.