32 位 – CLR – CMake – Cross – DKMS – Eclipse – Electron – Font – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel – 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。