出自 Arch Linux 中文维基
Arch 打包準則

32 位CLRCMakeCrossDKMSEclipseElectronFontFree PascalGNOMEGoHaskellJavaKDE內核模塊LispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

創建一個新的 DKMS 包時,可以參考下面的指導方針。

包名

DKMS 包的命名方式是:原始包名加"-dkms"後綴。

通常在 $pkgname 後面使用 $_pkgname 記錄不包含 "-dkms" 後綴的軟體包名 (例如 _pkgname=${pkgname%-*}). 這樣可以在原始的軟體包 PKGBUILD 和 DKMS 編譯文件之間保持相似性。

依賴

依賴的包應該是原來軟體包的基礎上,加上 dkms。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.

不要包含 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。

原始碼構建位置

構建模塊所需原始碼需要放在(這是DKMS構建模塊時使用的默認目錄):

/usr/src/PACKAGE_NAME-PACKAGE_VERSION

在軟體包目錄,要包含一個 dkms.conf 配置文件,告訴 DKMS 如何編譯。這個配置文件需要包含:

  • PACKAGE_NAME - 實際的項目名稱,通常使用 $_pkgname$_pkgbase.
  • PACKAGE_VERSION - 通常使用 $pkgver.
注意: 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.

打補丁

為內核模塊原始碼打補丁既可以直接在 PKGBUILD 中進行,也可以通過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.

.install 中模塊的自動加載

模塊的加載和卸載必須由用戶自己來執行,設想一下,某個模塊可能在加載的時候崩潰。

Also do not call dkms as it is automatically done via pacman hook provided by dkms. Pacman 會自動執行 dkms installdkms remove 鉤子。

dkms install 會確保過程結束時執行 depmoddkms install 依賴 dkms build (針對當前內核編譯源碼),build 依賴 dkms add (添加從 /var/lib/dkms/<package>/<version>/source/usr/src/<package> 的連結)。

例子

這兒有個根據包名字和版本來對dkms.conf進行編輯,並安裝模塊黑名單配置文件的例子。

其它示例請參考 官方軟體倉庫中的 -dkms 軟體包AUR 中的 -dkms 包

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 "${srcdir}/usr/lib/modprobe.d/${pkgname}.conf"
}

dkms.conf

dkms.conf
PACKAGE_NAME="@_PKGBASE@"
PACKAGE_VERSION="@PKGVER@"
MAKE[0]="make --uname_r=$kernelver"
CLEAN="make clean"
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