跳至內容
出自 Arch Linux 中文维基


Arch 打包準則

32 位CLRCMakeDKMSEclipseElectronFree PascalGNOMEGoHaskellJava交叉編譯工具KDELispMesonMinGW內核模塊Node.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine字體

本文檔涵蓋了為 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 進行編譯。目前 cargorustc 都由 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#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 確保使用發布模式編譯 (默認使用調試模式編譯)
  • --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