rust-embed-resource
A Cargo
build script library to handle compilation and inclusion of Windows resources
in the most resilient fashion imaginable
Documentation
Quickstart
In your build script, assuming the resource file is called checksums.rc
:
extern crate embed_resource;
fn main() {
// Compile and link checksums.rc
embed_resource::compile("checksums.rc", embed_resource::NONE);
// Or, to select a resource file for each binary separately
embed_resource::compile_for("assets/poke-a-mango.rc", &["poke-a-mango", "poke-a-mango-installer"], &["VERSION=\"0.5.0\""]);
embed_resource::compile_for("assets/uninstaller.rc", &["unins001"], embed_resource::NONE);
}
Example: Embedding a Windows Manifest
Courtesy of @jpoles1.
The following steps are used to embed a manifest in your compiled rust .exe file. In this example the manifest will cause admin permissions to be requested for the final executable:
- Add the following to your cargo.toml:
[build-dependencies]
embed-resource = "2.2"
- In your project root directory, add a file named
build.rs
with the following:
extern crate embed_resource;
fn main() {
embed_resource::compile("app-name-manifest.rc", embed_resource::NONE);
}
- In your project root directory, add a file named
app-name-manifest.rc
with the following:
#define RT_MANIFEST 24
1 RT_MANIFEST "app-name.exe.manifest"
- In your project root directory, add a file named
app-name.exe.manifest
with the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
- Build your project!
Errata
If no cargo:rerun-if-changed
annotations are generated, Cargo scans the entire build root by default.
Because the first step in building a manifest is an unspecified C preprocessor step with-out the ability to generate the equivalent of cc -MD
, we do not output said annotation.
If scanning is prohibitively expensive, or you have something else that generates the annotations, you may want to spec the full non-system dependency list for your manifest manually, so:
println!("cargo:rerun-if-changed=app-name-manifest.rc");
embed_resource::compile("app-name-manifest.rc", embed_resource::NONE);
for the above example (cf. #41).
Migration
2.x
Add embed_resource::NONE
as the last argument to embed_resource::compile()
and embed_resource::compile_for()
.
Credit
In chronological order:
@liigo -- persistency in pestering me and investigating problems where I have failed
@mzji -- MSVC lab rat
@TheCatPlusPlus -- knowledge and providing first iteration of manifest-embedding code
@azyobuzin -- providing code for finding places where RC.EXE could hide
@retep998 -- fixing MSVC support
@SonnyX -- Windows cross-compilation support and testing
@MSxDOS -- finding and supplying RC.EXE its esoteric header include paths
@roblabla -- cross-compilation to Windows MSVC via LLVM-RC
Special thanks
To all who support further development on Patreon, in particular:
- ThePhD
- Embark Studios
- Lars Strojny
- EvModder