Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dkms for openSUSE:Factory checked in 
at 2026-01-26 11:06:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dkms (Old)
 and      /work/SRC/openSUSE:Factory/.dkms.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dkms"

Mon Jan 26 11:06:00 2026 rev:15 rq:1329073 version:3.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/dkms/dkms.changes        2025-09-16 
18:18:24.119103342 +0200
+++ /work/SRC/openSUSE:Factory/.dkms.new.1928/dkms.changes      2026-01-26 
11:06:03.699378995 +0100
@@ -1,0 +2,9 @@
+Sat Jan  3 17:19:11 UTC 2026 - Alexandru Gabriel Bradatan 
<[email protected]>
+
+- Update to version 3.3.0
+  * Add per-module BUILD_EXCLUSIVE_* directives
+  * New build_environment directive to specify custom compilers
+- Update to version 3.2.2
+  * Various fixes
+
+-------------------------------------------------------------------

Old:
----
  dkms-3.2.1.tar.gz

New:
----
  dkms-3.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dkms.spec ++++++
--- /var/tmp/diff_new_pack.qJX8ek/_old  2026-01-26 11:06:05.407449334 +0100
+++ /var/tmp/diff_new_pack.qJX8ek/_new  2026-01-26 11:06:05.415449663 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package dkms
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           dkms
-Version:        3.2.1
+Version:        3.3.0
 Release:        0
 Summary:        Dynamic Kernel Module Support Framework
 License:        GPL-2.0-only

++++++ dkms-3.2.1.tar.gz -> dkms-3.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/.github/workflows/shellcheck.yml 
new/dkms-3.3.0/.github/workflows/shellcheck.yml
--- old/dkms-3.2.1/.github/workflows/shellcheck.yml     2025-05-12 
09:58:11.000000000 +0200
+++ new/dkms-3.3.0/.github/workflows/shellcheck.yml     2025-11-03 
11:40:02.000000000 +0100
@@ -9,7 +9,7 @@
     name: Shellcheck
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
       - name: Run ShellCheck
         uses: ludeeus/action-shellcheck@master
         with:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/.github/workflows/tests.yml 
new/dkms-3.3.0/.github/workflows/tests.yml
--- old/dkms-3.2.1/.github/workflows/tests.yml  2025-05-12 09:58:11.000000000 
+0200
+++ new/dkms-3.3.0/.github/workflows/tests.yml  2025-11-03 11:40:02.000000000 
+0100
@@ -10,57 +10,72 @@
 jobs:
   test-distributions:
     name: Build in containers
+    continue-on-error: true
     strategy:
       matrix:
         distro:
+          - {name: "almalinux", tag: "10"}
           - {name: "almalinux", tag: "9"}
           - {name: "almalinux", tag: "8"}
+          - {name: "alpine", tag: "3.22", variant: "-lts"}
+          - {name: "alpine", tag: "3.22", variant: "-virt"}
           - {name: "alpine", tag: "3.21", variant: "-lts"}
           - {name: "alpine", tag: "3.21", variant: "-virt"}
           - {name: "alpine", tag: "3.20", variant: "-lts"}
           - {name: "alpine", tag: "3.20", variant: "-virt"}
-          - {name: "alpine", tag: "3.19", variant: "-lts"}
-          - {name: "alpine", tag: "3.19", variant: "-virt"}
-          - {name: "alpine", tag: "3.18", variant: "-lts"}
-          - {name: "alpine", tag: "3.18", variant: "-virt"}
           - {name: "archlinux", tag: "latest"}
           - {name: "archlinux", tag: "latest", variant: "-lts"}
           - {name: "archlinux", tag: "latest", variant: "-zen"}
           - {name: "centos", tag: "stream10", url: "quay.io/centos/"}
           - {name: "centos", tag: "stream9", url: "quay.io/centos/"}
-          - {name: "debian", tag: "testing"}
+          - {name: "debian", tag: "13"}
           - {name: "debian", tag: "12"}
           - {name: "fedora", tag: "rawhide", url: 
"registry.fedoraproject.org/"}
+          - {name: "fedora", tag: "43", url: "registry.fedoraproject.org/"}
           - {name: "fedora", tag: "42", url: "registry.fedoraproject.org/"}
-          - {name: "fedora", tag: "41", url: "registry.fedoraproject.org/"}
           - {name: "gentoo/stage3", tag: "latest"}
           - {name: "opensuse/tumbleweed", tag: "latest", variant: "-default", 
url: "registry.opensuse.org/"}
           - {name: "opensuse/leap", tag: "15.6", variant: "-default", url: 
"registry.opensuse.org/"}
+          - {name: "opensuse/leap", tag: "16.0", variant: "-default", url: 
"registry.opensuse.org/"}
+          - {name: "oraclelinux", tag: "10", uek: "ol10_UEKR8"}
+          - {name: "oraclelinux", tag: "9", uek: "ol9_UEKR8", gcc: 
"gcc-toolset-14"}
+          - {name: "oraclelinux", tag: "8", uek: "ol8_UEKR7", gcc: 
"gcc-toolset-11"}
+          - {name: "ubuntu", tag: "25.10"}
           - {name: "ubuntu", tag: "25.04"}
-          - {name: "ubuntu", tag: "24.10"}
           - {name: "ubuntu", tag: "24.04"}
           - {name: "ubuntu", tag: "22.04"}
-          - {name: "ubuntu", tag: "20.04"}
     runs-on: ubuntu-24.04
     container:
       image: ${{ matrix.distro.url }}${{ matrix.distro.name }}:${{ 
matrix.distro.tag }}
 
     steps:
-    - name: Install git for checkout action
-      if: contains(matrix.distro.name, 'opensuse')
+    - name: Checkout
+      if: matrix.distro.name == 'opensuse/leap' && matrix.distro.tag == '15.6'
+      # openSUSE Leap 15.6 does not have tar in the base image
       run: |
-        zypper --non-interactive install git
-
-    - uses: actions/checkout@v4
+        zypper --non-interactive install tar gzip
+    - uses: actions/checkout@v5
 
     - name: Install dependencies for Red Hat based distributions
       if: matrix.distro.name == 'almalinux' || matrix.distro.name == 'centos' 
|| matrix.distro.name == 'fedora'
-      # Relax crypto policies on Fedora 43+ to allow RSA signatures
+      # Relax crypto policies to allow RSA signatures
       run: |
         dnf install -y gawk diffutils elfutils-libelf gcc kernel kernel-devel 
make openssl patch crypto-policies-scripts
         update-crypto-policies --set LEGACY
         make install-redhat
 
+    - name: Install dependencies for Oracle Linux
+      if: matrix.distro.name == 'oraclelinux'
+      # Relax crypto policies to allow RSA signatures
+      run: |
+        dnf config-manager --set-enabled ${{ matrix.distro.uek }}
+        dnf install -y gawk diffutils elfutils-libelf gcc kernel-uek 
kernel-uek-devel make openssl patch crypto-policies-scripts
+        update-crypto-policies --set LEGACY
+        make install-redhat
+        if [ -n "${{ matrix.distro.gcc }}" ]; then
+          echo "build_environment=\"/opt/rh/${{ matrix.distro.gcc }}/enable\"" 
>> /etc/dkms/framework.conf.d/uek.conf
+        fi
+
     - name: Install Alpine dependencies
       if: matrix.distro.name == 'alpine'
       run: |
@@ -76,6 +91,7 @@
     - name: Install Debian dependencies
       if: matrix.distro.name == 'debian'
       run: |
+        export DEBIAN_FRONTEND=noninteractive
         apt-get update -q
         apt-get install -qy make linux-headers-amd64 linux-image-amd64 openssl 
xz-utils patch
         make install-debian
@@ -97,6 +113,7 @@
     - name: Install Ubuntu dependencies
       if: matrix.distro.name == 'ubuntu'
       run: |
+        export DEBIAN_FRONTEND=noninteractive
         apt-get update -q
         apt-get install -qy gcc make linux-headers-generic linux-image-generic 
openssl shim-signed patch
         make install-debian
