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

跳转到内容

# Rust 软件打包准则

来自 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 – 字体

翻译状态：

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

本文档涵盖了为 Rust 软件编写 PKGBUILD 的标准和指南。

## 软件包命名

打包 Rust 项目时，软件包的名称应基本与生成的二进制文件名一致。请注意，打包库单元包 (library crate) 没有任何意义，只有带二进制文件的单元包 (crate) 才需要打包。对于生成多个二进制文件的包，通常使用上游单元包 (crate) 的名称较为合适。在任何情况下软件包的名称都应该小写。

## 源码

大多数 Rust 项目可以从 tarball、源归档文件（例如 GitHub Release 上的源链接）或其他已发布的源构建。另外，许多项目发布在 crates.io 上，该网站给 cargo 提供了稳定的 URL 下载方案。如果需要，PKGBUILD#source 可使用以下模板：

    source=("$pkgname-$pkgver.tar.gz::https://static.crates.io/crates/$pkgname/$pkgname-$pkgver.crate")

## 依赖关系

虽然有些 Rust 项目有外部依赖，但大多数项目只使用在最终二进制文件中静态链接的 Rust 生态系统库。因此，大多数项目不需要指定很多 `depends` (依赖)，只需要 `makedepends` (构建依赖)。绝大多数 Rust 项目都使用 cargo 依赖管理器构建，它会协调下载库以满足编译时的依赖关系，并执行所有必要的调用，使用真正的 Rust 编译器 `rustc` 进行编译。目前 cargo 和 rustc 都由 rust包 提供，但也有其他方法可同时获取或单独获取这两个包，包括 rustup包。因此，大多数 PKGBUILD 都会调用 cargo 工具，应该直接依赖它。

    makedepends=(cargo)

如果项目需要使用开发版 Rust 工具链，请使用：

    makedepends=(cargo-nightly)

## 准备工作

Rust 依赖管理器 cargo 能提前下载构建项目所需的所有库。在 `prepare()` 阶段进行下载，能使后续的 `build()` 和其他阶段完全离线运行。

    prepare() {
        export RUSTUP_TOOLCHAIN=stable
        cargo fetch --locked --target "$CARCH-unknown-linux-gnu"
    }

其中：

- `RUSTUP_TOOLCHAIN=stable` 确保默认工具链被设置为稳定版，以防用户改变默认值。当然，如果在上游项目有特殊要求，则应被设置为开发版。此操作可避免在未使用 chroot 环境构建时受用户配置影响。另外，如果上游项目的源代码中有 `rust-toolchain` 文件或 `rust-toolchain.toml` 文件可实现此目的，则无需此步骤。

- `--locked` 确保严格遵守 `Cargo.lock` 文件中指定的版本，防止其更新依赖关系。这对可重现构建很重要。

- `--target "$CARCH-unknown-linux-gnu"` 确保只获取正在构建的特定目标平台所需的依赖项，从而减少下载量（参见 PKGBUILD#arch 和 Rust 平台支持）。

注意：在为上游源项目构建 VCS 软件包时，如果该项目在发布周期之间未保持 `Cargo.lock` 文件与 `Cargo.toml` 同步，请在运行 `cargo fetch` 之前添加 `cargo update` 。尽管结果并非完全可重现，但有关构建的其他所有方面都应符合上述内容，因为依赖关系将在构建时得到解决。

## 构建

构建 Rust 软件包。

    build() {
        export RUSTUP_TOOLCHAIN=stable
        export CARGO_TARGET_DIR=target
        cargo build --frozen --release --all-features
    }

其中：

- `--release` 确保使用发布模式编译 (默认使用调试模式编译)
- `--frozen` 确保 cargo 保持离线状态，只使用 `Cargo.lock` 文件中指定的版本和 `prepare()` 阶段缓存的版本。这在功能上与 `--locked --offline` 一致。这对可重现构建很重要。
- `--all-features` 确保编译时启用软件包的所有特性。另外，如果只需启用指定特性，可使用 `--features FEATURE1, FEATURE2` 。
- `CARGO_TARGET_DIR=target` 指定输出路径为当前目录下的 target 目录，以防未使用 chroot 环境构建时受用户配置影响。

注意：对于 Arch 仓库的软件包来说不需要这两个环境变量，因为 Arch 仓库的软件包总是在 chroot 环境下使用默认设置下构建。但为了方便 AUR 用户，此处仍提到了上述环境变量，因为 AUR 用户可能没有意识到改变用户默认设置和在构建软件包时不使用 chroot 的后果。

## 检查

大多数 Rust 项目提供了运行测试的简单方法。

    check() {
        export RUSTUP_TOOLCHAIN=stable
        cargo test --frozen --all-features
    }

还应该检查仓库是否是 cargo 工作空间。只需打开 `/Cargo.toml`，检查是否包含 `[workspace]` 部分。如果包含 `[workspace]`，则应当在 `cargo test` 后添加 `--workspace`，以确保所有工作区成员的测试都能运行。

运行测试时应避免使用 `--release` 标志，否则二进制文件将会使用 bench 参数重新编译，并覆盖 `build()` 生成的文件。或者也可以保留 `--release` 标志，但使用不同的 `CARGO_TARGET_DIR`。但需要注意的是，使用发布模式也会启用编译器优化，并禁用一些功能，如整数溢出检查和 `debug_assert!()` 宏，所以理论上可能最终问题会更少。这两种方法都会重新编译依赖项，从而使总编译时间略微增加。

## 打包

Rust 在 `target/release` 目录内构建二进制文件，将二进制文件安装到 `/usr/bin` 很容易。

    package() {
        install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/$pkgname"
    }

如果一个软件包在 `/usr/bin` 内有多个可执行文件，可使用 find 命令：

    package() {
        find target/release \
            -maxdepth 1 \
            -executable \
            -type f \
            -exec install -Dm0755 -t "$pkgdir/usr/bin/" {} +
    }

### 使用 cargo install 的注意事项

有些软件包需要安装更多的文件，如手册页面或其他必要的文件。如果没有其他方式来安装这些文件，可使用 `cargo install`。在这种情况下不必使用 `build()`，因为即使该软件包已通过 `cargo build` 构建，`cargo install` 仍会强制重新构建。但仍然可使用 `prepare()` 提前获取源代码：

    package() {
        cd "$pkgname-$pkgver"
        export RUSTUP_TOOLCHAIN=stable
        cargo install --no-track --frozen --all-features --root "$pkgdir/usr/" --path .
    }

应始终使用 `--no-track` 参数，否则 `cargo install` 将创建不必要的文件，如 `/usr/.crates.toml` 或 `/usr/.crates2.json`。

## 软件包示例

PKGBUILD 样例请参阅软件包页面上的 Package Actions > Source Files。

- cbindgen包
- ripgrep包

分类：​

- 调用重复模板参数的页面
- Arch 打包准则

Rust 软件打包准则
添加话题