File kernel-cachyos.spec of Package kernel-cachyos

#
# spec file for package kernel-cachyos
#
# Copyright (c) 2024-2026 CachyOS team
# openSUSE Tumbleweed conversion
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon.
#
# norootforbuild
# needssslcertforbuild
%define debug_package %{nil}

# ----------------------------------------------------------------------
# Tumbleweed (suse_version >= 1550) is usrmerged
# ----------------------------------------------------------------------
%if 0%{?suse_version} >= 1550
%define usrmerged 1
%define kernel_module_directory /usr/lib/modules
%else
%define usrmerged 0
%define kernel_module_directory /lib/modules
%endif

# ----------------------------------------------------------------------
# Linux Kernel Versions -- change only these three defines for updates
# ----------------------------------------------------------------------
%define _basekver 7.0
%define _stablekver rc5
%define _rpmver %{version}-%{release}
%define _tarkver %{_basekver}-%{_stablekver}
%define _tag cachyos-%{_tarkver}-2
# _kver must match the actual KERNELRELEASE produced by the kernel Makefile.
# For rc kernels: VERSION.PATCHLEVEL.SUBLEVEL-EXTRAVERSION + CONFIG_LOCALVERSION
%define _kver %{_basekver}.0-%{_stablekver}-cachyos

# ----------------------------------------------------------------------
# Build options
# ----------------------------------------------------------------------
# Build a minimal kernel via modprobed.db to reduce build times
%define _build_minimal 0

# Build the kernel with clang + ThinLTO
%define _build_lto 0

# Build nvidia-open kernel modules
%define _nv_ver 595.58.03
%define _nv_pkg NVIDIA-kernel-module-source-%{_nv_ver}

# Tickrate (100, 250, 300, 500, 600, 750, 1000)
%define _hz_tick 1000

# x86_64 ISA level (1-4)
%define _x86_64_lvl 3

# ----------------------------------------------------------------------
# Directory layout
# ----------------------------------------------------------------------
%define _kernel_dir %{kernel_module_directory}/%{_kver}
%define _devel_dir /usr/src/linux-%{_kver}

%define _patch_src https://raw.githubusercontent.com/CachyOS/kernel-patches/master/%{_basekver}

%if %{_build_lto}
%define _lto_args CC=clang CXX=clang++ LD=ld.lld LLVM=1 LLVM_IAS=1
%endif

%define _module_args KERNEL_UNAME=%{_kver} IGNORE_PREEMPT_RT_PRESENCE=1 SYSSRC=%{_builddir}/%{_tag} SYSOUT=%{_builddir}/%{_tag}

# ----------------------------------------------------------------------
# Package metadata
# ----------------------------------------------------------------------
Name:           kernel-cachyos%{?_lto_args:-lto}
Summary:        Linux BORE %{?_lto_args:+ LTO }Cachy Sauce Kernel by CachyOS
Version:        %{_basekver}~%{_stablekver}
Release:        cachyos1%{?_lto_args:.lto}
License:        GPL-2.0-only
Group:          System/Kernel
URL:            https://cachyos.org
ExclusiveArch:  x86_64

AutoReq:        no
Provides:       %{name} = %{_rpmver}
Provides:       kernel = %{_rpmver}
Provides:       kernel-base = %{_rpmver}
Provides:       multiversion(kernel)
Requires(pre):  coreutils
Requires(pre):  suse-kernel-rpm-scriptlets
Requires(post): suse-kernel-rpm-scriptlets
Requires(post): suse-module-tools
Requires(post): modutils
Requires(preun): suse-kernel-rpm-scriptlets
Requires(postun): suse-kernel-rpm-scriptlets
OrderWithRequires(post): dracut
Suggests:       dracut
OrderWithRequires(post): perl-Bootloader
Suggests:       perl-Bootloader
OrderWithRequires(post): update-bootloader
Suggests:       update-bootloader
Recommends:     kernel-firmware
Conflicts:      xfsprogs < 4.3.0-1

