7 releases
Uses new Rust 2024
| 0.2.5 | Sep 18, 2025 |
|---|---|
| 0.2.4 | Sep 15, 2025 |
| 0.1.0 | Sep 9, 2025 |
#554 in Command line utilities
333 downloads per month
50KB
830 lines
cargo-revolve: The Power of RPM, the Convenience of Cargo
cargo-revolve is a Cargo subcommand for building RPM packages from Rust projects. It follows the robust "pre-compiled artifact" model, acting as an intelligent orchestrator for the native rpmbuild toolchain. It embraces the full power of the .spec file format while providing seamless integration with your Cargo.toml.
This tool is the spiritual successor to the original cargo-rpm, modernized for today's Rust development. It is for developers and packagers who need to create production-ready, distributable RPMs without requiring the target build environment to have a Rust toolchain installed.
The cargo-revolve Philosophy
cargo-revolve believes in a clear separation of concerns:
cargocompiles your code. It's the best tool for building Rust binaries.cargo-revolvepackages the results. It gathers your compiled binaries and other assets into a source tarball.rpmbuildbuilds the RPM. It takes the tarball of pre-compiled artifacts and uses your.specfile to create the final package.
This workflow is fast, reliable, and does not require rustc or cargo on your RPM build servers, making it ideal for corporate environments and simplified CI/CD pipelines.
How It Compares to Other Solutions
| Tool | Philosophy | Best For | cargo-revolve Advantage |
|---|---|---|---|
cargo-generate-rpm |
Declarative (Cargo.toml is everything) |
Simple projects, CI environments without rpmbuild. |
Full Power & Control. cargo-revolve doesn't hide the .spec file, giving you access to 100% of RPM's features like complex scriptlets, triggers, and custom macros. You are never limited by the tool's TOML schema. |
| "Spec-driven Build" (e.g., Fedora Packaging) | Let rpmbuild compile the code |
Official distribution packaging. | Simplicity & Portability. cargo-revolve's pre-compiled model means your build servers don't need a Rust toolchain. You ship binaries, not source, which is simpler and often required for proprietary applications. |
cargo-dist |
Full Release Orchestration | Multi-platform releases (RPM, DEB, MSI) automated in CI. | Focus & Depth. cargo-dist is a powerful release framework. cargo-revolve is a focused tool that does one thing exceptionally well: building robust, production-grade RPMs. |
In short, cargo-revolve gives you the expressiveness of a raw .spec file with a workflow optimized for distributing compiled Rust applications.
Features
- Pre-compiled Artifact Workflow: Compiles your code locally first, then packages the results for
rpmbuild. .specFile Templating: Uses the powerful Tera template engine to inject metadata from yourCargo.tomldirectly into your.specfile.- Automatic Directory Expansion: Intelligently include the contents of entire directories by adding a trailing slash to the
sourcepath in yourassetslist (e.g.,"config/").cargo-revolvewill recursively find all files and map them to the correct destinations in the final RPM. - Automatic Directory Ownership: The tool automatically discovers all directories required by your assets and generates the necessary
%dirdirectives in the spec file, ensuring correct ownership. - Safe System Directories: For assets installed into shared system directories (e.g.,
/usr/lib/systemd/system), you can use themkdir = falseflag to prevent the package from dangerously taking ownership of them. - Custom Build Command: Replace the default
cargo buildwith your own build script or command (e.g.,cargo leptos build), perfect for projects with complex build steps like WebAssembly or CSS processing. - Data-Driven Packaging: Define your package files once in an
assetslist inCargo.tomland use loops in your template to automatically populate the%installand%filessections. - Automatic Changelog Inclusion: Reads a changelog file and injects it directly into the spec's
%changelogsection. - Clean Output Directory: Copies final RPMs to a user-defined directory (e.g.,
dist/) for easy access in CI/CD. - Workspace-Aware: Correctly locates the
targetdirectory and package paths, whether in a single crate or a complex workspace. - Post-Build Verification: The
--verifyflag parses the generated RPMs to ensure their contents and file permissions match your configuration, catching packaging errors instantly. - Native
rpmbuildBackend: Ensures 100% compatibility with all RPM features and build environments. - Developer-Friendly Workflow: A
--dry-runflag shows you exactly what would happen. - Built-in Inspector: The
infosubcommand quickly inspects the metadata and file list of any.rpmfile.
Installation
cargo install cargo-revolve
Ensure that rpmbuild is installed on your system.
- On Fedora/RHEL/CentOS:
sudo dnf install rpm-build - On openSUSE:
sudo zypper install rpmbuild
Quick Start
-
Create a
.spec.inTemplateCreate a template file (e.g.,
.revolve/my-app.spec.in). This template is now fully automatic, leveraging the tool's directory discovery.# Disable automatic debug package generation. %define debug_package %{nil} Name: {{ pkg.name }} Version: {{ pkg.version }} Release: 1%{?dist} Summary: {{ pkg.description }} License: {{ pkg.license }} Source0: {{ pkg.name }}-{{ pkg.version }}.tar.gz %description {{ pkg.description }} %prep %setup -q -n {{ builder.archive_root_dir }} %build # This section is intentionally empty. %install rm -rf %{buildroot} # This simple loop works for all assets because the tool expands directories. {% for asset in builder.assets %} install -D -m {{ asset.mode | default(value="0644") }} "{{ asset.source | split(pat="/") | last }}" "%{buildroot}{{ asset.dest }}" {% endfor %} %files %defattr(-, root, root, -) # This loop automatically adds all necessary %dir directives. {% if builder.created_dirs %}{% for dir in builder.created_dirs %} %dir {{ dir }} {% endfor %}{% endif %} # This loop lists all the individual files. {% for asset in builder.assets %} {{ asset.dest }} {% endfor %} # Conditionally include the changelog. {% if builder.changelog %} %changelog {{ builder.changelog | trim }} {% endif %} -
Configure
Cargo.tomlAdd a
[package.metadata.revolve]section to yourCargo.toml.[package.metadata.revolve] spec_template = ".revolve/my-app.spec.in" output_dir = "dist" changelog = "CHANGELOG.md" # List all asset files and directories to be included in the RPM. assets = [ # The compiled binary (a file). Its parent directory (/usr/bin) will be created. { source = "target/release/my-app", dest = "/usr/bin/my-app", mode = "0755" }, # A systemd service file. We MUST NOT own its parent directory. { source = "systemd/my-app.service", dest = "/usr/lib/systemd/system/my-app.service", mkdir = false }, # Include an entire configuration directory. # The trailing slash tells cargo-revolve to expand this into individual file assets. # The parent directories (/etc/my-app and /etc/my-app/conf.d) will be automatically owned. { source = "config/", dest = "/etc/my-app/conf.d/" }, ] -
Build!
Run the build command from the root of your project.
cargo revolve build --verifyYour newly built RPM(s) will be in the
dist/directory.
Advanced Usage: Custom Build Commands
For projects that require more than a simple cargo build (e.g., web frontends using tools like cargo-leptos, or projects requiring code generation), you can specify a custom build_command.
This feature replaces the default build step with commands of your choosing. It works in tandem with the --no-archive flag to package artifacts directly from your target directory.
-
Configure
Cargo.tomlwithbuild_commandThe
build_commandkey can be a single command string or an array of commands to be executed sequentially.[package.metadata.revolve] spec_template = ".revolve/leptos-app.spec.in" output_dir = "dist" # Run a custom build tool instead of `cargo build`. # cargo-revolve sets REVOLVE_TARGET_DIR, REVOLVE_PACKAGE_NAME, and REVOLVE_PACKAGE_VERSION # environment variables for your script to use. build_command = "cargo leptos build --release" # Define the assets created by the custom command. # The directory expansion and mkdir flags work here too! assets = [ { source = "target/server/release/leptos-app", dest = "/usr/bin/leptos-app", mode = "0755" }, { source = "target/site/", dest = "/var/www/leptos-app/" }, ] -
Create a
--no-archiveCompatible.spec.inWhen using a custom build command, you must use a spec file designed for the
--no-archiveworkflow. The automatic directory ownership feature works here as well.# This spec is for --no-archive builds with pre-built artifacts. Name: {{ pkg.name }} Version: {{ pkg.version }} Release: 1%{?dist} Summary: A Leptos web application License: MIT # This directive tells rpmbuild this is a binary-only package. %define _binary_payload w7.gzdio %description A web application built with Leptos. %prep %build %install rm -rf %{buildroot} # The simple loop works because cargo-revolve expands directory assets. {% for asset in builder.assets %} # Use the absolute path provided by _sourcedir to locate the artifact. install -D -m {{ asset.mode | default(value="0644") }} "%{_sourcedir}/{{ asset.source }}" "%{buildroot}{{ asset.dest }}" {% endfor %} %files %defattr(-, root, root, -) # The automatic %dir loop works perfectly here too. {% if builder.created_dirs %}{% for dir in builder.created_dirs %} %dir {{ dir }} {% endfor %}{% endif %} {% for asset in builder.assets %} {{ asset.dest }} {% endfor %} -
Build with
--no-archiveYou must use the
--no-archiveflag when abuild_commandis specified.cargo revolve build --no-archive --verify
Usage
cargo revolve <COMMAND>
Commands
-
cargo revolve build [OPTIONS]--dry-run: Prepare everything but skip the finalrpmbuildexecution. Prints the rendered.specand therpmbuildcommand that would be run.--verify: After building, inspect the main binary RPM to ensure its name, version, files, and permissions match your configuration.--no-archive: (Advanced) Build directly from the source tree without creating a source archive. This is the required mode for custombuild_commandworkflows where artifacts are generated in the project'stargetdirectory. Requires a spec file that does not use the%setupmacro and instead copies files from%{_sourcedir}in the%installsection.
-
cargo revolve info <RPM_FILE>- Parses the given
.rpmfile and prints its metadata and file manifest.
- Parses the given
Contributing
This project is open to contributions! Please feel free to open an issue or submit a pull request.
License
cargo-revolve is distributed under the terms of the MPL-2.0 license. See LICENSE for details.
Dependencies
~15–31MB
~431K SLoC