@@ -129,4 +146,7 @@
             [ -e "$depmod" ] && grep -r ^search "$depmod" || true
         done
 
+        # Run all tests
         ./run_test.sh
+
+        make uninstall
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/.gitignore new/dkms-3.3.0/.gitignore
--- old/dkms-3.2.1/.gitignore   2025-05-12 09:58:11.000000000 +0200
+++ new/dkms-3.3.0/.gitignore   2025-11-03 11:40:02.000000000 +0100
@@ -15,3 +15,4 @@
 
 test_cmd_expected_output.log
 test_cmd_output.log
+*.code-workspace
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/Makefile new/dkms-3.3.0/Makefile
--- old/dkms-3.2.1/Makefile     2025-05-12 09:58:11.000000000 +0200
+++ new/dkms-3.3.0/Makefile     2025-11-03 11:40:02.000000000 +0100
@@ -1,7 +1,7 @@
-RELEASE_DATE := "12 May 2025"
+RELEASE_DATE := "03 Nov 2025"
 RELEASE_MAJOR := 3
-RELEASE_MINOR := 2
-RELEASE_MICRO := 1
+RELEASE_MINOR := 3
+RELEASE_MICRO := 0
 RELEASE_NAME := dkms
 RELEASE_VERSION := $(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_MICRO)
 RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_VERSION)
@@ -85,13 +85,36 @@
        install -D -m 0755 debian_kernel_postinst.d 
$(DESTDIR)$(KCONF)/header_postinst.d/dkms
        install -D -m 0755 debian_kernel_preinst.d 
$(DESTDIR)$(KCONF)/preinst.d/dkms
        install -D -m 0755 debian_kernel_prerm.d $(DESTDIR)$(KCONF)/prerm.d/dkms
-       install -D -m 0644 dkms.service $(DESTDIR)$(SYSTEMD)/dkms.service
 
 install-doc:
        $(if $(strip $(DOC)),$(error Setting DOCDIR is not supported))
        install -d -m 0755 $(DESTDIR)/usr/share/doc/dkms
        install -m 0644 COPYING README.md $(DESTDIR)/usr/share/doc/dkms
 
+uninstall:
+       $(if $(strip $(VAR)),$(error Setting VAR is not supported))
+       $(if $(strip $(ETC)),$(error Setting ETC is not supported))
+       $(if $(strip $(BASHDIR)),$(error Setting BASHDIR is not supported))
+       $(if $(strip $(SHAREDIR)),$(error Setting SHAREDIR is not supported))
+       $(if $(strip $(DOC)),$(error Setting DOCDIR is not supported))
+       $(RM) $(DESTDIR)$(SBIN)/dkms
+       $(RM) $(DESTDIR)/etc/dkms/framework.conf
+       $(RM) -r $(DESTDIR)/etc/dkms/framework.conf.d
+       $(RM) $(DESTDIR)/usr/share/bash-completion/completions/dkms
+       $(RM) $(DESTDIR)/usr/share/zsh/site-functions/_dkms
+       $(RM) $(DESTDIR)/usr/share/man/man8/dkms.8
+       $(RM) $(DESTDIR)$(SYSTEMD)/dkms.service
+       $(RM) $(DESTDIR)$(KINSTALL)/40-dkms.install
+       $(RM) $(DESTDIR)$(LIBDIR)/common.postinst
+       $(RM) $(DESTDIR)$(LIBDIR)/dkms_autoinstaller
+       $(RM) $(DESTDIR)/usr/share/apport/package-hooks/dkms_packages.py
+       $(RM) $(DESTDIR)$(KCONF)/postinst.d/dkms
+       $(RM) $(DESTDIR)$(KCONF)/header_postinst.d/dkms
+       $(RM) $(DESTDIR)$(KCONF)/preinst.d/dkms
+       $(RM) $(DESTDIR)$(KCONF)/prerm.d/dkms
+       $(RM) -r $(DESTDIR)/usr/share/doc/dkms
+       $(RM) -r $(DESTDIR)/var/lib/dkms
+
 .PHONY = tarball
 
 TARBALL=$(BUILDDIR)/dist/$(RELEASE_STRING).tar.gz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/dkms.8.in new/dkms-3.3.0/dkms.8.in
--- old/dkms-3.2.1/dkms.8.in    2025-05-12 09:58:11.000000000 +0200
+++ new/dkms-3.3.0/dkms.8.in    2025-11-03 11:40:02.000000000 +0100
@@ -802,6 +802,19 @@
 would only be built for kernels that have PCI enabled, but the RT patchset
 disabled.
 .TP
