DKMS 软件包打包准则

来自 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