DKMS 软件包打包准则 - Arch Linux 中文维基

跳转到内容

# DKMS 软件包打包准则

来自 Arch Linux 中文维基
Arch 打包准则

32 位 – 安全 – CLR – CMake – DKMS – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – 交叉编译工具 – KDE – Lisp – Meson – MinGW – 内核模块 – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – Shell – VCS – Web – Wine – 字体

翻译状态：

- 本文（或部分内容）译自 DKMS package guidelines，最近一次同步于 2024-06-01，若英文版本有所更改，则您可以帮助同步与翻译更改的内容。
- 您可以在 ArchWiki 的对应页面找到本文翻译的原始修订历史。
- 本文可能与英文原文存在出入。

创建一个新的 DKMS 包时，可以参考下面的指导方针。

## 包名

DKMS 包的命名方式是：原始包名加"-dkms"后缀。

通常在 `$pkgname` 后面使用 `$_pkgname` 记录不包含 "-dkms" 后缀的软件包名 (例如 `_pkgname=${pkgname%-*}`). 这样可以在原始的软件包 PKGBUILD 和 DKMS 编译文件之间保持相似性。

## 依赖

依赖的包应该是原来软件包的基础上，加上 dkms包。这一点很重要，因为它将提供工具和 Hook 文件，在内核更新时重建由 -dkms 软件包提供的内核驱动程序。

不要在 PKGBUILD 包含 linux-headers包 或任何其他的Linux头文件包。这些头文件已经作为 dkms包 的可选依赖，同时每个内核包都有自己的头文件包，因此在 -dkms 软件包包含这些头文件包是不必要的重复和限制的。

## 源代码构建位置

构建模块所需源代码需要放在（这是DKMS构建模块时使用的默认目录）：

    /usr/src/PACKAGE_NAME-PACKAGE_VERSION

在软件包目录，要包含一个 `dkms.conf` 配置文件，告诉 DKMS 如何编译。这个配置文件需要包含：

- `PACKAGE_NAME` - 实际的项目名称，通常使用 `$_pkgname` （见#包名）或 `$_pkgbase`.
- `PACKAGE_VERSION` - 通常使用 `$pkgver`.

注意：不需要编译内核模块的源文件，也不需要安装它们；由于 dkms包 中的 pacman#钩子，每当 Linux 内核更新时，这些工作都会自动完成。

## 打补丁

为内核模块源代码打补丁既可以直接在 PKGBUILD 中进行，也可以通过`dkms.conf`来进行。

若通过 `dkms.conf` 打补丁，请确保将补丁安装在 `/usr/src/PACKAGE_NAME-PACKAGE_VERSION/patches/` 目录下，并为每个补丁添加 `PATCH[number]=patch_filename` 条目，记得将 `number` 替换为以0起始的数字。查阅 dkms(8) § DKMS.CONF 以获取相关信息

## .install 中模块的自动加载

模块的加载和卸载必须由用户自己来执行，设想一下，某个模块可能在加载的时候崩溃。

另外，不要在 .install 中调用 dkms ，该操作会由 dkms包 提供的 Pacman 钩子 自动完成。Pacman 会自动执行 `dkms install` 和 `dkms remove` 钩子。

`dkms install` 会确保过程结束时执行 `depmod`。`dkms 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

该示例会在安装或升级后显示一条信息，建议用户在不想立即重启系统时，卸载冲突模块（`example-conflicting-module`）并加载该包提供的模块（`example`）。

    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

已知模块 `example-conflicting-module` 会与模块 `example` 冲突时，应将其加入模块黑名单：

    example-dkms.conf

    blacklist example-conflicting-module

分类：​

- Arch 打包准则

DKMS 软件包打包准则
添加话题