+.B BUILD_EXCLUSIVE_KERNEL[#]=, BUILD_EXCLUSIVE_KERNEL_MIN[#]=, 
BUILD_EXCLUSIVE_KERNEL_MAX[#]=, BUILD_EXCLUSIVE_ARCH[#]=, 
BUILD_EXCLUSIVE_CONFIG[#]=
+These optional per-module directives function identically to their global 
counterparts
+but apply only to the specific module at the given index. They allow you to 
specify
+different BUILD_EXCLUSIVE constraints for each module in a multi-module 
package.
+The global BUILD_EXCLUSIVE directives are still checked for backward 
compatibility,
+and if any module fails either the global or its specific per-module 
constraints,
+the build will be excluded.
+
+For example, if you have two modules in your package:
+.B BUILD_EXCLUSIVE_KERNEL[0]="^5\..*"
+.B BUILD_EXCLUSIVE_KERNEL[1]="^6\..*"
+Module 0 would only be built for kernel 5.x, while module 1 would only be 
built for kernel 6.x.
+.TP
 .B POST_ADD=
 The name of the script to be run after an
 .B add
@@ -940,6 +953,27 @@
 .B compress_gzip_opts, compress_xz_opts, compress_zstd_opts
 Control how modules are compressed. By default, the highest available level of 
compression is used.
 .TP
+.B build_environment
+If the directive is set to any non null-value, when building modules, the 
exported variables that are in the file will be imported into the DKMS shell 
with the
+.B source
+command.
+
+Can be used to specify a custom
+.B gcc
+installed in a custom path; and the variable
+.B $kernelver
+can be used inside the environment file to represent the target kernel 
version. Some examples:
+
+Define a custom script to point to a specific GCC (
+.B export CC=/opt/gcc12/bin/gcc
+):
+.B build_environment="/opt/gcc12/env"
+
+Enable the software collection
+.B gcc-toolset-11
+and use it for building an UEK kernel on Oracle Linux:
+.B build_environment="/opt/rh/gcc-toolset-11/enable"
+.TP
 .B post_transaction
 If the directive is set to any non null-value, the content of the directive 
will be executed with any command that change the content of the kernel modules 
folder, that is
 .B dkms autoinstall, dkms install
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/dkms.in new/dkms-3.3.0/dkms.in
--- old/dkms-3.2.1/dkms.in      2025-05-12 09:58:11.000000000 +0200
+++ new/dkms-3.3.0/dkms.in      2025-11-03 11:40:02.000000000 +0100
@@ -103,8 +103,7 @@
 # All of the variables not related to signing we will accept from 
framework.conf.
 readonly dkms_framework_nonsigning_variables="source_tree dkms_tree 
install_tree tmp_location
    verbose symlink_modules autoinstall_all_kernels modprobe_on_install 
parallel_jobs
-   compress_gzip_opts compress_xz_opts compress_zstd_opts
-   post_transaction"
+   compress_gzip_opts compress_xz_opts compress_zstd_opts build_environment 
post_transaction"
 # All of the signing related variables we will accept from framework.conf.
 readonly dkms_framework_signing_variables="sign_file mok_signing_key 
mok_certificate"
 
@@ -149,6 +148,11 @@
 unset make_tarball_rm_temp_dir_name load_tarball_rm_temp_dir_name
 trap on_exit EXIT
 
+CP()
+{
+    cp --reflink=auto "$@"
+}
+
 # Run a command that we may or may not want to be detailed about.
 invoke_command()
 {
@@ -673,15 +677,18 @@
     fi
 
     # Determine number of modules
+    # The arrays are possibly sparse, so use the maximum index instead of the 
array length
     local s
-    num_modules=0
+    local max_index
+    max_index=-1
     # shellcheck disable=SC2153
-    for s in ${#BUILT_MODULE_NAME[@]} \
-        ${#BUILT_MODULE_LOCATION[@]} \
-        ${#DEST_MODULE_NAME[@]} \
-        ${#DEST_MODULE_LOCATION[@]}; do
-        ((s > num_modules)) && num_modules=$s
+    for s in "${!BUILT_MODULE_NAME[@]}" \
+        "${!BUILT_MODULE_LOCATION[@]}" \
+        "${!DEST_MODULE_NAME[@]}" \
+        "${!DEST_MODULE_LOCATION[@]}"; do
+        ((s > max_index)) && max_index=$s
     done
+    num_modules=$((max_index + 1))
 
     # Set module naming/location arrays
     local index
@@ -739,14 +746,12 @@
         # Override location for specific distributions
         dest_module_location[index]="$(override_dest_module_location 
"${dest_module_location[index]}")"
 
-        # Fail if no DEST_MODULE_LOCATION
-        if [[ ! ${DEST_MODULE_LOCATION[$index]} ]]; then
-            echo "dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive 
specified for record #$index.">&2
-            return_value=1
-        fi
-
         # Fail if bad DEST_MODULE_LOCATION
         case ${DEST_MODULE_LOCATION[$index]} in
+            "")
+                echo "dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive 
specified for record #$index.">&2
+                return_value=1
+                ;;
             /kernel*)
                 ;;
             /updates*)
@@ -754,9 +759,9 @@
             /extra*)
                 ;;
             *)
-            echo "dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does not 
begin with">&2
-            echo "'/kernel', '/updates', or '/extra' in record #$index.">&2
-            return_value=1
+                echo "dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does 
not begin with">&2
+                echo "'/kernel', '/updates', or '/extra' in record #$index.">&2
+                return_value=1
             ;;
         esac
     done
@@ -804,20 +809,81 @@
     fi
     done
 
-    # Set build_exclude
-    [[ $obsolete_by && ! $BUILD_EXCLUSIVE_KERNEL_MAX ]] && 
BUILD_EXCLUSIVE_KERNEL_MAX=$obsolete_by
-    [[ $BUILD_EXCLUSIVE_KERNEL && ! $1 =~ $BUILD_EXCLUSIVE_KERNEL ]] && 
build_exclude="yes"
-    [[ $BUILD_EXCLUSIVE_KERNEL_MIN && "$(VER "$1")" < "$(VER 
"$BUILD_EXCLUSIVE_KERNEL_MIN")" ]] && build_exclude="yes"
-    [[ $BUILD_EXCLUSIVE_KERNEL_MAX && "$(VER "$1")" > "$(VER 
"$BUILD_EXCLUSIVE_KERNEL_MAX")" ]] && build_exclude="yes"
-    [[ $BUILD_EXCLUSIVE_ARCH && ! $2 =~ $BUILD_EXCLUSIVE_ARCH ]] && 
build_exclude="yes"
-    if [[ $BUILD_EXCLUSIVE_CONFIG && -e "${kernel_config}" ]]; then
-        local kconf
-        for kconf in $BUILD_EXCLUSIVE_CONFIG ; do
-            case "$kconf" in
-                !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && 
build_exclude="yes" ;;
-                *)  grep -q "^${kconf}=[ym]" "${kernel_config}" || 
build_exclude="yes" ;;
-            esac
+    # Set build_exclude (preserve backward compatibility for OBSOLETE_BY)
+    # Only set global BUILD_EXCLUSIVE_KERNEL_MAX if obsolete_by is set and no 
global or per-module restrictions exist
+    if [[ $obsolete_by && ! $BUILD_EXCLUSIVE_KERNEL_MAX ]]; then
+        # Check if we have any per-module KERNEL_MAX restrictions
+        local has_per_module_max=false
+        for ((i=0; i < num_modules; i++)); do
+            [[ ${BUILD_EXCLUSIVE_KERNEL_MAX[i]} ]] && has_per_module_max=true 
&& break
         done
+        # Only set global if no per-module restrictions exist (backward 
compatibility)
+        [[ $has_per_module_max == false ]] && 
BUILD_EXCLUSIVE_KERNEL_MAX=$obsolete_by
+    fi
+
+    # Function to check BUILD_EXCLUSIVE conditions for a specific module
+    check_build_exclusive_for_module() {
+        local module_index="$1"
+        local kernel_version="$2"
+        local arch="$3"
+
+        # Set has_build_exclusive_directives if any BUILD_EXCLUSIVE directives 
are defined
+        if [[ $BUILD_EXCLUSIVE_KERNEL || $BUILD_EXCLUSIVE_KERNEL_MIN || 
$BUILD_EXCLUSIVE_KERNEL_MAX || $BUILD_EXCLUSIVE_ARCH || $BUILD_EXCLUSIVE_CONFIG 
]]; then
+            has_build_exclusive_directives=true
+        elif [[ ${BUILD_EXCLUSIVE_KERNEL[$module_index]} || 
${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]} || 
${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]} || 
${BUILD_EXCLUSIVE_ARCH[$module_index]} || 
${BUILD_EXCLUSIVE_CONFIG[$module_index]} ]]; then
+            has_build_exclusive_directives=true
+        fi
+
+        # Check global BUILD_EXCLUSIVE directives (backward compatibility)
+        [[ $BUILD_EXCLUSIVE_KERNEL && ! $kernel_version =~ 
$BUILD_EXCLUSIVE_KERNEL ]] && return 1
+        [[ $BUILD_EXCLUSIVE_KERNEL_MIN && "$(VER "$kernel_version")" < "$(VER 
"$BUILD_EXCLUSIVE_KERNEL_MIN")" ]] && return 1
+        [[ $BUILD_EXCLUSIVE_KERNEL_MAX && "$(VER "$kernel_version")" > "$(VER 
"$BUILD_EXCLUSIVE_KERNEL_MAX")" ]] && return 1
+        [[ $BUILD_EXCLUSIVE_ARCH && ! $arch =~ $BUILD_EXCLUSIVE_ARCH ]] && 
return 1
+
+        # Check per-module BUILD_EXCLUSIVE directives
+        [[ ${BUILD_EXCLUSIVE_KERNEL[$module_index]} && ! $kernel_version =~ 
${BUILD_EXCLUSIVE_KERNEL[$module_index]} ]] && return 1
+        [[ ${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]} && "$(VER 
"$kernel_version")" < "$(VER "${BUILD_EXCLUSIVE_KERNEL_MIN[$module_index]}")" 
]] && return 1
+        [[ ${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]} && "$(VER 
"$kernel_version")" > "$(VER "${BUILD_EXCLUSIVE_KERNEL_MAX[$module_index]}")" 
]] && return 1
+        [[ ${BUILD_EXCLUSIVE_ARCH[$module_index]} && ! $arch =~ 
${BUILD_EXCLUSIVE_ARCH[$module_index]} ]] && return 1
+
+        # Check BUILD_EXCLUSIVE_CONFIG (both global and per-module)
+        if [[ $BUILD_EXCLUSIVE_CONFIG && -e "${kernel_config}" ]]; then
+            local kconf
+            for kconf in $BUILD_EXCLUSIVE_CONFIG ; do
+                case "$kconf" in
+                    !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && 
return 1 ;;
+                    *)  grep -q "^${kconf}=[ym]" "${kernel_config}" || return 
1 ;;
+                esac
+            done
+        fi
+
+        if [[ ${BUILD_EXCLUSIVE_CONFIG[$module_index]} && -e 
"${kernel_config}" ]]; then
+            local kconf
+            for kconf in ${BUILD_EXCLUSIVE_CONFIG[$module_index]} ; do
+                case "$kconf" in
+                    !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && 
return 1 ;;
+                    *)  grep -q "^${kconf}=[ym]" "${kernel_config}" || return 
1 ;;
+                esac
+            done
+        fi
+
+        return 0
+    }
+
+    # Check if any module should be excluded from build
+    build_exclude=""
+    buildable_modules=0
+    has_build_exclusive_directives=false
+
+    for ((index=0; index < num_modules; index++)); do
+        if check_build_exclusive_for_module "$index" "$1" "$2"; then
+            ((buildable_modules++))
+        fi
+    done
+
+    # If no modules can be built and BUILD_EXCLUSIVE directives are defined, 
set build_exclude to fail the entire build
+    if [[ $buildable_modules -eq 0 && $has_build_exclusive_directives = true 
]]; then
+        build_exclude="yes"
     fi
 
     # Helper function to check yes/no values