# ----------------------------------------------------------------------
# Build dependencies
# ----------------------------------------------------------------------
BuildRequires:  bc
BuildRequires:  bison
BuildRequires:  coreutils
BuildRequires:  dwarves
BuildRequires:  fdupes
BuildRequires:  flex
BuildRequires:  gcc
BuildRequires:  gettext-tools
BuildRequires:  libelf-devel
BuildRequires:  libopenssl-devel
BuildRequires:  make
BuildRequires:  modutils
BuildRequires:  openssl
BuildRequires:  perl
BuildRequires:  python3-base
BuildRequires:  python3-PyYAML
BuildRequires:  clang
BuildRequires:  lld
BuildRequires:  llvm
BuildRequires:  zstd
BuildRequires:  gcc-c++
BuildRequires:  pesign-obs-integration

# ----------------------------------------------------------------------
# Sources & Patches -- filenames must match _service download_url names
# ----------------------------------------------------------------------
Source0:        %{_tag}.tar.gz
Source1:        config

%if %{_build_minimal}
Source2:        minimal-modprobed.db
%endif

Patch0:         0001-bore-cachy.patch

%if %{_build_lto}
Patch1:         dkms-clang.patch
%endif

Patch2:         0001-acpi-call.patch
Patch3:         0001-cgroup-vram.patch
Patch4:         0001-rt-i915.patch

Source10:       %{_nv_pkg}.tar.xz

# openSUSE rpmify patches (ksym-provides, supported-flag, etc.)
Source14:       series.conf
Source105:      patches.rpmify.tar.bz2

%description
The CachyOS kernel with the BORE scheduler and additional performance
patches for openSUSE. Contains the kernel image, modules, and boot files.

# ----------------------------------------------------------------------
# = prep =
# ----------------------------------------------------------------------
%prep
%setup -q -n %{_tag}
# Extract NVIDIA open kernel module source alongside the kernel tree
tar xf %{SOURCE10} -C %{_builddir}

# Extract and apply openSUSE rpmify patches (ksym-provides, supported-flag, etc.)
tar xjf %{SOURCE105}
grep '^[[:space:]]*patches\.rpmify/' %{SOURCE14} | while read p; do
    if [ -f "$p" ]; then
        echo "Applying rpmify patch: $p"
        patch -p1 < "$p"
    fi
done

%autopatch -p1 -v -M 9

cp %{SOURCE1} .config

# --- Default kernel config overrides ---
scripts/config -e CACHY -e SCHED_BORE
scripts/config --set-str CONFIG_LOCALVERSION "-cachyos"

# Tickrate
case %{_hz_tick} in
    100|250|300|500|600|750|1000)
        scripts/config -e HZ_%{_hz_tick} --set-val HZ %{_hz_tick};;
    *)
        echo "Invalid tickrate value, using default 1000"
        scripts/config -e HZ_1000 --set-val HZ 1000;;
esac

# x86_64 ISA level
%if %{_x86_64_lvl} < 5 && %{_x86_64_lvl} > 0
scripts/config --set-val X86_64_VERSION %{_x86_64_lvl}
%else
echo "Invalid x86_64 ISA Level. Using x86_64_v3"
scripts/config --set-val X86_64_VERSION 3
%endif

# Secure Boot / IMA
scripts/config -e CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT
scripts/config -e CONFIG_IMA
scripts/config -e CONFIG_IMA_APPRAISE_BOOTPARAM
scripts/config -e CONFIG_IMA_APPRAISE
scripts/config -e CONFIG_IMA_ARCH_POLICY

# Module signing and EFI stub for Secure Boot
scripts/config -e CONFIG_MODULE_SIG
scripts/config -e CONFIG_MODULE_SIG_SHA256
scripts/config --set-str CONFIG_MODULE_SIG_HASH sha256
scripts/config -e CONFIG_MODULE_SIG_ALL
scripts/config -e CONFIG_EFI
scripts/config -e CONFIG_EFI_STUB

