A multi-platform companion tool to help package your Rust app when using cargo-packager.
In a workspace, you can run cargo packager from the app crate directory. The tool will use the
current directory for ./resources and ./dist, and use --path-to-binary to locate the target dir.
[package.metadata.packager]
product_name = "Robrix"
out_dir = "./dist"
before-each-package-command = """
robius-packaging-commands before-each-package \
--binary-name robrix \
--path-to-binary ../../target/release/robrix
"""
resources = [
{ src = "./dist/resources/makepad_widgets", target = "makepad_widgets" },
{ src = "./dist/resources/makepad_fonts_chinese_bold", target = "makepad_fonts_chinese_bold" },
{ src = "./dist/resources/makepad_fonts_chinese_bold_2", target = "makepad_fonts_chinese_bold_2" },
{ src = "./dist/resources/makepad_fonts_chinese_regular", target = "makepad_fonts_chinese_regular" },
{ src = "./dist/resources/makepad_fonts_chinese_regular_2", target = "makepad_fonts_chinese_regular_2" },
{ src = "./dist/resources/makepad_fonts_emoji", target = "makepad_fonts_emoji" },
{ src = "./dist/resources/robrix", target = "robrix" },
]This program should be invoked by cargo-packager's "before-package" and "before-each-package" hooks,
which you must specify in your Cargo.toml file under the [package.metadata.packager] section.
It uses the current working directory as the app root for ./resources and ./dist,
while --path-to-binary is used to locate the target directory (useful in workspaces).
Important
You must build in release mode (using cargo packager --release).
Important
To build a Linux .deb package, you need to install dpkg-dev:
sudo apt-get install dpkg-devSee the example below for an app called "Robrix" with a binary named "robrix".
## Configuration for `cargo packager`
[package.metadata.packager]
product_name = "Robrix"
[package.metadata.packager.macos]
## You can use `-` as the value for `signing_identity`,
## if you just want to test the packaging on macOS without signing the app.
signature_identity = "-"
...
## Note: for Makepad apps, you only need to specify `before-packaging-command`
## if you're using Makepad versions **BEFORE** v1.0.
## If using Makepad v1.0 or higher, you can omit this.
##
## This runs just one time before packaging starts.
before-packaging-command = """
robius-packaging-commands before-packaging \
--binary-name robrix \
--path-to-binary ./target/release/robrix
"""
...
## This runs once before building each separate kind of package,
## so it is used to build your app specifically for each package kind.
before-each-package-command = """
robius-packaging-commands before-each-package \
--binary-name robrix \
--path-to-binary ./target/release/robrix
"""
## Note: if you're using Makepad versions **BEFORE** v1.0, you only need these resources:
resources = [
{ src = "./dist/resources/makepad_widgets", target = "makepad_widgets" },
{ src = "./dist/resources/robrix", target = "robrix" },
]
## Note: if you're using Makepad v1.0 or higher, you need to specify more resource files:
resources = [
{ src = "./dist/resources/makepad_widgets", target = "makepad_widgets" },
{ src = "./dist/resources/makepad_fonts_chinese_bold", target = "makepad_fonts_chinese_bold" },
{ src = "./dist/resources/makepad_fonts_chinese_bold_2", target = "makepad_fonts_chinese_bold_2" },
{ src = "./dist/resources/makepad_fonts_chinese_regular", target = "makepad_fonts_chinese_regular" },
{ src = "./dist/resources/makepad_fonts_chinese_regular_2", target = "makepad_fonts_chinese_regular_2" },
{ src = "./dist/resources/makepad_fonts_emoji", target = "makepad_fonts_emoji" },
{ src = "./dist/resources/robrix", target = "robrix" },
]Once you have this package metadata fully completed in your app crate's Cargo.toml,
you are ready to run.
- Install
cargo-packager:
rustup update stable ## Rust version 1.79 or higher is required
cargo +stable install --force --locked cargo-packager- Install this appropriate version of this crate, either from
crates.ioor from this git repo.
Important
For Makepad apps using Makepad versions before v1.0, install robius-packaging-commands --version 0.1.
For Makepad apps using Makepad versions after v1.0, install the newest version of robius-packaging-commands.
# From crates.io
cargo install robius-packaging-commands --version <VERSION> --locked# From this git repo
cargo install --version <VERSION> --locked [--git https://github.com/project-robius/robius-packaging-commands.git]- Then run the packaging routine:
cargo packager --release ## --verbose is optionalThis program no longer requires the workspace root as the working directory.
It uses the current working directory for app resources (./resources) and build output (./dist),
and uses --path-to-binary to locate the target directory (e.g., a workspace target/release).
This program runs in two modes, one for each kind of before-packaging step in cargo-packager:
before-packaging: specifies that thebefore-packaging-commandis being run by cargo-packager, which gets executed only once before cargo-packager generates any package bundles.
Important
The before-packaging command is not needed if building an app using Makepad v1.0 or higher.
before-each-package: specifies that thebefore-each-package-commandis being run by cargo-packager, which gets executed multiple times: once for each package that cargo-packager is going to generate.
- The environment variable
CARGO_PACKAGER_FORMATis set by cargo-packager to the declare which package format is about to be generated, which include the values given here: https://docs.rs/cargo-packager/latest/cargo_packager/enum.PackageFormat.html.app,dmg: for macOS.deb,appimage,pacman: for Linux.nsis: for Windows;nsisgenerates an installersetup.exe.wix: (UNSUPPORTED) for Windows; generates an.msiinstaller package.
Tip
For .deb packages, runtime dependencies are computed automatically:
dpkg-shlibdepshandles every dynamically-linked lib, version-pinned.- The binary is scanned for what the linker can't see: dlopen'd libs (e.g. Makepad's
libEGL.so.1), TLS (ca-certificates), andxdg-open(xdg-utils). A soname only counts if an instruction actually references it, so a lib merely named in an error message doesn't become a dep. desktop-file-utilsandhicolor-icon-themeare always added; their dpkg triggers are what register the.desktopfile (deep links included) and the app icons.
Makepad apps also skip the libs Makepad dlopens but runs fine without (its GStreamer
video stack). Other apps don't inherit that, since skipping a lib an app really needs
would ship a broken .deb.
To fix anything missed: --add-deb-dep <package> adds a dep, and
--optional-deb-dep-prefix <stem> marks a dlopen'd lib as optional so it's skipped.
Both are repeatable, and ignored for non-.deb formats.
Tip
verify-deb checks that a built .deb really declares what it uses:
robius-packaging-commands verify-deb --deb ./dist/myapp_1.0.0_amd64.debIt installs the package into a minimal container with only its Depends (which also
proves it's installable), boots the app under strace, and fails if anything the app
loads or spawns isn't covered. On failure it prints the missing packages and the exact
command to add them. Worth running in CI: scanning a binary can't prove a dlopen'd lib
or spawned program was found.
--host skips the container (quicker, weaker), --image <distro:version> picks the
test distro, --run-secs <n> sets how long the app runs (default 10), and
--binary-name <name> picks the binary if the .deb ships several.
Note it only sees code paths a short boot exercises, so a pass means the startup-critical deps are there, not that the list is provably complete.
This program uses the CARGO_PACKAGER_FORMAT environment variable to determine
which specific build commands and configuration options should be used.
MIT