Rust package guidelines

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Arch package guidelines

32-bitCLRCMakeCrossDKMSEclipseElectronFontFree PascalGNOMEGoHaskellJavaKDEKernelLispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

This document covers standards and guidelines on writing PKGBUILDs for Rust.

General guidelines

Package naming

For Rust binaries use only the program name.

Note: The package name should be entirely lowercase.

Source

Rust#Cargo provides a stable naming scheme for download URLs. PKGBUILD#source source=() array can use the following template:

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

Building

Building a Rust package.

 build() {
   RUSTUP_TOOLCHAIN=stable cargo build --release --locked --all-features --target-dir=target
 }

where:

  • --release tells cargo to compile a release build
  • --locked tells cargo to adhere the Cargo.lock file and prevent it from updating dependencies which is important for reproducible builds.
  • --all-features tells cargo to compile with all features of the package enabled. Alternatively, use --features FEATURE1,FEATURE2 if you want enable only selected features.
  • --target-dir=target tells cargo to put the target directory in the current directory. It can also be specified via CARGO_TARGET_DIR environment variable.

Check

Most Rust projects provide a simple way to run the testsuite.

 check() {
   RUSTUP_TOOLCHAIN=stable cargo test --locked --target-dir=target
 }

Consider avoiding --release flag for running tests, otherwise the binary will be recompiled using bench profile, replacing the one produced in build() stage. Alternatively, keep --release flag and use a different value for --target-dir, however keep in mind that release mode also enables compiler optimizations and disables some features like integer overflow checks and debug_assert!() macro, so in theory you could end up catching less problems. Both approaches will compile the dependencies again, slightly increasing total build time.

Package

Rust builds binaries in target/release and can simply be installed to /usr/bin.

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

If a package has more than one executables in /usr/bin you can use find command:

 package() {
   find target/release \
     -maxdepth 1 \
     -executable \
     -type f \
     -exec install -m 755 "{}" "$pkgdir"/usr/bin \;
 }

Notes about using cargo install

Some packages should install more files such as a man page, so in that case it would be better to use cargo, in this case build() is unnecessary because cargo install forces rebuilding even if the package already has been built by using cargo build.:

 build() {
   return 0
 }

 package() {
   cd "$pkgname-$pkgver"
   cargo install --no-track --locked --all-features --root "$pkgdir/usr/" --path .
 }

The --no-track argument should always be used, because cargo install may create unwanted files such as /usr/.crates.toml or /usr/.crates2.json unless it is specified.

Example packages

Click Package Actions > Source Files in the package page to see its example PKGBUILD.