Wrap rust executables in OS-specific app bundles
Rust
1,373
515 commits
updated Sep 20, 2026
Wrap Rust executables in OS-specific app bundles
cargo-bundle is a tool used to generate installers or app bundles for GUI
executables built with cargo. It can create .app bundles for Mac OS X and
iOS, .deb packages and .AppImage bundles for Linux, and .msi installers
for Windows (note however that iOS and Windows support is still experimental).
Support for creating .rpm packages (for Linux) and .apk packages (for
Android) is still pending.
To install cargo bundle, run cargo install cargo-bundle. This will add the most recent version of cargo-bundle
published to crates.io as a subcommand to your default cargo installation.
To start using cargo bundle, add a [package.metadata.bundle] section to your project's Cargo.toml file. This
section describes various attributes of the generated bundle, such as its name, icon, description, copyright, as well
as any packaging scripts you need to generate extra data. The full manifest format is described below.
To build a bundle for the OS you're on, simply run cargo bundle in your
project's directory (where the Cargo.toml is placed). If you would like to
bundle a release build, you must add the --release flag to your call. To
cross-compile and bundle an application for another OS, add an appropriate
--target flag, just as you would for cargo build. On macOS the
--target flag may be repeated to build every architecture and combine them
into a single universal binary with lipo, e.g.
cargo bundle -t aarch64-apple-darwin -t x86_64-apple-darwin.
If the executable has already been built, and you'd like to avoid rebuilding,
or perhaps maintain a change you made against it, pass it with --binary-path to
package it without running cargo build again. This is useful when a CI build
and packaging step are separate, or when another build system produced the
executable. Cargo metadata is still read for the bundle manifest and selected
--bin/--example; --release, --profile, and --target still select the
bundle output directory and target metadata, but do not rebuild the supplied
file.
cargo build --release --bin my-app
cargo bundle --release --bin my-app --binary-path target/release/my-app
The supplied path must be a regular file. It is copied into the generated bundle; the input binary is not modified.
-b, --bin <NAME> Bundle the specified binary
-e, --example <NAME> Bundle the specified example
-f, --format <FORMAT> Which bundle format to produce [possible values: deb, ios, msi, wxsmsi, osx, rpm, appimage]
-r, --release Build a bundle from a target built in release mode
--profile <NAME> Build a bundle from a target build using the given profile
--binary-path <PATH> Bundle this already-built executable instead of running `cargo build`
-t, --target <TRIPLE> Build a bundle for the target triple. May be repeated to combine several architectures into a universal binary (macOS only)
--features <FEATURES> Set crate features for the bundle. Eg: `--features "f1 f2"`
--all-features Build a bundle with all crate features
--no-default-features Build a bundle without the default crate features
-p, --package <SPEC> The name of the package to bundle. If not specified, the root package will be used
-h, --help Print help
-V, --version Print version
aarch64-unknown-linux-gnu ARM64 Linux (kernel 4.1, glibc 2.17+) 1
i686-pc-windows-gnu 32-bit MinGW (Windows 7+) 2 3
i686-pc-windows-msvc 32-bit MSVC (Windows 7+) 2 3
i686-unknown-linux-gnu 32-bit Linux (kernel 3.2+, glibc 2.17+) 3
x86_64-apple-darwin 64-bit macOS (10.12+, Sierra+)
x86_64-pc-windows-gnu 64-bit MinGW (Windows 7+) 2
x86_64-pc-windows-msvc 64-bit MSVC (Windows 7+) 2
x86_64-unknown-linux-gnu 64-bit Linux (kernel 3.2+, glibc 2.17+)
There are several fields in the [package.metadata.bundle] section.
These settings apply to bundles for all (or most) OSes.
name: The name of the built application. If this is not present, then it will use the name value from bin
target in your Cargo.toml file.identifier: [REQUIRED] A string that uniquely identifies your application,
in reverse-DNS form (for example, "com.example.appname" or
"io.github.username.project"). For OS X and iOS, this is used as the
bundle's CFBundleIdentifier value; for Windows, this is hashed to create
an application GUID.icon: [OPTIONAL] The icons used for your application. This should be an array of file paths or globs (with images
in various sizes/formats); cargo-bundle will automatically convert between image formats as necessary for
different platforms. Supported formats include SVG (Linux only), ICNS, ICO, PNG, and anything else that can be decoded by the
image crate. Icons intended for high-resolution (e.g. Retina) displays
should have a filename with @2x just before the extension (see example below).version: [OPTIONAL] The version of the application. If this is not present, then it will use the version
value from your Cargo.toml file.resources: [OPTIONAL] List of files or directories which will be copied to the resources section of the
bundle. Globs are supported.script: [OPTIONAL] This is a reserved field; at the moment it is not used for anything, but may be used to
run scripts while packaging the bundle (e.g. download files, compress and encrypt, etc.).copyright: [OPTIONAL] This contains a copyright string associated with your application.category: [OPTIONAL] What kind of application this is. This can
be a human-readable string (e.g. "Puzzle game"), or a Mac OS X
LSApplicationCategoryType value
(e.g. "public.app-category.puzzle-games"), or a GNOME desktop
file category name (e.g. "LogicGame"), and cargo-bundle will
automatically convert as needed for different platforms.short_description: [OPTIONAL] A short, one-line description of the application. If this is not present, then it
will use the description value from your Cargo.toml file.long_description: [OPTIONAL] A longer, multi-line description of the application.note: description is also required in the [package] section.
Platform-specific settings belong in their platform sub-table. This keeps the metadata typed: for example, macOS frameworks cannot be declared in the main bundle table.
[package.metadata.bundle]
name = "Example"
identifier = "com.example.app"
[package.metadata.bundle.osx]
frameworks = ["WebKit.framework"]
These settings are used when bundling Linux packages (deb, rpm, appimage).
Declare these in [package.metadata.bundle.linux] using the concise names below.
mime_types: A list of strings which represent mime types. If present, these are assigned
to the MimeType field of the .desktop file.
exec_args: A single string which is inserted after the name of the binary in the Exec
field in the .desktop file. For example if the binary is called my_program and
exec_args = "%f" then the Exec filed will be Exec=my_program %f. Find out more from the
specification
use_terminal: A boolean variable indicating the app is a console app or a gui app, default it's set to false.
localizations: Per-locale translations for FreeDesktop .desktop entry fields.
Mirrors the shape of osx.localizations: each sub-table is a locale code
(fr, de, pt_BR, zh_CN, …) containing optional FreeDesktop
localestring
keys. Supported keys:
Name -- translated application name (Name[fr]=…)GenericName -- generic type name, e.g. "Web Browser"Comment -- short description / tooltipKeywords -- search keywords; either a semicolon-separated string
("outil;utilitaire") or a TOML list (["outil", "utilitaire"]), both
emitted with a trailing ; per the Desktop Entry SpecIcon — locale-specific icon name (Icon[locale]=…; rarely needed)Locale codes may include an encoding part (fr.UTF-8); it is stripped when
rendering, since desktop files are always UTF-8.
Unlocalized Name and Comment still come from name / short_description
(or the package description). If only localized GenericName / Keywords
are provided, the unlocalized base value is taken from the C or en
locale when present, otherwise from the first locale in sorted order
(FreeDesktop requires an unlocalized key whenever any Key[locale] is
present).
Example:
[package.metadata.bundle.linux.localizations.fr]
Name = "Mon App"
Comment = "Une description"
GenericName = "Utilitaire"
Keywords = ["outil", "utilitaire"]
[package.metadata.bundle.linux.localizations.de]
Name = "Meine App"
Comment = "Eine Beschreibung"
Keywords = "werkzeug;dienstprogramm"
startup_wm_class: [OPTIONAL] Value for the StartupWMClass key of the .desktop
file, used by desktop environments to match running windows to the launcher entry.
desktop_actions: [OPTIONAL] Additional application actions (e.g. "New Window")
shown in launcher context menus, emitted as [Desktop Action <id>] groups. Each sub-table
key is an action id; Name is required, Exec defaults to the app binary, Icon and
per-locale NameLocalized are optional:
[package.metadata.bundle.linux.desktop_actions.new-window]
Name = "New Window"
Exec = "myapp --new-window"
[package.metadata.bundle.linux.desktop_actions.new-window.NameLocalized]
fr = "Nouvelle fenêtre"
These settings are used only when bundling appimage packages.
The type-2 AppImage runtime is downloaded from the official continuous release for the target architecture and cached under the user cache directory.
appimage_metainfo_path: [OPTIONAL] Path to an
AppStream metainfo XML file, copied to
usr/share/metainfo/<identifier>.appdata.xml inside the AppDir. A warning is printed when
absent — software centers increasingly expect metainfo.appimage_compression: [OPTIONAL] SquashFS codec, "gzip" (default, maximally compatible),
"lz4", "lzo", or "none".Limitations: Shared libraries are not auto-collected (unlike tools that wrap
linuxdeploy / appimagetool). Dynamically linked GUI apps may need matching system libraries
on the target machine, or you can stage libs under usr/lib in the AppDir yourself.
These settings are used only when bundling deb packages.
deb_depends: A list of strings indicating other packages (e.g. shared
libraries) that this package depends on to be installed. If present, this
forms the Depends: field of the deb package control file.These settings are used only when bundling osx packages and belong in
[package.metadata.bundle.osx].
frameworks: A list of strings indicating any Mac OS X frameworks that
need to be bundled with the app. Each string can either be the name of a
framework (without the .framework extension, e.g. "SDL2"), in which case
cargo-bundle will search for that framework in the standard install
locations (~/Library/Frameworks/, /Library/Frameworks/, and
/Network/Library/Frameworks/), or a path to a specific framework bundle
(e.g. ./data/frameworks/SDL2.framework). Note that this setting just makes
cargo-bundle copy the specified frameworks into the OS X app bundle (under
Foobar.app/Contents/Frameworks/); you are still responsible for (1)
arranging for the compiled binary to link against those frameworks (e.g. by
emitting lines like cargo:rustc-link-lib=framework=SDL2 from your
build.rs script), and (2) embedding the correct rpath in your binary
(e.g. by running install_name_tool -add_rpath "@executable_path/../Frameworks" path/to/binary after compiling).minimum_system_version: A version string indicating the minimum Mac OS
X version that the bundled app supports (e.g. "10.11"). If you are using
this config field, you may also want have your build.rs script emit
cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11 (or whatever version number
you want) to ensure that the compiled binary has the same minimum version.url_schemes: A list of strings indicating the URL schemes that the app
handles.info_plist_exts: A list of path strings that contain extra values for
Info.plist. It reads each file in that path, and blindly appends its
contents into the Info.plist file, after cargo-bundle has generated its
keys but before it closes the <dict> and <plist>.dmg_background: A path string pointing to an SVG that becomes the
Finder window background of the DMG bundle. The SVG must contain elements
with ids app and applications; the center of each element becomes the
icon position of the application bundle and of the /Applications symlink
respectively. The image is rendered at 2x resolution so it stays crisp on
Retina displays. See examples/hello/dmg-background.svg for an example.Apple application bundles and DMGs are signed in-process with the pure-Rust
apple-codesign library. Export the
Developer ID certificate and private key from Keychain Access as a .p12 file,
then configure it by path. The password is read from an environment variable;
optional entitlements, hardened runtime, and an RFC 3161 timestamp are also
supported:
[package.metadata.bundle]
apple_signing_p12 = "secrets/developer-id.p12"
apple_signing_password_env = "APPLE_SIGNING_PASSWORD"
apple_signing_entitlements = "packaging/entitlements.plist"
apple_signing_hardened_runtime = true
apple_signing_timestamp_url = "https://timestamp.example.com"
The same implementation works on Linux, Windows, and macOS; no codesign or
other signing executable is spawned. It signs the finished .app before DMG
creation, and then signs the final DMG itself. It does not notarize artifacts.
Do not modify a signed app or DMG afterwards: changing an executable,
framework, plugin, resource, or disk image invalidates its signature. Keep the
.p12 file and its password in CI secrets, never in version control.
Windows .exe and .msi artifacts can be Authenticode-signed with a PKCS#12
certificate. This support is not enabled by default because it links the
vendored osslsigncode implementation, which is GPL-3.0-or-later (with an
OpenSSL linking exception). Build or install cargo-bundle with the explicit
feature only if those terms are acceptable for the binary you distribute:
cargo install cargo-bundle --features windows-signing
Then keep the certificate password out of Cargo.toml and configure signing
through an environment variable:
[package.metadata.bundle.windows_signing]
certificate_path = "secrets/publisher.p12"
certificate_password_env = "WINDOWS_CERTIFICATE_PASSWORD"
timestamp_url = "https://timestamp.example.com"
timestamp_url is optional and is sent as an RFC 3161 timestamp request. When
certificate_password_env is omitted, the signing backend prompts on the
terminal. Supplying Windows signing metadata to a cargo-bundle executable that
was not built with windows-signing is an error rather than silently emitting
an unsigned artifact. In CI, protect the certificate and password as secrets;
never commit either one. Signatures are applied to the final generated .exe
or .msi, so later changes invalidate them.
Linux artifacts use keyless Sigstore signing when configured.
Configure the environment variable holding an OIDC identity token whose
audience is sigstore:
[package.metadata.bundle.linux_signing]
identity_token_env = "SIGSTORE_ID_TOKEN"
Every generated .deb, .rpm, or .AppImage then receives an adjacent
<artifact>.sigstore.json Sigstore bundle containing the signature,
certificate, and transparency-log proof. The original artifact is unchanged;
publish the sidecar bundle with it. This is keyless signing: the token must be
fresh and normally comes from your CI provider's OIDC integration. For a
release that signs both Linux and Windows outputs, install with
--features windows-signing; enabling windows-signing still has the
GPL-3.0-or-later consequence described above.
[package.metadata.bundle] only applies to the main executable.
Settings for other binaries can be specified in a [package.metadata.bundle.bin.<binary name>] section.
[package]
# other fields...
[package.metadata.bundle.bin.foo]
icon = ["icons/foo32x32.png"]
# other fields...
[[bin]]
name = "foo"
path = "src/bin/foo.rs"
# other fields...
Cargo.toml:[package]
name = "example"
# ...other fields...
[package.metadata.bundle]
name = "ExampleApplication"
identifier = "com.doe.exampleapplication"
icon = ["32x32.png", "128x128.png", "128x128@2x.png"]
version = "1.0.0"
resources = ["assets", "images/**/*.png", "secrets/public_key.txt"]
copyright = "Copyright (c) Jane Doe 2016. All rights reserved."
category = "Developer Tool"
short_description = "An example application."
long_description = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
"""
deb_depends = ["libgl1-mesa-glx", "libsdl2-2.0-0 (>= 2.0.5)"]
[package.metadata.bundle.osx]
frameworks = ["SDL2"]
url_schemes = ["com.doe.exampleapplication"]
cargo-bundle has ambitions to be inclusive project and welcome contributions from anyone. Please abide by the Rust
code of conduct.
Very early alpha. Expect the format of the [package.metadata.bundle] section to change, and there is no guarantee of
stability.
This program is licensed either under the terms of the Apache Software License, or the MIT License.
Overall
Maintained
Code review
crates.io
Latest release
Releases this year
(top 24 of 50)
1,061 followers · starred Mar 2021
1,030 followers · starred Jul 2017
208 followers · starred Dec 2020
501 followers · starred Feb 2020
Wrap rust executables in OS-specific app bundles
Rust
1,373
515 commits
updated Sep 20, 2026
Wrap Rust executables in OS-specific app bundles
cargo-bundle is a tool used to generate installers or app bundles for GUI
executables built with cargo. It can create .app bundles for Mac OS X and
iOS, .deb packages and .AppImage bundles for Linux, and .msi installers
for Windows (note however that iOS and Windows support is still experimental).
Support for creating .rpm packages (for Linux) and .apk packages (for
Android) is still pending.
To install cargo bundle, run cargo install cargo-bundle. This will add the most recent version of cargo-bundle
published to crates.io as a subcommand to your default cargo installation.
To start using cargo bundle, add a [package.metadata.bundle] section to your project's Cargo.toml file. This
section describes various attributes of the generated bundle, such as its name, icon, description, copyright, as well
as any packaging scripts you need to generate extra data. The full manifest format is described below.
To build a bundle for the OS you're on, simply run cargo bundle in your
project's directory (where the Cargo.toml is placed). If you would like to
bundle a release build, you must add the --release flag to your call. To
cross-compile and bundle an application for another OS, add an appropriate
--target flag, just as you would for cargo build. On macOS the
--target flag may be repeated to build every architecture and combine them
into a single universal binary with lipo, e.g.
cargo bundle -t aarch64-apple-darwin -t x86_64-apple-darwin.
If the executable has already been built, and you'd like to avoid rebuilding,
or perhaps maintain a change you made against it, pass it with --binary-path to
package it without running cargo build again. This is useful when a CI build
and packaging step are separate, or when another build system produced the
executable. Cargo metadata is still read for the bundle manifest and selected
--bin/--example; --release, --profile, and --target still select the
bundle output directory and target metadata, but do not rebuild the supplied
file.
cargo build --release --bin my-app
cargo bundle --release --bin my-app --binary-path target/release/my-app
The supplied path must be a regular file. It is copied into the generated bundle; the input binary is not modified.
-b, --bin <NAME> Bundle the specified binary
-e, --example <NAME> Bundle the specified example
-f, --format <FORMAT> Which bundle format to produce [possible values: deb, ios, msi, wxsmsi, osx, rpm, appimage]
-r, --release Build a bundle from a target built in release mode
--profile <NAME> Build a bundle from a target build using the given profile
--binary-path <PATH> Bundle this already-built executable instead of running `cargo build`
-t, --target <TRIPLE> Build a bundle for the target triple. May be repeated to combine several architectures into a universal binary (macOS only)
--features <FEATURES> Set crate features for the bundle. Eg: `--features "f1 f2"`
--all-features Build a bundle with all crate features
--no-default-features Build a bundle without the default crate features
-p, --package <SPEC> The name of the package to bundle. If not specified, the root package will be used
-h, --help Print help
-V, --version Print version
aarch64-unknown-linux-gnu ARM64 Linux (kernel 4.1, glibc 2.17+) 1
i686-pc-windows-gnu 32-bit MinGW (Windows 7+) 2 3
i686-pc-windows-msvc 32-bit MSVC (Windows 7+) 2 3
i686-unknown-linux-gnu 32-bit Linux (kernel 3.2+, glibc 2.17+) 3
x86_64-apple-darwin 64-bit macOS (10.12+, Sierra+)
x86_64-pc-windows-gnu 64-bit MinGW (Windows 7+) 2
x86_64-pc-windows-msvc 64-bit MSVC (Windows 7+) 2
x86_64-unknown-linux-gnu 64-bit Linux (kernel 3.2+, glibc 2.17+)
There are several fields in the [package.metadata.bundle] section.
These settings apply to bundles for all (or most) OSes.
name: The name of the built application. If this is not present, then it will use the name value from bin
target in your Cargo.toml file.identifier: [REQUIRED] A string that uniquely identifies your application,
in reverse-DNS form (for example, "com.example.appname" or
"io.github.username.project"). For OS X and iOS, this is used as the
bundle's CFBundleIdentifier value; for Windows, this is hashed to create
an application GUID.icon: [OPTIONAL] The icons used for your application. This should be an array of file paths or globs (with images
in various sizes/formats); cargo-bundle will automatically convert between image formats as necessary for
different platforms. Supported formats include SVG (Linux only), ICNS, ICO, PNG, and anything else that can be decoded by the
image crate. Icons intended for high-resolution (e.g. Retina) displays
should have a filename with @2x just before the extension (see example below).version: [OPTIONAL] The version of the application. If this is not present, then it will use the version
value from your Cargo.toml file.resources: [OPTIONAL] List of files or directories which will be copied to the resources section of the
bundle. Globs are supported.script: [OPTIONAL] This is a reserved field; at the moment it is not used for anything, but may be used to
run scripts while packaging the bundle (e.g. download files, compress and encrypt, etc.).copyright: [OPTIONAL] This contains a copyright string associated with your application.category: [OPTIONAL] What kind of application this is. This can
be a human-readable string (e.g. "Puzzle game"), or a Mac OS X
LSApplicationCategoryType value
(e.g. "public.app-category.puzzle-games"), or a GNOME desktop
file category name (e.g. "LogicGame"), and cargo-bundle will
automatically convert as needed for different platforms.short_description: [OPTIONAL] A short, one-line description of the application. If this is not present, then it
will use the description value from your Cargo.toml file.long_description: [OPTIONAL] A longer, multi-line description of the application.note: description is also required in the [package] section.
Platform-specific settings belong in their platform sub-table. This keeps the metadata typed: for example, macOS frameworks cannot be declared in the main bundle table.
[package.metadata.bundle]
name = "Example"
identifier = "com.example.app"
[package.metadata.bundle.osx]
frameworks = ["WebKit.framework"]
These settings are used when bundling Linux packages (deb, rpm, appimage).
Declare these in [package.metadata.bundle.linux] using the concise names below.
mime_types: A list of strings which represent mime types. If present, these are assigned
to the MimeType field of the .desktop file.
exec_args: A single string which is inserted after the name of the binary in the Exec
field in the .desktop file. For example if the binary is called my_program and
exec_args = "%f" then the Exec filed will be Exec=my_program %f. Find out more from the
specification
use_terminal: A boolean variable indicating the app is a console app or a gui app, default it's set to false.
localizations: Per-locale translations for FreeDesktop .desktop entry fields.
Mirrors the shape of osx.localizations: each sub-table is a locale code
(fr, de, pt_BR, zh_CN, …) containing optional FreeDesktop
localestring
keys. Supported keys:
Name -- translated application name (Name[fr]=…)GenericName -- generic type name, e.g. "Web Browser"Comment -- short description / tooltipKeywords -- search keywords; either a semicolon-separated string
("outil;utilitaire") or a TOML list (["outil", "utilitaire"]), both
emitted with a trailing ; per the Desktop Entry SpecIcon — locale-specific icon name (Icon[locale]=…; rarely needed)Locale codes may include an encoding part (fr.UTF-8); it is stripped when
rendering, since desktop files are always UTF-8.
Unlocalized Name and Comment still come from name / short_description
(or the package description). If only localized GenericName / Keywords
are provided, the unlocalized base value is taken from the C or en
locale when present, otherwise from the first locale in sorted order
(FreeDesktop requires an unlocalized key whenever any Key[locale] is
present).
Example:
[package.metadata.bundle.linux.localizations.fr]
Name = "Mon App"
Comment = "Une description"
GenericName = "Utilitaire"
Keywords = ["outil", "utilitaire"]
[package.metadata.bundle.linux.localizations.de]
Name = "Meine App"
Comment = "Eine Beschreibung"
Keywords = "werkzeug;dienstprogramm"
startup_wm_class: [OPTIONAL] Value for the StartupWMClass key of the .desktop
file, used by desktop environments to match running windows to the launcher entry.
desktop_actions: [OPTIONAL] Additional application actions (e.g. "New Window")
shown in launcher context menus, emitted as [Desktop Action <id>] groups. Each sub-table
key is an action id; Name is required, Exec defaults to the app binary, Icon and
per-locale NameLocalized are optional:
[package.metadata.bundle.linux.desktop_actions.new-window]
Name = "New Window"
Exec = "myapp --new-window"
[package.metadata.bundle.linux.desktop_actions.new-window.NameLocalized]
fr = "Nouvelle fenêtre"
These settings are used only when bundling appimage packages.
The type-2 AppImage runtime is downloaded from the official continuous release for the target architecture and cached under the user cache directory.
appimage_metainfo_path: [OPTIONAL] Path to an
AppStream metainfo XML file, copied to
usr/share/metainfo/<identifier>.appdata.xml inside the AppDir. A warning is printed when
absent — software centers increasingly expect metainfo.appimage_compression: [OPTIONAL] SquashFS codec, "gzip" (default, maximally compatible),
"lz4", "lzo", or "none".Limitations: Shared libraries are not auto-collected (unlike tools that wrap
linuxdeploy / appimagetool). Dynamically linked GUI apps may need matching system libraries
on the target machine, or you can stage libs under usr/lib in the AppDir yourself.
These settings are used only when bundling deb packages.
deb_depends: A list of strings indicating other packages (e.g. shared
libraries) that this package depends on to be installed. If present, this
forms the Depends: field of the deb package control file.These settings are used only when bundling osx packages and belong in
[package.metadata.bundle.osx].
frameworks: A list of strings indicating any Mac OS X frameworks that
need to be bundled with the app. Each string can either be the name of a
framework (without the .framework extension, e.g. "SDL2"), in which case
cargo-bundle will search for that framework in the standard install
locations (~/Library/Frameworks/, /Library/Frameworks/, and
/Network/Library/Frameworks/), or a path to a specific framework bundle
(e.g. ./data/frameworks/SDL2.framework). Note that this setting just makes
cargo-bundle copy the specified frameworks into the OS X app bundle (under
Foobar.app/Contents/Frameworks/); you are still responsible for (1)
arranging for the compiled binary to link against those frameworks (e.g. by
emitting lines like cargo:rustc-link-lib=framework=SDL2 from your
build.rs script), and (2) embedding the correct rpath in your binary
(e.g. by running install_name_tool -add_rpath "@executable_path/../Frameworks" path/to/binary after compiling).minimum_system_version: A version string indicating the minimum Mac OS
X version that the bundled app supports (e.g. "10.11"). If you are using
this config field, you may also want have your build.rs script emit
cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11 (or whatever version number
you want) to ensure that the compiled binary has the same minimum version.url_schemes: A list of strings indicating the URL schemes that the app
handles.info_plist_exts: A list of path strings that contain extra values for
Info.plist. It reads each file in that path, and blindly appends its
contents into the Info.plist file, after cargo-bundle has generated its
keys but before it closes the <dict> and <plist>.dmg_background: A path string pointing to an SVG that becomes the
Finder window background of the DMG bundle. The SVG must contain elements
with ids app and applications; the center of each element becomes the
icon position of the application bundle and of the /Applications symlink
respectively. The image is rendered at 2x resolution so it stays crisp on
Retina displays. See examples/hello/dmg-background.svg for an example.Apple application bundles and DMGs are signed in-process with the pure-Rust
apple-codesign library. Export the
Developer ID certificate and private key from Keychain Access as a .p12 file,
then configure it by path. The password is read from an environment variable;
optional entitlements, hardened runtime, and an RFC 3161 timestamp are also
supported:
[package.metadata.bundle]
apple_signing_p12 = "secrets/developer-id.p12"
apple_signing_password_env = "APPLE_SIGNING_PASSWORD"
apple_signing_entitlements = "packaging/entitlements.plist"
apple_signing_hardened_runtime = true
apple_signing_timestamp_url = "https://timestamp.example.com"
The same implementation works on Linux, Windows, and macOS; no codesign or
other signing executable is spawned. It signs the finished .app before DMG
creation, and then signs the final DMG itself. It does not notarize artifacts.
Do not modify a signed app or DMG afterwards: changing an executable,
framework, plugin, resource, or disk image invalidates its signature. Keep the
.p12 file and its password in CI secrets, never in version control.
Windows .exe and .msi artifacts can be Authenticode-signed with a PKCS#12
certificate. This support is not enabled by default because it links the
vendored osslsigncode implementation, which is GPL-3.0-or-later (with an
OpenSSL linking exception). Build or install cargo-bundle with the explicit
feature only if those terms are acceptable for the binary you distribute:
cargo install cargo-bundle --features windows-signing
Then keep the certificate password out of Cargo.toml and configure signing
through an environment variable:
[package.metadata.bundle.windows_signing]
certificate_path = "secrets/publisher.p12"
certificate_password_env = "WINDOWS_CERTIFICATE_PASSWORD"
timestamp_url = "https://timestamp.example.com"
timestamp_url is optional and is sent as an RFC 3161 timestamp request. When
certificate_password_env is omitted, the signing backend prompts on the
terminal. Supplying Windows signing metadata to a cargo-bundle executable that
was not built with windows-signing is an error rather than silently emitting
an unsigned artifact. In CI, protect the certificate and password as secrets;
never commit either one. Signatures are applied to the final generated .exe
or .msi, so later changes invalidate them.
Linux artifacts use keyless Sigstore signing when configured.
Configure the environment variable holding an OIDC identity token whose
audience is sigstore:
[package.metadata.bundle.linux_signing]
identity_token_env = "SIGSTORE_ID_TOKEN"
Every generated .deb, .rpm, or .AppImage then receives an adjacent
<artifact>.sigstore.json Sigstore bundle containing the signature,
certificate, and transparency-log proof. The original artifact is unchanged;
publish the sidecar bundle with it. This is keyless signing: the token must be
fresh and normally comes from your CI provider's OIDC integration. For a
release that signs both Linux and Windows outputs, install with
--features windows-signing; enabling windows-signing still has the
GPL-3.0-or-later consequence described above.
[package.metadata.bundle] only applies to the main executable.
Settings for other binaries can be specified in a [package.metadata.bundle.bin.<binary name>] section.
[package]
# other fields...
[package.metadata.bundle.bin.foo]
icon = ["icons/foo32x32.png"]
# other fields...
[[bin]]
name = "foo"
path = "src/bin/foo.rs"
# other fields...
Cargo.toml:[package]
name = "example"
# ...other fields...
[package.metadata.bundle]
name = "ExampleApplication"
identifier = "com.doe.exampleapplication"
icon = ["32x32.png", "128x128.png", "128x128@2x.png"]
version = "1.0.0"
resources = ["assets", "images/**/*.png", "secrets/public_key.txt"]
copyright = "Copyright (c) Jane Doe 2016. All rights reserved."
category = "Developer Tool"
short_description = "An example application."
long_description = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
"""
deb_depends = ["libgl1-mesa-glx", "libsdl2-2.0-0 (>= 2.0.5)"]
[package.metadata.bundle.osx]
frameworks = ["SDL2"]
url_schemes = ["com.doe.exampleapplication"]
cargo-bundle has ambitions to be inclusive project and welcome contributions from anyone. Please abide by the Rust
code of conduct.
Very early alpha. Expect the format of the [package.metadata.bundle] section to change, and there is no guarantee of
stability.
This program is licensed either under the terms of the Apache Software License, or the MIT License.
Overall
Maintained
Code review
crates.io
Latest release
Releases this year
(top 24 of 50)
1,061 followers · starred Mar 2021
1,030 followers · starred Jul 2017
208 followers · starred Dec 2020
501 followers · starred Feb 2020