跳转至内容

Rust 包指南

来自 ArchWiki
Arch 软件包指南

32位CLRCMake交叉编译DKMSEclipse 插件Electron字体Free PascalGNOMEGoHaskellJavaKDE内核模块LispMesonMinGWNode.js非免费OCamlPerlPHPPythonRRubyRust - 安全ShellVCSWeb 应用Wine

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

包命名

在打包 Rust 项目时,包名几乎总是应该与生成的二进制文件名相同。请注意,打包库 crate 没有意义,因此只打包带有 bin 的 crate。对于生成多个二进制文件的 crate,上游 crate 名称通常是合适的。无论如何,包名应该全部小写。

Source(生效配置)

大多数 Rust 项目可以从 tarball、源档案(例如 GitHub releases 上的源链接)或任何其他已发布的源进行构建。

当其他源不可用时,大多数 Rust 项目发布在 crates.io 上,它提供了一个稳定的下载 URL 方案供 cargo 使用。这种源的缺点是它通常不包含所有测试文件、许可证文件或其他通常存在于其他源中的资源。如果需要,PKGBUILD#source 可以使用以下模板

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

依赖

虽然一些 Rust 项目有外部依赖,但大多数项目只使用 Rust 生态系统库,这些库是静态嵌入在最终二进制文件中的。因此,大多数项目不需要指定很多 depends。大多数 Rust 二进制文件通常会链接 glibc 库,因此 gcc-libsglibc 通常是大多数 Rust 包的依赖项。如果构建过程查找并链接任何系统库,可能会有更多依赖项。

对于 makedepends,绝大多数 Rust 项目都被设计为使用 cargo 依赖管理器进行构建,该管理器协调下载库以满足构建时依赖项,并进行所有必要的 rustc(实际的 Rust 编译器)调用。目前 cargorustc 都由 rust 包提供,但也有其他方法可以同时或分别获取这两个包,包括 rustup 包。因此,大多数 PKGBUILD 将调用的工具是 cargo,你应该直接依赖它。

makedepends=(cargo)

如果项目需要使用 Rust 工具链的 nightly 版本,请使用

makedepends=(cargo-nightly)

准备

Rust 依赖管理器 cargo 能够提前下载构建项目所需的所有库。在 prepare() 阶段运行此获取操作,可以使后续的 build() 和其他阶段完全离线运行。

prepare() {
    export RUSTUP_TOOLCHAIN=stable
    cargo fetch --locked --target $(rustc --print host-tuple)
}

其中

  • RUSTUP_TOOLCHAIN=stable 确保默认工具链设置为 stable,以防用户更改了他们的默认设置。当然,如果上游项目需要,应该将其设置为 nightly。这可以避免在非 chroot 环境中构建时用户偏好设置带来的常见副作用。另请注意,如果上游项目在其源中有一个 rust-toolchain 文件或 rust-toolchain.toml 文件来实现此目的,则 不需要 设置此环境变量。
  • --locked 告诉 cargo 严格遵守 Cargo.lock 文件中指定的版本,并阻止其更新依赖项。这对于 可复现构建 很重要。
  • --target $(rustc --print host-tuple) 告诉 cargo 只获取构建指定目标平台所需的依赖项,从而减少下载量(请参阅 PKGBUILD#archRust 平台支持)。
注意 如果为上游源项目构建 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 告诉 cargo 编译一个发布版本(默认是调试版本)
  • --frozen 告诉 cargo 保持离线状态,并且只使用 Cargo.lock 文件中指定的版本以及在 prepare() 阶段的 fetch 操作缓存的版本。这在功能上等同于 --locked --offline,也可以使用。这对于 可复现构建 很重要。
  • --all-features 告诉 cargo 启用包的所有功能进行编译。或者,如果你只想启用选定的功能,可以使用 --features FEATURE1,FEATURE2
  • CARGO_TARGET_DIR=target 告诉 cargo 将输出放在当前目录的相对路径 target 中。这可以避免在非 chroot 环境中构建时用户偏好设置带来的常见副作用。
注意 Arch 仓库包不需要这两个环境变量,因为它们 总是 在具有默认设置的 chroot 环境中构建。此处包含它们是为了方便 AUR 用户,他们可能没有意识到更改用户默认设置和在构建包时不使用 chroot 的后果。

检查

大多数 Rust 项目提供了一种简单的方式来运行测试套件。

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

你也应该检查仓库是否是 cargo workspace。只需打开 /Cargo.toml 文件,看看它是否包含 [workspace] 部分。如果是,你应该在 cargo test 中添加 --workspace 标志,以确保也运行了 workspace 成员的所有测试。

注意 避免在使用 --release 标志运行测试,因为它会启用编译器优化并禁用某些功能,如整数溢出检查和 debug_assert!() 宏,所以理论上你 可能 会捕获到更少的问题。由于正在测试的最终二进制工件与我们打包的工件不同,并且我们没有测试构建工具链,因此对于大多数 Rust 项目,在发布模式下测试没有什么好处。

软件包 (Package)

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 的注意事项

一些包应该安装更多文件,例如 man 页或其他资源。如果这样的包没有其他安装这些文件的方式,可以使用 cargo install。在这种情况下,build() 是不必要的,因为 cargo install 会强制重新构建,即使包已经被 cargo build 构建过。prepare() 阶段仍然可以用来提前获取源文件。

package() {
    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 模板

# Maintainer: Firstname Lastname <email@example.org>

pkgname=
pkgver=
pkgrel=1
pkgdesc=''
url=''
license=()
makedepends=('cargo')
depends=()
arch=('i686' 'x86_64' 'armv6h' 'armv7h')
source=()
b2sums=()

prepare() {
    export RUSTUP_TOOLCHAIN=stable
    cargo fetch --locked --target "$(rustc --print host-tuple)"
}

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

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

package() {
    install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/$pkgname"
    # for custom license, e.g. MIT
    # install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}

示例包

在包页面上点击 Package Actions > Source Files 查看其示例 PKGBUILD。

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.