Packer for creating self-contained single-binary applications from executables and directories.
- Packing of executables and their dependencies into single self-contained binaries
- Compression of packed payloads with Zstandard
- Streaming decompression with minimal memory overhead
- Compression and decompression of files in parallel
- Decompression only when necessary by checking existing files
- Automatic transfer of resources including icons and version information
- Platform support for Windows, macOS, Linux and more
With wrappe you can distribute your application and its files as a single executable without the need for an installer, while resulting in a smaller file size and faster startup than many alternatives.
A snapshot build of the latest version can be found on the release page.
Snapshot builds contain runners for Windows (x86_64-pc-windows-gnu
), macOS (x86_64-apple-darwin
and aarch64-apple-darwin
) and Linux (x86_64-unknown-linux-musl
), allowing packing for these platforms without additional setup.
Alternatively wrappe can be installed with cargo
, see the compilation section for more info on how to compile wrappe with additional runners for other platforms.
wrappe --compression 16 app app/diogenes.exe packed.exe
Run wrappe
with an input
directory, the command
to launch and the output
filename to create a single-binary executable.
The input directory and all contained files and links will be packed. The command must be an executable file within the input directory that should be launched after unpacking.
wrappe [OPTIONS] <input> <command> [output] [-- <ARGUMENTS>...]
Arguments:
<input> Path to the input directory
<command> Path to the executable to start after unpacking
[output] Path to or filename of the output executable
[ARGUMENTS]... Command line arguments to pass to the executable
Options:
-r, --runner <RUNNER>
Platform to pack for (see --list-runners for available options) [default: native]
-c, --compression <COMPRESSION>
Zstd compression level (0-22) [default: 8]
-t, --unpack-target <UNPACK_TARGET>
Unpack directory target (temp, local, cwd) [default: temp]
-d, --unpack-directory <UNPACK_DIRECTORY>
Unpack directory name [default: inferred from input directory]
-v, --versioning <VERSIONING>
Versioning strategy (sidebyside, replace, none) [default: sidebyside]
-e, --verification <VERIFICATION>
Verification of existing unpacked data (existence, checksum, none) [default: existence]
-s, --version-string <VERSION_STRING>
Version string override [default: randomly generated]
-i, --show-information <SHOW_INFORMATION>
Information output details (title, verbose, none) [default: title]
-n, --console <CONSOLE>
Show or attach to a console window (auto, always, never, attach) [default: auto]
-w, --current-dir <CURRENT_DIR>
Working directory of the command (inherit, unpack, runner, command) [default: inherit]
-o, --once
Allow only one running instance
-z, --build-dictionary
Build compression dictionary
-l, --list-runners
Print available runners
-h, --help
Print help
-V, --version
Print version
Additional arguments for the packed executable can be specified after --
and will automatically be passed to the command when launched.
If the packed executable needs to access packed files by relative path and expects a certain working directory, use the --current-dir
option to set it to its parent directory or the unpack directory. The WRAPPE_UNPACK_DIR
and WRAPPE_LAUNCH_DIR
environment variables will always be set for the command with the paths to the unpack directory and the inherited working directory.
Packed Windows executables will have their subsystem, icons and other resources automatically transferred to the output executable through editpe.
The packing and unpacking behavior is highly customizable. The default options are suitable for most use cases, but can be adjusted to fit specific requirements.
This option specifies which runner will be used for the output executable. The runner is the pre-built executable that unpacks the payload and starts the packed command.
Partial matches are accepted if unambiguous, for instance windows
will be accepted if only one runner for Windows is available.
It defaults to the native runner for the current platform. Additional runners have to be included at compile time, see the compilation section for more info.
This option controls the Zstandard compression level. Accepted values range from 0
to 22
. Higher compression levels will result in smaller output files, but will also increase the packing time.
It defaults to 8
.
This option specifies the directory the packed files are unpacked to. Accepted values are:
temp
: The files will be unpacked to the systems temporary directory.local
: The files will be unpacked to the local data directory, usuallyUser/AppData/Local
on Windows and/home/user/.local/share
on Linux.cwd
: The files will be unpacked to the working directory of the runner executable.
It defaults to temp
.
This option specifies the unpack directory name inside the unpack-target
. It defaults to the name of the input file or directory.
This option specifies the versioning strategy. Accepted values are:
sidebyside
: An individual directory will be created for every version. An already unpacked version will not be unpacked again.replace
: Already unpacked files from a different version will be overwritten. Unpacked files from the same version will not be upacked again.none
: Packed files are always unpacked and already unpacked files will be overwritten.
It defaults to sidebyside
. The version is determined by a unique identifier generated during the packing process or specified with the version-string
option.
Using replace
or none
might cause unpacking to fail if another instance of the packed executable is already running unless the once
option is set.
This option specifies the verification of the unpacked payload before skipping extraction. Accepted values are:
existence
: All files in the payload will be checked for existence.checksum
: A checksum for all files will be calculated and compared with the checksum calculated during the packing process.none
: No verification will be performed. Unpacking will be skipped if the unpack directory exists and was created with the same version string.
It defaults to existence
. This option has no effect when versioning
is set to none
.
This option specifies the version string. It defaults to a randomly generated string of 8 characters.
This option controls the information output of the runner. Accepted values are:
title
: The runner will output thewrappe
version and the unpack directory.verbose
: The runner will output various additional details like unpack status, configuration and payload size.none
: The runner will show no additional output.
It defaults to title
. Error information is always shown when applicable. Windows runners using the GUI subsystem will only show information output when launched from a console and this option is set to verbose
, or a console is attached or opened through the console
option.
This option controls if the runner should attach to a console or if a console window should be opened when launching a Windows application from the Windows explorer. Accepted values are:
auto
: Select the console behavior based on the subsystem of the input executable if available. If not available, it will fall back tonever
for Windows runners, andalways
for all other runners.always
Always attach to or open a console. The runner will block the console until the packed executable exits.never
: Never open or attach to a console. The runner will immediately exit after launching the packed executable.attach
: Never open a new console window, but attach to an existing console if available. The runner will unblock the console immediately, but output will still be shown.
It defaults to auto
. This option currently only affects Windows runners, other runners will always attach to a console if available. This option will also not prevent packed Windows command line applications from opening a console on their own when launched from the Windows explorer.
This option changes the working directory of the packed executable. Accepted values are:
inherit
: The working directory will be inherited from the runner. This is usually the directory containing the runner or the directory from which the runner was launched.unpack
: The working directory will be set to the unpack directory. This is the top-level directory of the unpacked payload.runner
: The working directory will be set to the directory containing the runner, with all symbolic links resolved.command
: The working directory will be set to the directory containing the unpacked executable. This will either be the unpack directory or a subdirectory within the unpacked payload.
It defaults to inherit
.
This option prevents multiple instances of the packed executable from running at the same time. When set, the runner will check for running processes on the system and will exit immediately if a running instance of the executable is found during startup.
This option currently only affects Windows and Linux runners. On Windows, if the packed executable is a GUI application, the runner will bring its window into the foreground and activate it.
This option builds a zstandard compression dictionary from the input files and stores it in the output executable. This can improve the compression ratio when many small and similar files are packed.
At least 8 input files are required to build a dictionary, and at most 128 KB of data from each input file will be sampled.
Building a dictionary can increase the packing time and can in some cases negatively affect the compression ratio. It is recommended to test the results with and without this option to determine whether it is beneficial for the specific use case.
Wrappe is optimized for compression ratio and decompression speed, generally matching or outperforming other packers in terms of both. It uses a custom metadata format designed for parallel iteration and decompression and compact storage of file information. Packed files are concurrently decompressed from the memory-mapped executable directly to disk, while extraction is skipped when the files are already unpacked to enable fast startup of packed executables with minimal overhead.
As an example, a 400 MB PyInstaller one-directory output with 1500 files packed with wrappe at maximum compression level results in a 100 MB executable that unpacks and starts in around 500 milliseconds on a modern Windows system on the first run and instantly on subsequent runs. This is around 50% faster and only 5% larger than the same project packed by PyInstaller in one-file mode with UPX compression, which unpacks and loads into memory on every run.
Generally, on a reasonably modern system, the decompression speed of wrappe is limited by the read and write speed of the system and storage medium.
Compiling wrappe will also compile a runner for your current platform by default.
cargo install wrappe
To compile and include additional runners for other platforms, specify the desired target triples in the WRAPPE_TARGETS
environment variable.
WRAPPE_TARGETS=x86_64-unknown-linux-gnu;x86_64-pc-windows-msvc cargo install wrappe
Target-specific rustflags for runners can be configured through the WRAPPE_TARGET_RUSTFLAGS_{target triple}
environment variable.
Additional targets need to be available to cargo
for cross compilation. Targets can be installed with rustup
, for example rustup target add x86_64-unknown-linux-musl
.
Some cross compilation targets require certain AR
, CC
and CXX
environment variables to be set. Target-specific AR
, CC
and CXX
can be configured through the WRAPPE_TARGET_{AR|CC|CXX}_{target triple}
environment variables.
Cross compilation of additional runners can alternatively be performed through cross when available and the WRAPPE_USE_CROSS
environment variable is set to true
.
When including runners for multiple macOS targets, the WRAPPE_MACOS_UNIVERSAL
environment variable can be set to a list of targets to build a universal runner with lipo
containing the specified architectures, for example x86_64-apple-darwin;aarch64-apple-darwin
. This runner will be included as universal-apple-darwin
.