@@ -1020,7 +1086,7 @@
         return 0
     fi
     local dkms_module
-    dkms_module=$(compressed_or_uncompressed 
"$dkms_tree/$module/$module_version/$1/$2/module/" "${4}")
+    dkms_module=$(compressed_or_uncompressed 
"$dkms_tree/$module/$module_version/$1/$2/module" "${4}")
 
     local cmp_res
     cmp_res="$(compare_module_version "${kernels_module}" "${dkms_module}")"
@@ -1344,8 +1410,8 @@
     # Error out if build_exclude is set
     [[ $build_exclude ]] && diewarn 77 \
         "The $base_dir/dkms.conf"\
-        "for module $module/$module_version includes a BUILD_EXCLUSIVE 
directive"\
-        "which does not match this kernel/arch/config."\
+        "for module $module/$module_version includes BUILD_EXCLUSIVE 
directives"\
+        "which do not match this kernel/arch/config for any modules."\
         "This indicates that it should not be built."
 
     # Error out if source_tree is basically empty (binary-only dkms tarball w/ 
--force check)
@@ -1366,7 +1432,17 @@
 
     if [[ -e "${kernel_config}" ]]; then
         local cc
-        cc=$(sed -n 's|^CONFIG_CC_VERSION_TEXT="\([^ ]*\) .*"|\1|p' 
"${kernel_config}")
+        # Depending on the kernel version the strings might be formatted 
differently (with or without quotes):
+        #
+        # $ grep CONFIG_CC_VERSION_TEXT= 
/lib/modules/5.15.0-141-generic/build/.config
+        # CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
+        # $ grep CONFIG_CC_VERSION_TEXT= 
/lib/modules/5.15.0-141-generic/build/include/config/auto.conf
+        # CONFIG_CC_VERSION_TEXT="gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
+        # $ grep CONFIG_CC_VERSION_TEXT= 
/lib/modules/6.8.0-60-generic/build/.config
+        # CONFIG_CC_VERSION_TEXT="x86_64-linux-gnu-gcc-12 (Ubuntu 
12.3.0-1ubuntu1~22.04) 12.3.0"
+        # $ grep CONFIG_CC_VERSION_TEXT= 
/lib/modules/6.8.0-60-generic/build/include/config/auto.conf
+        # CONFIG_CC_VERSION_TEXT=x86_64-linux-gnu-gcc-12 (Ubuntu 
12.3.0-1ubuntu1~22.04) 12.3.0
+        cc=$(sed -n 's|^CONFIG_CC_VERSION_TEXT="*\([^" ]*\) .*|\1|p' 
"${kernel_config}")
         if command -v "$cc" >/dev/null; then
             CC="$cc"
             KERNEL_CC="$cc"
@@ -1397,6 +1473,12 @@
         fi
     fi
 
+    # Source build environment file if specified
+    if [[ -n "$build_environment" && -f "$build_environment" ]]; then
+        # shellcheck disable=SC1090
+        source <( (source "$build_environment" &>/dev/null; export -p) )
+    fi
+
     # Check for missing BUILD_DEPENDS
     bd_missing=
     # shellcheck disable=SC2153
@@ -1418,7 +1500,7 @@
 
     # Set up temporary build directory for build
     rm -rf "${build_dir:?}"
-    cp -a "$source_dir/" "$build_dir"
+    CP -a "$source_dir/" "$build_dir"
 
     echo "DKMS (@RELEASE_STRING@) make.log for $module/$module_version for 
kernel $kernelver ($arch)" >> "$build_log"
     date >> "$build_log"
@@ -1449,8 +1531,13 @@
         report_build_problem 10 "Bad return status for module build on kernel: 
$kernelver ($arch)" \
         "Consult $build_log for more information."
 