%if %{_build_lto}
scripts/config -e LTO_CLANG_THIN
%endif

%if %{_build_minimal}
make %{?_lto_args} %{?_smp_mflags} LSMOD=%{SOURCE2} localmodconfig
%else
make %{?_lto_args} %{?_smp_mflags} olddefconfig
%endif

# --- Signing key setup ---
# If OBS provides signing certs (%_sourcedir/.kernel_signing_key.pem), use them.
# Otherwise generate a self-signed key (user must enroll via mokutil --import).
if [ -f %{_sourcedir}/.kernel_signing_key.pem ]; then
    ln -sf %{_sourcedir}/.kernel_signing_key.pem .
else
    cat > .kernel.genkey <<GENKEY_EOF
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts

[ req_distinguished_name ]
O = kernel-cachyos
CN = kernel-cachyos Secure Boot Signing Key
emailAddress = unspecified@unspecified.org

[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
GENKEY_EOF
    openssl req -new -nodes -utf8 -sha256 -days 36500 \
        -batch -x509 -config .kernel.genkey \
        -outform PEM -out .kernel_signing_key.pem \
        -keyout .kernel_signing_key.pem
fi
scripts/config --set-str CONFIG_MODULE_SIG_KEY ".kernel_signing_key.pem"

diff -u %{SOURCE1} .config || :



# ----------------------------------------------------------------------
# = build =
# ----------------------------------------------------------------------
%build
make %{?_lto_args} %{?_smp_mflags} all
make %{?_lto_args} %{?_smp_mflags} -C tools/bpf/bpftool vmlinux.h feature-clang-bpf-co-re=1

# Build NVIDIA open kernel modules
cd %{_builddir}/%{_nv_pkg}
CFLAGS= CXXFLAGS= LDFLAGS= make %{?_smp_mflags} %{_module_args} IGNORE_CC_MISMATCH=yes CONFIG_DEBUG_INFO_BTF_MODULES= modules
cd %{_builddir}/%{_tag}



# ----------------------------------------------------------------------
# = install =
# ----------------------------------------------------------------------
%install
# The -devel subpackage provides symlink targets that brp-25-symlink cannot
# see during the main package build. Suppress the stale link error.
export NO_BRP_STALE_LINK_ERROR=yes

# --- Kernel image ---
echo "Installing the kernel image..."
install -Dm644 "$(make %{?_lto_args} %{?_smp_mflags} -s image_name)" "%{buildroot}%{_kernel_dir}/vmlinuz"
zstdmt -19 < Module.symvers > %{buildroot}%{_kernel_dir}/symvers.zst

# --- Boot directory files ---
echo "Installing boot files..."
install -dm755 %{buildroot}/boot
install -m644 "$(make %{?_lto_args} %{?_smp_mflags} -s image_name)" "%{buildroot}/boot/vmlinuz-%{_kver}"
cp System.map %{buildroot}/boot/System.map-%{_kver}
cp .config %{buildroot}/boot/config-%{_kver}

# --- Kernel modules ---
echo "Installing kernel modules..."
ZSTD_CLEVEL=19 make %{?_lto_args} %{?_smp_mflags} INSTALL_MOD_PATH="%{buildroot}%{?usrmerged:/usr}" INSTALL_MOD_STRIP=1 DEPMOD=/doesnt/exist modules_install

# --- Development files ---
echo "Installing development files..."
install -Dt %{buildroot}%{_devel_dir} -m644 .config Makefile Module.symvers System.map tools/bpf/bpftool/vmlinux.h
cp .config %{buildroot}%{_kernel_dir}/config
cp System.map %{buildroot}%{_kernel_dir}/System.map
cp --parents `find  -type f -name "Makefile*" -o -name "Kconfig*"` %{buildroot}%{_devel_dir}
rm -rf %{buildroot}%{_devel_dir}/scripts
rm -rf %{buildroot}%{_devel_dir}/include
cp -a scripts %{buildroot}%{_devel_dir}
rm -rf %{buildroot}%{_devel_dir}/scripts/tracing
rm -f %{buildroot}%{_devel_dir}/scripts/spdxcheck.py

# Files needed for make scripts
cp -a --parents security/selinux/include/classmap.h %{buildroot}%{_devel_dir}
cp -a --parents security/selinux/include/initial_sid_to_string.h %{buildroot}%{_devel_dir}
cp -a --parents tools/include/tools/be_byteshift.h %{buildroot}%{_devel_dir}
cp -a --parents tools/include/tools/le_byteshift.h %{buildroot}%{_devel_dir}

# Files needed for make prepare -- Generic
cp -a --parents tools/include/linux/compiler* %{buildroot}%{_devel_dir}
cp -a --parents tools/include/linux/types.h %{buildroot}%{_devel_dir}
cp -a --parents tools/build/Build.include %{buildroot}%{_devel_dir}
cp --parents tools/build/fixdep.c %{buildroot}%{_devel_dir}
cp --parents tools/objtool/sync-check.sh %{buildroot}%{_devel_dir}
cp -a --parents tools/bpf/resolve_btfids %{buildroot}%{_devel_dir}
cp --parents security/selinux/include/policycap_names.h %{buildroot}%{_devel_dir}
cp --parents security/selinux/include/policycap.h %{buildroot}%{_devel_dir}

cp -a --parents tools/include/asm %{buildroot}%{_devel_dir}
cp -a --parents tools/include/asm-generic %{buildroot}%{_devel_dir}
cp -a --parents tools/include/linux %{buildroot}%{_devel_dir}
cp -a --parents tools/include/uapi/asm %{buildroot}%{_devel_dir}
cp -a --parents tools/include/uapi/asm-generic %{buildroot}%{_devel_dir}
cp -a --parents tools/include/uapi/linux %{buildroot}%{_devel_dir}
cp -a --parents tools/include/vdso %{buildroot}%{_devel_dir}
cp --parents tools/scripts/utilities.mak %{buildroot}%{_devel_dir}
cp -a --parents tools/lib/subcmd %{buildroot}%{_devel_dir}
cp --parents tools/lib/*.c %{buildroot}%{_devel_dir}
cp --parents tools/objtool/*.[ch] %{buildroot}%{_devel_dir}
cp --parents tools/objtool/Build %{buildroot}%{_devel_dir}
cp --parents tools/objtool/include/objtool/*.h %{buildroot}%{_devel_dir}
cp -a --parents tools/lib/bpf %{buildroot}%{_devel_dir}
cp --parents tools/lib/bpf/Build %{buildroot}%{_devel_dir}
cp -a --parents tools/docs/kernel-doc %{buildroot}%{_devel_dir}

# x86_64 headers
cp -a --parents arch/x86/include %{buildroot}%{_devel_dir}
cp -a --parents tools/arch/x86/include %{buildroot}%{_devel_dir}
cp -a include %{buildroot}%{_devel_dir}/include
cp -a sound/soc/sof/sof-audio.h %{buildroot}%{_devel_dir}/sound/soc/sof
cp -a tools/objtool/objtool %{buildroot}%{_devel_dir}/tools/objtool/
cp -a tools/objtool/fixdep %{buildroot}%{_devel_dir}/tools/objtool/

# Files needed for make prepare -- x86_64
cp -a --parents arch/x86/entry/syscalls/syscall_32.tbl %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/entry/syscalls/syscall_64.tbl %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/tools/relocs_32.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/tools/relocs_64.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/tools/relocs.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/tools/relocs_common.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/tools/relocs.h %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/purgatory/purgatory.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/purgatory/stack.S %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/purgatory/setup-x86_64.S %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/purgatory/entry64.S %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/boot/string.h %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/boot/string.c %{buildroot}%{_devel_dir}
cp -a --parents arch/x86/boot/ctype.h %{buildroot}%{_devel_dir}

cp -a --parents scripts/syscalltbl.sh %{buildroot}%{_devel_dir}
cp -a --parents scripts/syscallhdr.sh %{buildroot}%{_devel_dir}

cp -a --parents tools/arch/x86/include/asm %{buildroot}%{_devel_dir}
cp -a --parents tools/arch/x86/include/uapi/asm %{buildroot}%{_devel_dir}
cp -a --parents tools/objtool/arch/x86/lib %{buildroot}%{_devel_dir}
cp -a --parents tools/arch/x86/lib/ %{buildroot}%{_devel_dir}
cp -a --parents tools/arch/x86/tools/gen-insn-attr-x86.awk %{buildroot}%{_devel_dir}
cp -a --parents tools/objtool/arch/x86/ %{buildroot}%{_devel_dir}

# Cleanup build artifacts from devel tree
echo "Cleaning up development files..."
find %{buildroot}%{_devel_dir}/scripts \( -iname "*.o" -o -iname "*.cmd" \) -exec rm -f {} +
find %{buildroot}%{_devel_dir}/tools \( -iname "*.o" -o -iname "*.cmd" \) -exec rm -f {} +
touch -r %{buildroot}%{_devel_dir}/Makefile \
    %{buildroot}%{_devel_dir}/include/generated/uapi/linux/version.h \
    %{buildroot}%{_devel_dir}/include/config/auto.conf

# build/source symlinks
rm -rf %{buildroot}%{_kernel_dir}/build
ln -s %{_devel_dir} %{buildroot}%{_kernel_dir}/build
ln -s %{_kernel_dir}/build %{buildroot}%{_kernel_dir}/source

# Stub initrd to reserve /boot space (bz#530778 equivalent)
echo "Creating stub initrd..."
install -dm755 %{buildroot}/boot
dd if=/dev/zero of=%{buildroot}/boot/initrd-%{_kver} bs=1024 seek=2047 count=1
chmod 0600 %{buildroot}/boot/initrd-%{_kver}

# Install NVIDIA open kernel modules
cd %{_builddir}/%{_nv_pkg}
echo "Installing NVIDIA open kernel modules..."
install -dm755 %{buildroot}%{_kernel_dir}/extramodules
install -m644 kernel-open/*.ko %{buildroot}%{_kernel_dir}/extramodules/
install -Dt %{buildroot}%{_licensedir}/%{name}-nvidia-open -m644 COPYING

# Sign NVIDIA kernel modules
cd %{_builddir}/%{_tag}
for ko in %{buildroot}%{_kernel_dir}/extramodules/*.ko; do
    scripts/sign-file sha256 .kernel_signing_key.pem certs/signing_key.x509 "${ko}"
    zstd --rm -19 "${ko}"
done

# --- Secure Boot: pesign-obs-integration ---
# BRP_PESIGN_FILES tells the brp-99-pesign hook which files to sign.
# On OBS with signing permissions, this signs the EFI kernel image and modules.
# Without OBS signing, the self-signed key is used (user enrolls via mokutil).
export BRP_PESIGN_FILES="%{_kernel_dir}/vmlinuz *.ko.zst"
export BRP_PESIGN_COMPRESS_MODULE=zstd

# Install OBS signing certificates if available (for MOK enrollment)
_has_certs=0
if [ -d %{_sourcedir}/.kernel_signing_certs ]; then
    for f in %{_sourcedir}/.kernel_signing_certs/*.crt; do
        install -Dm644 "${f}" %{buildroot}/etc/uefi/certs/
        _has_certs=1
    done
fi

# Install the signing key public cert for out-of-tree module building
install -Dm644 certs/signing_key.x509 %{buildroot}%{_devel_dir}/certs/signing_key.x509

# HMAC for FIPS
if [ -x /usr/lib/rpm/pesign/gen-hmac ]; then
    /usr/lib/rpm/pesign/gen-hmac -r %{buildroot} /boot/vmlinuz-%{_kver}
fi

# Deduplicate files
%fdupes %{buildroot}%{_devel_dir}

# ----------------------------------------------------------------------
# Main package scriptlets
# ----------------------------------------------------------------------
%post
/sbin/depmod -a %{_kver}
if [ -x /usr/bin/dracut ]; then
    /usr/bin/dracut -f --kver "%{_kver}" || :
fi
if [ -x /sbin/update-bootloader ]; then
    /sbin/update-bootloader --refresh || :
fi

%preun
if [ -x /sbin/update-bootloader ]; then
    /sbin/update-bootloader --remove "%{_kver}" || :
fi

%posttrans
if [ -x /sbin/depmod ]; then
    /sbin/depmod -a %{_kver}
fi

%files
%license COPYING
%ghost %attr(0600, root, root) /boot/initrd-%{_kver}
/boot/vmlinuz-%{_kver}
/boot/.vmlinuz-%{_kver}.hmac
/boot/System.map-%{_kver}
/boot/config-%{_kver}
%dir %{_kernel_dir}
%{_kernel_dir}/vmlinuz
%{_kernel_dir}/modules.builtin
%{_kernel_dir}/modules.builtin.modinfo
%{_kernel_dir}/symvers.zst
%{_kernel_dir}/config
%{_kernel_dir}/System.map
%{_kernel_dir}/modules.order
%{_kernel_dir}/build
%{_kernel_dir}/source
%{_kernel_dir}/kernel

# ----------------------------------------------------------------------
# Subpackage: kernel-cachyos-devel
# ----------------------------------------------------------------------
%package devel
Summary:        Development files for building kernel modules against %{name}
Group:          Development/Sources
Provides:       %{name}-devel = %{_rpmver}
Provides:       kernel-devel = %{_rpmver}
Provides:       multiversion(kernel)
AutoReqProv:    no
Requires:       %{name} = %{_rpmver}
Requires:       kernel-devel%{?variant} = %{_rpmver}
Requires(pre):  coreutils
Requires(pre):  findutils
Requires:       findutils
Requires:       perl
Requires:       libopenssl-devel
Requires:       libelf-devel
Requires:       bison
Requires:       flex
Requires:       make
Requires:       modutils
%if %{_build_lto}
Requires:       clang
Requires:       lld
Requires:       llvm
%else
Requires:       gcc
%endif

%description devel
This package provides kernel headers and makefiles sufficient to build
modules against the CachyOS kernel.

%post devel
if [ -x /usr/bin/find ] && [ -x /usr/bin/hardlink ]; then
    cd %{_devel_dir} && \
    /usr/bin/find . -type f | while read f; do
        hardlink -c /usr/src/linux-*/%{_arch}/"$f" "$f" > /dev/null 2>&1
    done
fi

%files devel
%{_devel_dir}

# ----------------------------------------------------------------------
# Subpackage: kernel-cachyos-nvidia-open
# ----------------------------------------------------------------------
%package nvidia-open
Summary:        NVIDIA open %{_nv_ver} kernel modules for %{name}
Group:          System/Kernel
License:        MIT AND GPL-2.0-only
Provides:       nvidia-open-driver-kmp = %{_nv_ver}
Provides:       multiversion(kernel)
Requires:       %{name} = %{_rpmver}
Conflicts:      nvidia-gfxG06-kmp
Recommends:     nvidia-drivers-G06 >= %{_nv_ver}

%description nvidia-open
This package provides NVIDIA open %{_nv_ver} kernel modules for the
CachyOS kernel. This replaces the need for nvidia-open-dkms.
Requires a Turing (RTX 20xx) or newer GPU.

%post nvidia-open
/sbin/depmod -a %{_kver}

%postun nvidia-open
/sbin/depmod -a %{_kver}

%files nvidia-open
%dir %{_licensedir}/%{name}-nvidia-open
%license %{_licensedir}/%{name}-nvidia-open/COPYING
%dir %{_kernel_dir}/extramodules
%{_kernel_dir}/extramodules/*

%changelog
openSUSE Build Service is sponsored by