Home

Awesome

cargo-generate-rpm

Cargo helper command to generate a binary RPM package (.rpm) from Cargo project.

This command does not depend on rpmbuild and generates an RPM package file without a spec file by using the rpm crate.

Rust cargo-generate-rpm at crates.io

Legacy systems requiring RPMv3 (e.g. CentOS 7) are no longer supported due to rpm-rs compatibility. Use versions prior to 0.15 for such a system.

Install

cargo install cargo-generate-rpm

Usage

cargo build --release
strip -s target/release/XXX
cargo generate-rpm

Upon run cargo generate-rpm on your cargo project, a binary RPM package file will be created in target/generate-rpm/XXX.rpm. You can change the RPM package file location using -o option.

In advance, run cargo build --release and strip the debug symbols (strip -s target/release/XXX), because these are not run upon cargo generate-rpm as of now.

Configuration

This command generates RPM metadata from the Cargo.toml file:

[package.metadata.generate-rpm] options

Adding assets such as the binary file, .desktop file, or icons, shall be written in the following way.

[package.metadata.generate-rpm]
assets = [
    { source = "target/release/XXX", dest = "/usr/bin/XXX", mode = "755" },
    { source = "<path_relative_to_project_root>/XXX.desktop", dest = "/usr/share/applications/XXX.desktop", mode = "644" },
    { source = "<path_relative_to_project_root>/*/apps/XXX.png", dest = "/usr/share/icons/hicolor/", mode = "644" },
]

[package.metadata.generate-rpm.{requires,obsoletes,conflicts,provides,recommends,supplements,suggests,enhances}] options

Dependencies such as "requires", "obsoletes", "conflicts" and "provides" and weak dependencies such as "recommends", "supplements", "suggests", and "enhances" shall be written in similar way as dependencies in Cargo.toml.

[package.metadata.generate-rpm.requires]
alternative = "*"
filesystem = ">= 3"

This example states that the package requires with any versions of alternative and all versions of filesystem 3.0 or higher.

Following table lists the version comparisons:

ComparisonMeaning
package = "*"A package at any version number
package = "< version"A package with a version number less than version
package = "<= version"A package with a version number less than or equal to version
package = "= version"A package with a version number equal to version
package = "> version"A package with a version number greater than version
package = ">= version"A package with a version number greater than or equal to version

It is necessary to place a space between version and symbols such as <, <=, etc... package = "version" is not accepted, instead use package = "= version".

This command automatically determines what shared libraries a package requires. There may be times when the automatic dependency processing is not desired. The packege author and users can configure the processing.

/bin/sh is always added to the package requirements. To disable it, set package.metadata.generate-rpm.require-sh to false. You should not do this if you use scripts such as pre_install_script or if your assets contain shell scripts.

Overwrite configuration

[package.metadata.generate-rpm] can be overwritten. The following command line options are used:

These options may be specified multiple times, with the last one written being applied regardless of the kind of option. For example, the arguments -s 'release = "alpha"' --metadata-overwrite=beta.toml where beta.toml contains release = "beta", then gives release = "beta".

Advanced Usage

Workspace

To generate an RPM package from a member of a workspace, execute cargo generate-rpm in the workspace directory with specifying the package (directory path) with option -p:

cargo build --release
strip -s target/release/XXX
cargo generate-rpm -p XXX

[package.metadata.generate-rpm] options should be written in XXX/Cargo.toml.

When the option -p specified, first, the asset file source shall be treated as a relative path from the current directory. If not found, it shall be treated as a relative path from the directory of the package. If both not found, cargo generate-rpm shall fail with an error.

For example, source = target/bin/XXX would usually be treated as a relative path from the current directory. Because all packages in the workspace share a common output directory that is located target in workspace directory.

Cross compilation

This command supports --target-dir, --target, and --profile options like cargo build. Depending on these options, this command changes the RPM package file location and replaces target/release/ of the source locations of the assets.

cargo build --release --target x86_64-unknown-linux-gnu
cargo generate-rpm --target x86_64-unknown-linux-gnu

When --target-dir TARGET-DIR and --target x86_64-unknown-linux-gnu are specified, a binary RPM file will be created at TARGET-DIR/x86_64-unknown-linux-gnu/generate-rpm/XXX.rpm instead of target/generate-rpm/XXX.rpm. In this case, the source of the asset { source = "target/release/XXX", dest = "/usr/bin/XXX" } will be treated as TARGET-DIR/x86_64-unknown-linux-gnu/release/XXX instead of target/release/XXX.

You can use CARGO_BUILD_TARGET environment variable instead of --target option and CARGO_BUILD_TARGET_DIR or CARGO_TARGET_DIR instead of --target-dir.

Similarly, if using a custom build profile with, for example, --profile custom the source of the asset { source = "target/release/XXX" } will be treated as target/custom/XXX.

Payload compress type

The default payload compress type of the generated RPM file is zstd. You can specify the payload compress type with --payload-compress TYPE: none, gzip, or zstd.

Scriptlet Flags and Prog Settings

Scriptlet settings can be configured via *_script_flags and *_script_prog settings.

Scriptlet Flags

FlagSetting ValueDescriptionExample Usage
RPMSCRIPT_FLAG_EXPAND1Enables macro expansionpre_install_script_flags = 0b001
RPMSCRIPT_FLAG_QFORMAT2Enables header query format expansionpre_install_script_flags = 0b010
RPMSCRIPT_FLAG_CRITICAL4Enables critical severity for scriplet success or failurepre_install_script_flags = 0b100

Example

pre_install_script = """
echo preinstall
"""
pre_install_script_flags = 0b011 # Enables EXPAND and QFORMAT flags
pre_install_script_prog = ["/bin/blah/bash", "-c"] # Sets the interpreter/argument settings for the scriptlet