-    # Make sure all the modules built successfully
+    # Make sure all the modules built successfully (skip excluded modules)
     for ((count=0; count < num_modules; count++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$count" "$kernelver" "$arch"; 
then
+            continue
+        fi
+
         [[ -e 
${built_module_location[$count]}${built_module_name[$count]}$module_uncompressed_suffix
 ]] && continue
         report_build_problem 7 \
             "Build of 
${built_module_location[$count]}${built_module_name[$count]}$module_uncompressed_suffix
 failed for: $kernelver ($arch)" \
@@ -1462,14 +1549,18 @@
     mkdir -p "$kernelver_dir"
     local -r tmp_base_dir=$(mktemp_or_die -d 
"$kernelver_dir/.tmp_${arch}_XXXXXX")
     mkdir -p "$tmp_base_dir/log"
-    [[ $kernel_config ]] && cp -f "$kernel_config" "$tmp_base_dir/log/"
 
     # Save a copy of the new module
     mkdir -p "$tmp_base_dir/module"
     if [[ -f "$build_dir/Module.symvers" ]] ; then
-        cp -f "$build_dir/Module.symvers" "$tmp_base_dir/module/Module.symvers"
+        CP -f "$build_dir/Module.symvers" "$tmp_base_dir/module/Module.symvers"
     fi
     for ((count=0; count < num_modules; count++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$count" "$kernelver" "$arch"; 
then
+            continue
+        fi
+
         local the_module
         local built_module
         local compressed_module
@@ -1509,14 +1600,19 @@
             zstd $compress_zstd_opts -f "$built_module" || compressed_module=""
         fi
         if [[ $compressed_module ]]; then
-            cp -f "$compressed_module" 
"$tmp_base_dir/module/${dest_module_name[$count]}$module_suffix"
+            CP -f "$compressed_module" 
"$tmp_base_dir/module/${dest_module_name[$count]}$module_suffix"
         else
-            cp -f "$built_module" 
"$tmp_base_dir/module/${dest_module_name[$count]}$module_uncompressed_suffix"
+            CP -f "$built_module" 
"$tmp_base_dir/module/${dest_module_name[$count]}$module_uncompressed_suffix"
         fi
     done
 
-    # Validate build completeness
+    # Validate build completeness (skip excluded modules)
     for ((index=0; index < num_modules; index++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$index" "$kernelver" "$arch"; 
then
+            continue
+        fi
+
         local m
         local f
         m=${dest_module_name[index]}
@@ -1633,8 +1729,13 @@
     set_module_suffix "$kernelver"
     read_conf_strict_or_die "$kernelver" "$arch"
 
-    # Validate build completeness
+    # Validate build completeness (skip excluded modules)
     for ((index=0; index < num_modules; index++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$index" "$kernelver" "$arch"; 
then
+            continue
+        fi
+
         local m
         local f
         m=${dest_module_name[index]}
@@ -1661,6 +1762,11 @@
     fi
 
     for ((count=0; count < num_modules; count++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$count" "$kernelver" "$arch"; 
then
+            continue
+        fi
+
         # Check this version against what is already in the kernel
         check_version_sanity "$kernelver" "$arch" "$obsolete_by" 
"${dest_module_name[$count]}" || continue
 
@@ -1724,7 +1830,7 @@
         dest_name=${toinstall##*/}
         echo "Installing $dest_dir/$dest_name"
         mkdir -p "$dest_dir"
-        cp -f $symlink "$toinstall" "$dest_dir/$dest_name" || die 6 "Copying 
'$toinstall' failed"
+        CP -f $symlink "$toinstall" "$dest_dir/$dest_name" || die 6 "Copying 
'$toinstall' failed"
         any_module_installed=1
 
     done
@@ -2057,8 +2163,45 @@
 maybe_uninstall_module()
 {
     is_module_installed "$module" "$module_version" "$1" "$2" || {
-        echo "Module $module/$module_version is not installed for kernel $1 
($2)."\
-            "Skipping..."
+        # Check if this module might have been excluded due to BUILD_EXCLUSIVE 
restrictions
+        # If so, don't show the "not installed" message since it's expected
+        local was_excluded=false
+
+        # Try to read the dkms.conf to check BUILD_EXCLUSIVE settings
+        if [[ -f "$dkms_tree/$module/$module_version/source/dkms.conf" ]]; then
+            # Temporarily read the conf to check BUILD_EXCLUSIVE settings
+            local saved_last_mvka="$last_mvka"
+            local saved_last_mvka_conf="$last_mvka_conf"
+            local saved_num_modules="$num_modules"
+
+            # Read conf without modifying global state permanently
+            read_conf "$1" "$2" 
"$dkms_tree/$module/$module_version/source/dkms.conf" 2>/dev/null || true
+
+            # If this package has any BUILD_EXCLUSIVE restrictions, suppress 
the message
+            # because it can be confusing to users (modules might be built but 
not installed)
+            local has_build_exclusive=false
+            for ((index=0; index < num_modules; index++)); do
+                if [[ ${BUILD_EXCLUSIVE_KERNEL[index]} || 
${BUILD_EXCLUSIVE_KERNEL_MIN[index]} || ${BUILD_EXCLUSIVE_KERNEL_MAX[index]} || 
${BUILD_EXCLUSIVE_ARCH[index]} || ${BUILD_EXCLUSIVE_CONFIG[index]} ]]; then
+                    has_build_exclusive=true
+                    break
+                fi
+            done
+
+            if [[ $has_build_exclusive == true ]]; then
+                was_excluded=true
+            fi
+
+            # Restore global state
+            last_mvka="$saved_last_mvka"
+            last_mvka_conf="$saved_last_mvka_conf"
+            num_modules="$saved_num_modules"
+        fi
+
+        # Only show the "not installed" message if it wasn't excluded due to 
BUILD_EXCLUSIVE
+        if [[ $was_excluded == false ]]; then
+            echo "Module $module/$module_version is not installed for kernel 
$1 ($2)."\
+                "Skipping..."
+        fi
         return 0
     }
     do_uninstall "$1" "$2"
@@ -2237,6 +2380,11 @@
     read_conf "$3" "$4" "$dkms_tree/$1/$2/source/dkms.conf"
     [[ -d $dkms_tree/$1/original_module/$3/$4 ]] && echo -n " (Original 
modules exist)"
     for ((count=0; count < num_modules; count++)); do
+        # Skip modules that are excluded due to BUILD_EXCLUSIVE restrictions
+        if ! check_build_exclusive_for_module "$count" "$3" "$4"; then
+            continue
+        fi
+
         tree_mod=$(compressed_or_uncompressed "$dkms_tree/$1/$2/$3/$4/module" 
"${dest_module_name[$count]}")
         if [[ ! $tree_mod ]]; then
             echo -n " (Built modules are missing in the kernel modules folder)"
@@ -2398,7 +2546,7 @@
             
kernel_version_list="${kernel_version_list}-kernel${kernelver[$i]}-${arch[$i]}"
         fi
         mkdir -p "$temp_module_dir"
-        cp -rf "$intree_module_dir" "$temp_module_dir"
+        CP -rf "$intree_module_dir" "$temp_module_dir"
     done
     fi
 
@@ -2415,12 +2563,12 @@
         echo "$module" > "$binary_only_dir/PACKAGE_NAME"
         echo "$module_version" > "$binary_only_dir/PACKAGE_VERSION"
         [[ ! $conf ]] && conf="$source_dir/dkms.conf"
-        cp -f "$conf" "$binary_only_dir/" 2>/dev/null
+        CP -f "$conf" "$binary_only_dir/" 2>/dev/null
     else
         echo ""
         echo "Marking $source_dir for archiving..."
         mkdir -p "$temp_dir_name/dkms_source_tree"
-        cp -rf "$source_dir/"* "$temp_dir_name/dkms_source_tree"
+        CP -fprT "$source_dir/" "$temp_dir_name/dkms_source_tree"
     fi
 
     # shellcheck disable=SC1083
@@ -2542,7 +2690,7 @@
                 echo "Creating $source_dir"
                 mkdir -p "$source_dir"
                 echo "Copying dkms.conf to $source_dir ..."
-                cp -rf "$temp_dir_name/dkms_binaries_only/dkms.conf" 
"$source_dir"
+                CP -rf "$temp_dir_name/dkms_binaries_only/dkms.conf" 
"$source_dir"
             fi
             ;;
     esac
@@ -2564,7 +2712,7 @@
             echo "Loading $dkms_dir_location..."
             rm -rf "${dkms_dir_location:?}"
             mkdir -p "$dkms_dir_location"
-            cp -rf "$directory/"* "$dkms_dir_location/"
+            CP -rf "$directory/"* "$dkms_dir_location/"
         fi
     done
 
@@ -2741,7 +2889,7 @@
             ;;
     esac
     mkdir -p "$source_tree/$module-$module_version"
-    cp -fr "$from"/* "$source_tree/$module-$module_version"
+    CP -fprT "$from/" "$source_tree/$module-$module_version"
 }
 
 # This code used to be in dkms_autoinstaller.
@@ -3159,7 +3307,6 @@
 # Source in configuration not related to signing
 read_framework_conf "$dkms_framework_nonsigning_variables"
 
-
 # Clear out command line argument variables
 module=""
 module_version=""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/dkms_common.postinst.in 
new/dkms-3.3.0/dkms_common.postinst.in
--- old/dkms-3.2.1/dkms_common.postinst.in      2025-05-12 09:58:11.000000000 
+0200
+++ new/dkms-3.3.0/dkms_common.postinst.in      2025-11-03 11:40:02.000000000 
+0100
@@ -208,6 +208,13 @@
     fi
 fi
 
+if [ -z "$KERNELS" ]; then
+    echo "WARNING: No kernel headers were found, skipping module build."
+    echo "         To get the headers for the running kernel ($CURRENT_KERNEL)"
+    echo "         please install the linux-headers-$CURRENT_KERNEL package."
+    exit 0
+fi
+
 # Take care of displaying newline separated list
 echo "Building for $KERNELS" | tr '\n' ',' \
     | sed -e 's/,/, /g; s/, $/\n/; s/, \([^,]\+\)$/ and \1/'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/dkms_framework.conf.in 
new/dkms-3.3.0/dkms_framework.conf.in
--- old/dkms-3.2.1/dkms_framework.conf.in       2025-05-12 09:58:11.000000000 
+0200
+++ new/dkms-3.3.0/dkms_framework.conf.in       2025-11-03 11:40:02.000000000 
+0100
@@ -56,8 +56,13 @@
 # compress_xz_opts="--check=crc32 --lzma2=dict=1MiB -6"
 # compress_zstd_opts="-q --rm -T0 -3"
 
+# Path to a file containing environment variables to be sourced by DKMS.
+# This file will be sourced for the build command. $kernelver can be used in
+# the environment file to represent the target kernel version.
+# build_environment=""
+
 # Command to run at the end of every DKMS transaction, for example after a new
-# kernel has been installed on the system and all modules have been succesfully
+# kernel has been installed on the system and all modules have been 
successfully
 # built and installed.
 # The command listed is executed if set to any non null value. $kernelver can 
be
 # used in path to represent the target kernel version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/redhat_kernel_install.d.in 
new/dkms-3.3.0/redhat_kernel_install.d.in
--- old/dkms-3.2.1/redhat_kernel_install.d.in   2025-05-12 09:58:11.000000000 
+0200
+++ new/dkms-3.3.0/redhat_kernel_install.d.in   2025-11-03 11:40:02.000000000 
+0100
@@ -3,15 +3,13 @@
 COMMAND=$1
 KERNEL_VERSION=$2
 
-res=0
 case "$COMMAND" in
     add)
         dkms kernel_postinst --kernelver "$KERNEL_VERSION"
-        res=$?
         ;;
     remove)
         dkms kernel_prerm --kernelver "$KERNEL_VERSION"
-        res=$?
         ;;
 esac
-exit $res
+
+exit 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dkms-3.2.1/run_test.sh new/dkms-3.3.0/run_test.sh
--- old/dkms-3.2.1/run_test.sh  2025-05-12 09:58:11.000000000 +0200
+++ new/dkms-3.3.0/run_test.sh  2025-11-03 11:40:02.000000000 +0100
@@ -52,35 +52,11 @@
     "dkms_deprecated_test"
     "dkms_build_exclusive_test"
     "dkms_build_exclusive_dependencies_test"
+    "dkms_per_module_config_test"
+    "dkms_per_module_kernel_version_test"
+    "dkms_per_module_config_exclusive_test"
 )
 TEST_TMPDIRS=(
-    "/usr/src/dkms_test-1.0"
-    "/usr/src/dkms_test-2.0"
-    "/usr/src/dkms_dependencies_test-1.0"
-    "/usr/src/dkms_dependencies_rebuild_test-1.0"
-    "/usr/src/dkms_circular_dependencies_test-1.0"
-    "/usr/src/dkms_replace_test-2.0"
-    "/usr/src/dkms_noautoinstall_test-1.0"
-    "/usr/src/dkms_failing_test-1.0"
-    "/usr/src/dkms_failing_dependencies_test-1.0"
-    "/usr/src/dkms_multiver_test-1.0"
-    "/usr/src/dkms_multiver_test-2.0"
-    "/usr/src/dkms_nover_test-1.0"
-    "/usr/src/dkms_emptyver_test-1.0"
-    "/usr/src/dkms_nover_update_test-1.0"
-    "/usr/src/dkms_nover_update_test-2.0"
-    "/usr/src/dkms_nover_update_test-3.0"
-    "/usr/src/dkms_conf_test-1.0"
-    "/usr/src/dkms_duplicate_test-1.0"
-    "/usr/src/dkms_duplicate_built_test-1.0"
-    "/usr/src/dkms_duplicate_dest_test-1.0"
-    "/usr/src/dkms_patches_test-1.0"
-    "/usr/src/dkms_scripts_test-1.0"
-    "/usr/src/dkms_noisy_test-1.0"
-    "/usr/src/dkms_crlf_test-1.0"
-    "/usr/src/dkms_deprecated_test-1.0"
-    "/usr/src/dkms_build_exclusive_test-1.0"
-    "/usr/src/dkms_build_exclusive_dependencies_test-1.0"
     "${tmpdir}/dkms_test_dir_${KERNEL_VER}/"
 )
 TEST_TMPFILES=(
@@ -118,11 +94,14 @@
 
 clean_dkms_env() {
     local found_module
+    local module
+    local version
+    local dir
+    local file
 
     for module in "${TEST_MODULES[@]}"; do
         found_module=$(dkms_status_grep_dkms_module "${module}")
         if [[ $found_module ]] ; then
-            local version
             for version in 1.0 2.0 3.0; do
                 [[ ! -d "/var/lib/dkms/${module}/${version}" ]] || dkms remove 
"${module}/${version}" >/dev/null || true
             done
@@ -130,6 +109,9 @@
         rm -rf "/var/lib/dkms/${module}/"
         rm -f 
"/lib/modules/${KERNEL_VER}/${expected_dest_loc}/${module}.ko${mod_compression_ext}"
         rm -f 
"/lib/modules/${KERNEL_VER}/kernel/extra/${module}.ko${mod_compression_ext}"
+        for version in 1.0 2.0 3.0; do
+            rm -rf "/usr/src/${module}-${version}"
+        done
     done
     for dir in "${TEST_TMPDIRS[@]}"; do
         rm -rf "$dir"
@@ -243,13 +225,16 @@
     local output_log=test_cmd_output.log
     local expected_output_log=test_cmd_expected_output.log
     local error_code=0
+    local make_log
 
     shift
     cat > "${expected_output_log}"
     stdbuf -o L -e L "$@" > "${output_log}" 2>&1 || error_code=$?
+    make_log=$(awk '{print $2}' "${output_log}" | grep make.log || true)
     if [[ "${error_code}" != "${expected_error_code}" ]] ; then
         echo "Error: command '$*' returned status ${error_code} instead of 
expected ${expected_error_code}"
         cat "${output_log}"
+        [ -z "${make_log}" ] || cat "${make_log}"
         rm "${expected_output_log}" "${output_log}"
         return 1
     fi
@@ -374,7 +359,7 @@
 distro_modsigkey=/var/lib/dkms/mok.key
 distro_modsigcert=/var/lib/dkms/mok.pub
 case "${os_id}" in
-    centos | fedora | rhel | ovm | almalinux)
+    centos | fedora | rhel | ovm | almalinux | ol)
         expected_dest_loc=extra
         mod_compression_ext=.xz
         ;;
@@ -1005,6 +990,8 @@
 echo '*** Testing dkms autoinstall/kernel_{postinst/prerm}, dkms_autoinstaller'
 ############################################################################
 
+set_signing_message "dkms_test" "1.0"
+
 echo 'Testing without modules and without headers'
 
 echo ' Running dkms autoinstall'
@@ -2631,8 +2618,8 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall of module dkms_noisy_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
@@ -2714,8 +2701,8 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall on ${KERNEL_VER} succeeded for module(s) dkms_dependencies_test 
dkms_noisy_test dkms_patches_test dkms_scripts_test dkms_test.
@@ -2869,7 +2856,6 @@
 
 echo 'Removing the build-exclusive test module'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m 
dkms_build_exclusive_test -v 1.0 << EOF
-Module dkms_build_exclusive_test/1.0 is not installed for kernel ${KERNEL_VER} 
(${KERNEL_ARCH}). Skipping...
 Module dkms_build_exclusive_test/1.0 is not built for kernel ${KERNEL_VER} 
(${KERNEL_ARCH}). Skipping...
 
 Deleting module dkms_build_exclusive_test/1.0 completely from the DKMS tree.
@@ -2945,8 +2931,6 @@
 '/kernel', '/updates', or '/extra' in record #0.
 dkms.conf: Error! 'BUILT_MODULE_NAME' directive ends in '.o' or '.ko' in 
record #1.
 dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified for record #1.
-dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does not begin with
-'/kernel', '/updates', or '/extra' in record #1.
 dkms.conf: Error! Unsupported AUTOINSTALL value 'maybe'
 
 Error! Bad conf file.
@@ -3025,6 +3009,22 @@
 
 # --------------------------------------------------------------------------
 
+echo 'Testing dkms.conf with sparse BUILT_MODULE_NAME[] array (expected error)'
+run_with_expected_error 8 dkms add test/dkms_conf_test_sparse_arrays << EOF
+dkms.conf: Error! No 'BUILT_MODULE_NAME' directive specified for record #0.
+dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified for record #0.
+dkms.conf: Error! No 'BUILT_MODULE_NAME' directive specified for record #2.
+dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified for record #2.
+dkms.conf: Error! No 'BUILT_MODULE_NAME' directive specified for record #4.
+dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does not begin with
+'/kernel', '/updates', or '/extra' in record #4.
+
+Error! Bad conf file.
+File: ${abspwd}/test/dkms_conf_test_sparse_arrays/dkms.conf does not represent 
a valid dkms.conf file.
+EOF
+
+# --------------------------------------------------------------------------
+
 echo 'Testing dkms.conf with missing patch'
 run_with_expected_output dkms add test/dkms_conf_test_patch_missing << EOF
 Creating symlink /var/lib/dkms/dkms_conf_test/1.0/source -> 
/usr/src/dkms_conf_test-1.0
@@ -3670,7 +3670,7 @@
 if [[ ! $only || $only = exclusive ]]; then
 
 ############################################################################
-echo '*** Running tests with BUILD_EXCLUSIVE_* modules'
+echo '*** Testing modules with BUILD_EXCLUSIVE_* directives'
 ############################################################################
 
 set_signing_message "dkms_test" "1.0"
@@ -3688,8 +3688,8 @@
 echo '(Not) building the build-exclusive test module'
 run_with_expected_error 77 dkms build -k "${KERNEL_VER}" -m 
dkms_build_exclusive_test -v 1.0 << EOF
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 EOF
 run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
@@ -3701,8 +3701,8 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall on ${KERNEL_VER} was skipped for module(s) 
dkms_build_exclusive_test.
@@ -3725,8 +3725,8 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall of module dkms_test/1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH})
@@ -3766,8 +3766,8 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall of module dkms_failing_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
@@ -3829,14 +3829,14 @@
 ${SIGNING_PROLOGUE}
 Autoinstall of module dkms_build_exclusive_test/1.0 for kernel ${KERNEL_VER} 
(${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_test/1.0 includes a BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall of module dkms_build_exclusive_dependencies_test/1.0 for kernel 
${KERNEL_VER} (${KERNEL_ARCH})
 Warning: The 
/var/lib/dkms/dkms_build_exclusive_dependencies_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
-for module dkms_build_exclusive_dependencies_test/1.0 includes a 
BUILD_EXCLUSIVE directive
-which does not match this kernel/arch/config.
+for module dkms_build_exclusive_dependencies_test/1.0 includes BUILD_EXCLUSIVE 
directives
+which do not match this kernel/arch/config for any modules.
 This indicates that it should not be built.
 
 Autoinstall on ${KERNEL_VER} was skipped for module(s) 
dkms_build_exclusive_test dkms_build_exclusive_dependencies_test.
@@ -3866,6 +3866,94 @@
 
 remove_module_source_tree /usr/src/dkms_build_exclusive_test-1.0
 
+############################################################################
+echo '*** Testing per-module BUILD_EXCLUSIVE directives'
+############################################################################
+
+echo 'Adding per-module config test module'
+run_with_expected_output dkms add test/dkms_per_module_config_test-1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_per_module_config_test/1.0/source -> 
/usr/src/dkms_per_module_config_test-1.0
+EOF
+check_module_source_tree_created /usr/src/dkms_per_module_config_test-1.0
+run_status_with_expected_output 'dkms_per_module_config_test' << EOF
+dkms_per_module_config_test/1.0: added
+EOF
+
+echo 'Testing per-module config test module build (should be excluded due to 
per-module restrictions)'
+run_with_expected_error 77 dkms build -k "${KERNEL_VER}" -m 
dkms_per_module_config_test -v 1.0 << EOF
+Warning: The 
/var/lib/dkms/dkms_per_module_config_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
+for module dkms_per_module_config_test/1.0 includes BUILD_EXCLUSIVE directives
+which do not match this kernel/arch/config for any modules.
+This indicates that it should not be built.
+EOF
+run_status_with_expected_output 'dkms_per_module_config_test' << EOF
+dkms_per_module_config_test/1.0: added
+EOF
+
+echo 'Removing per-module config test module'
+run_with_expected_output dkms remove --all -m dkms_per_module_config_test -v 
1.0 << EOF
+Deleting module dkms_per_module_config_test/1.0 completely from the DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_per_module_config_test' << EOF
+EOF
+remove_module_source_tree /usr/src/dkms_per_module_config_test-1.0
+
+echo 'Adding per-module kernel version test module'
+run_with_expected_output dkms add test/dkms_per_module_kernel_version_test-1.0 
<< EOF
+Creating symlink /var/lib/dkms/dkms_per_module_kernel_version_test/1.0/source 
-> /usr/src/dkms_per_module_kernel_version_test-1.0
+EOF
+check_module_source_tree_created 
/usr/src/dkms_per_module_kernel_version_test-1.0
+run_status_with_expected_output 'dkms_per_module_kernel_version_test' << EOF
+dkms_per_module_kernel_version_test/1.0: added
+EOF
+
+echo 'Testing per-module kernel version test module build (should be excluded 
due to kernel version restrictions)'
+run_with_expected_error 77 dkms build -k "${KERNEL_VER}" -m 
dkms_per_module_kernel_version_test -v 1.0 << EOF
+Warning: The 
/var/lib/dkms/dkms_per_module_kernel_version_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf
+for module dkms_per_module_kernel_version_test/1.0 includes BUILD_EXCLUSIVE 
directives
+which do not match this kernel/arch/config for any modules.
+This indicates that it should not be built.
+EOF
+run_status_with_expected_output 'dkms_per_module_kernel_version_test' << EOF
+dkms_per_module_kernel_version_test/1.0: added
+EOF
+
+echo 'Removing per-module kernel version test module'
+run_with_expected_output dkms remove --all -m 
dkms_per_module_kernel_version_test -v 1.0 << EOF
+Deleting module dkms_per_module_kernel_version_test/1.0 completely from the 
DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_per_module_kernel_version_test' << EOF
+EOF
+remove_module_source_tree /usr/src/dkms_per_module_kernel_version_test-1.0
+
+echo 'Adding per-module config exclusive test module'
+run_with_expected_output dkms add 
test/dkms_per_module_config_exclusive_test-1.0 << EOF
+Creating symlink 
/var/lib/dkms/dkms_per_module_config_exclusive_test/1.0/source -> 
/usr/src/dkms_per_module_config_exclusive_test-1.0
+EOF
+check_module_source_tree_created 
/usr/src/dkms_per_module_config_exclusive_test-1.0
+run_status_with_expected_output 'dkms_per_module_config_exclusive_test' << EOF
+dkms_per_module_config_exclusive_test/1.0: added
+EOF
+
+echo 'Testing per-module config exclusive test module build (one should be 
built, one not)'
+run_with_expected_output dkms build -k "${KERNEL_VER}" -m 
dkms_per_module_config_exclusive_test -v 1.0 << EOF
+${SIGNING_PROLOGUE}
+Building module(s)... done.
+Signing module 
/var/lib/dkms/dkms_per_module_config_exclusive_test/1.0/build/dkms_per_module_config_exclusive_test_mod1.ko
+EOF
+run_status_with_expected_output 'dkms_per_module_config_exclusive_test' << EOF
+dkms_per_module_config_exclusive_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+EOF
+
+echo 'Removing per-module config exclusive test module'
+run_with_expected_output dkms remove --all -m 
dkms_per_module_config_exclusive_test -v 1.0 << EOF
+
+Deleting module dkms_per_module_config_exclusive_test/1.0 completely from the 
DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_per_module_config_exclusive_test' << EOF
+EOF
+remove_module_source_tree /usr/src/dkms_per_module_config_exclusive_test-1.0
+
 echo 'Checking that the environment is clean again'
 check_no_dkms_test
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_build_exclusive_test-1.0/dkms.conf 
new/dkms-3.3.0/test/dkms_build_exclusive_test-1.0/dkms.conf
--- old/dkms-3.2.1/test/dkms_build_exclusive_test-1.0/dkms.conf 2025-05-12 
09:58:11.000000000 +0200
+++ new/dkms-3.3.0/test/dkms_build_exclusive_test-1.0/dkms.conf 2025-11-03 
11:40:02.000000000 +0100
@@ -1,5 +1,8 @@
 PACKAGE_NAME="dkms_build_exclusive_test"
 PACKAGE_VERSION="1.0"
+BUILT_MODULE_NAME[0]="dkms_build_exclusive_test"
 DEST_MODULE_LOCATION[0]="/updates/dkms"
+BUILT_MODULE_NAME[1]="dkms_build_exclusive_test2"
+DEST_MODULE_LOCATION[1]="/updates/dkms"
 BUILD_EXCLUSIVE_ARCH="none"
 AUTOINSTALL="yes"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_conf_test_sparse_arrays/dkms.conf 
new/dkms-3.3.0/test/dkms_conf_test_sparse_arrays/dkms.conf
--- old/dkms-3.2.1/test/dkms_conf_test_sparse_arrays/dkms.conf  1970-01-01 
01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_conf_test_sparse_arrays/dkms.conf  2025-11-03 
11:40:02.000000000 +0100
@@ -0,0 +1,7 @@
+PACKAGE_NAME="dkms_conf_test"
+PACKAGE_VERSION="1.0"
+BUILT_MODULE_NAME[1]="dkms_sparse_arrays_test_1"
+DEST_MODULE_LOCATION[1]="/kernel/extra"
+BUILT_MODULE_NAME[3]="dkms_sparse_arrays_test_3"
+DEST_MODULE_LOCATION[3]="/kernel/extra"
+DEST_MODULE_LOCATION[4]="/oops"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/Makefile 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/Makefile
--- old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/Makefile      
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/Makefile      
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1 @@
+obj-m += dkms_per_module_config_exclusive_test_mod1.o 
dkms_per_module_config_exclusive_test_mod2.o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms.conf 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms.conf
--- old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms.conf     
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms.conf     
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,15 @@
+PACKAGE_NAME="dkms_per_module_config_exclusive_test"
+PACKAGE_VERSION="1.0"
+
+BUILT_MODULE_NAME[0]="dkms_per_module_config_exclusive_test_mod1"
+BUILT_MODULE_NAME[1]="dkms_per_module_config_exclusive_test_mod2"
+
+DEST_MODULE_LOCATION[0]="/updates/dkms"
+DEST_MODULE_LOCATION[1]="/updates/dkms"
+
+# Requires CONFIG_MODULES to be enabled and CONFIG_NONEXISTENT_CONFIG to be 
absent (should always match):
+BUILD_EXCLUSIVE_CONFIG[0]="CONFIG_MODULES !CONFIG_NONEXISTENT_CONFIG"
+# Requires CONFIG_NONEXISTENT_CONFIG to be enabled and CONFIG_MODULES to be 
absent (should never match):
+BUILD_EXCLUSIVE_CONFIG[1]="!CONFIG_MODULES CONFIG_NONEXISTENT_CONFIG"
+
+AUTOINSTALL="yes"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod1.c
 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod1.c
--- 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod1.c
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod1.c
  2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_config_exclusive_test_mod1_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_exclusive_test_mod1: module 
loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_config_exclusive_test_mod1_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_exclusive_test_mod1: module 
unloaded\n");
+}
+
+module_init(dkms_per_module_config_exclusive_test_mod1_init);
+module_exit(dkms_per_module_config_exclusive_test_mod1_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module config exclusive test module 1");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod2.c
 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod2.c
--- 
old/dkms-3.2.1/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod2.c
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_config_exclusive_test-1.0/dkms_per_module_config_exclusive_test_mod2.c
  2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_config_exclusive_test_mod2_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_exclusive_test_mod2: module 
loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_config_exclusive_test_mod2_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_exclusive_test_mod2: module 
unloaded\n");
+}
+
+module_init(dkms_per_module_config_exclusive_test_mod2_init);
+module_exit(dkms_per_module_config_exclusive_test_mod2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module config exclusive test module 2");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/Makefile 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/Makefile
--- old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/Makefile        
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/Makefile        
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1 @@
+obj-m += dkms_per_module_config_test_mod1.o dkms_per_module_config_test_mod2.o 
dkms_per_module_config_test_mod3.o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms.conf 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms.conf
--- old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms.conf       
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms.conf       
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,18 @@
+PACKAGE_NAME="dkms_per_module_config_test"
+PACKAGE_VERSION="1.0"
+
+BUILT_MODULE_NAME[0]="dkms_per_module_config_test_mod1"
+BUILT_MODULE_NAME[1]="dkms_per_module_config_test_mod2"
+BUILT_MODULE_NAME[2]="dkms_per_module_config_test_mod3"
+
+DEST_MODULE_LOCATION[0]="/updates/dkms"
+DEST_MODULE_LOCATION[1]="/updates/dkms"
+DEST_MODULE_LOCATION[2]="/updates/dkms"
+
+# Build only for kernel starting with 99 (should never match):
+BUILD_EXCLUSIVE_KERNEL[0]="^99\..*"
+# Build for any kernel (should always match) but only for architecture "none" 
(should never match):
+BUILD_EXCLUSIVE_KERNEL[1]=".*"
+BUILD_EXCLUSIVE_ARCH[1]="none"
+
+AUTOINSTALL="yes"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod1.c
 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod1.c
--- 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod1.c
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod1.c
      2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_config_test_mod1_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod1: module loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_config_test_mod1_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod1: module unloaded\n");
+}
+
+module_init(dkms_per_module_config_test_mod1_init);
+module_exit(dkms_per_module_config_test_mod1_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module config test module 1");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod2.c
 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod2.c
--- 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod2.c
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod2.c
      2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_config_test_mod2_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod2: module loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_config_test_mod2_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod2: module unloaded\n");
+}
+
+module_init(dkms_per_module_config_test_mod2_init);
+module_exit(dkms_per_module_config_test_mod2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module config test module 2");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod3.c
 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod3.c
--- 
old/dkms-3.2.1/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod3.c
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_config_test-1.0/dkms_per_module_config_test_mod3.c
      2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_config_test_mod3_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod3: module loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_config_test_mod3_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_config_test_mod3: module unloaded\n");
+}
+
+module_init(dkms_per_module_config_test_mod3_init);
+module_exit(dkms_per_module_config_test_mod3_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module config test module 3");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/Makefile 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/Makefile
--- old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/Makefile        
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/Makefile        
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1 @@
+obj-m += dkms_per_module_kernel_version_test_old.o 
dkms_per_module_kernel_version_test_new.o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms.conf 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms.conf
--- old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms.conf       
1970-01-01 01:00:00.000000000 +0100
+++ new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms.conf       
2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,15 @@
+PACKAGE_NAME="dkms_per_module_kernel_version_test"
+PACKAGE_VERSION="1.0"
+
+BUILT_MODULE_NAME[0]="dkms_per_module_kernel_version_test_old"
+BUILT_MODULE_NAME[1]="dkms_per_module_kernel_version_test_new"
+
+DEST_MODULE_LOCATION[0]="/updates/dkms"
+DEST_MODULE_LOCATION[1]="/updates/dkms"
+
+# Build only for kernels < 4.0 (should never match):
+BUILD_EXCLUSIVE_KERNEL_MAX[0]="3.99"
+# Build only for kernels >= 5.0 (should always match):
+BUILD_EXCLUSIVE_KERNEL_MIN[1]="5.0"
+
+AUTOINSTALL="yes"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_new.c
 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_new.c
--- 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_new.c
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_new.c
       2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_kernel_version_test_new_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_kernel_version_test_new: module 
loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_kernel_version_test_new_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_kernel_version_test_new: module 
unloaded\n");
+}
+
+module_init(dkms_per_module_kernel_version_test_new_init);
+module_exit(dkms_per_module_kernel_version_test_new_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module kernel version test - new kernel module");
+MODULE_VERSION("1.0");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_old.c
 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_old.c
--- 
old/dkms-3.2.1/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_old.c
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/dkms-3.3.0/test/dkms_per_module_kernel_version_test-1.0/dkms_per_module_kernel_version_test_old.c
       2025-11-03 11:40:02.000000000 +0100
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+static int __init dkms_per_module_kernel_version_test_old_init(void)
+{
+    printk(KERN_INFO "dkms_per_module_kernel_version_test_old: module 
loaded\n");
+    return 0;
+}
+
+static void __exit dkms_per_module_kernel_version_test_old_exit(void)
+{
+    printk(KERN_INFO "dkms_per_module_kernel_version_test_old: module 
unloaded\n");
+}
+
+module_init(dkms_per_module_kernel_version_test_old_init);
+module_exit(dkms_per_module_kernel_version_test_old_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("DKMS per-module kernel version test - old kernel module");
+MODULE_VERSION("1.0");

Reply via email to