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 – VCS – Web – Wine – 字體
本文檔涵蓋了為 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 平台支持)。
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 環境構建時受用戶配置影響。
檢查
大多數 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。