DKMS package guidelines

Arch package guidelines
32-bit
–
CLR
–
CMake
–
Cross
–
DKMS
–
Eclipse
–
Electron
–
Font
–
Free Pascal
–
GNOME
–
Go
–
Haskell
–
Java
–
KDE
–
Kernel modules
–
Lisp
–
Meson
–
MinGW
–
Node.js
–
Nonfree
–
OCaml
–
Perl
–
PHP
–
Python
–
R
–
Ruby
–
Rust
-
Security
–
Shell
–
VCS
–
Web
–
Wine
Here are some guidelines to follow when creating a
DKMS
package.
Package name
DKMS packages are named by appending "
-dkms
" to the original package name.
The variable
$_pkgname
is often used below
$pkgname
to describe the package name minus the "
-dkms
" suffix (e.g.
_pkgname="${pkgname%-*}"
)
Dependencies
Add
dkms
to
depends
array. This is important because this will provide tools and hooks that will rebuild the kernel driver provided by the
-dkms
package whenever the kernel is updated.
Do not include
linux-headers
– or any other Linux header package – to the PKGBUILD. These headers are already listed as optional dependencies of
dkms
and each kernel package has its own header package, so including header package dependency in the
-dkms
package is both unnecessarily redundant and restricting.
Source location
The package should install the kernel module's source files into:
/usr/src/
PACKAGE_NAME
-
PACKAGE_VERSION
where
PACKAGE_NAME
and
PACKAGE_VERSION
are the kernel module's name and version.
It is highly recommended to set
PACKAGE_NAME
with the value of
$_pkgname
(See
#Package name
), and
PACKAGE_VERSION
with
$pkgver
.
Note
There is no need to build the kernel module's sources file nor install them; this is done automatically whenever the Linux kernel is updated thanks to a
pacman hook
in
dkms
.
Patching
The sources can be patched either directly in the PKGBUILD or through
dkms.conf
.
If patching through
dkms.conf
, make sure to install the patches into
/usr/src/
PACKAGE_NAME
-
PACKAGE_VERSION
/patches/
directory and to add a
PATCH[
number
]=
patch_filename
for each patch to be applied, replacing
number
with a incremental value starting at
0
. See
dkms(8) § DKMS.CONF
for more information.
Module loading automatically in .install
Do
not
use .install file to load or unload modules. Leave it to the user, since there is a possibility a module may crash when loaded.
Also do
not
call
dkms
as it is automatically done via
pacman hook
provided by
dkms
. This hook runs
dkms install
and
dkms remove
leaving no manual task for the package maintainer.
Note
dkms install
is making sure
depmod
is called at the end of its process.
dkms install
depends on
dkms build
(to build the source against the current kernel), which itself depends on
dkms add
(to add a symlink from
/var/lib/dkms/
PACKAGE_NAME
/
PACKAGE_VERSION
/source
to
/usr/src/
PACKAGE_NAME
-
PACKAGE_VERSION
).
Example
Here is an example package that edits
dkms.conf
according to the package name and version, and install module blacklist configuration file.
For other example of (real) packages, search
-dkms in official repositories
and
-dkms in AUR
.
PKGBUILD
PKGBUILD
# Maintainer: foo <foo(at)example(dot)org>
# Contributor: bar <bar(at)example(dot)org>

_pkgbase=example
pkgname=example-dkms
pkgver=1
pkgrel=1
pkgdesc="The Example kernel modules (DKMS)"
arch=('x86_64')
url="https://www.example.org/"
license=('GPL2')
depends=('dkms')
conflicts=("${_pkgbase}")
install=${pkgname}.install
source=("${url}/files/tarball.tar.gz"
        'dkms.conf'
        "${pkgname}.conf"
        'linux-3.14.patch')
md5sums=(
use 'updpkgsums'
)

prepare() {
  cd ${_pkgbase}-${pkgver}

  # Patch
  patch -p1 -i "${srcdir}"/linux-3.14.patch
}

package() {
  # Copy dkms.conf
  install -Dm644 dkms.conf "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf

  # Set name and version
  sed -e "s/@_PKGBASE@/${_pkgbase}/" \
      -e "s/@PKGVER@/${pkgver}/" \
      -i "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf

  # Copy sources (including Makefile)
  cp -r ${_pkgbase}/* "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/

  # Blacklists conflicting module
  install -Dm644 ${pkgname}.conf "${pkgdir}/usr/lib/modprobe.d/${pkgname}.conf"
}
dkms.conf
dkms.conf
PACKAGE_NAME="@_PKGBASE@"
PACKAGE_VERSION="@PKGVER@"
MAKE[0]="make --uname_r=$kernelver"
BUILT_MODULE_NAME[0]="@_PKGBASE@"
DEST_MODULE_LOCATION[0]="/kernel/drivers/misc"
AUTOINSTALL="yes"
.install
This example shows a message on post-install and post-upgrade that suggests unloading a conflicting module (
example-conflicting-module
) and then loading this package's module (
example
) for immediate use, when the user do not want to reboot the system at this moment.
example.install
post_install() {
  cat<<EOF

Unload and load kernel modules:

  rmmod example-conflicting-module
  modprobe example

EOF
}

post_upgrade() {
  post_install
}
Module blacklist conf
When it is known that
example-conflicting-module
conflicts with this package's
example
module, it should be blacklisted:
example-dkms.conf
blacklist example-conflicting-module