Rust programs may want to generate assets/products which aren't for the build itself, but are products to be used along with the program, such as:
- bash_completion files
- manpages and other auto-generated documentation
- .service files for setting up servers under systemd
- icon/resource files compiled from raw images
Currently Cargo runs
build.rs with an
OUT_DIR variable, but the location of
OUT_DIR is private to the build script, and it's unpredictable. It's fine as a temporary directory to be used during the build, but it doesn't seem appropriate for files to be used after the build is done.
These files usually need to be present in a predictable location, so that post-build tools can find them and package them along with other Cargo products.
What would be the right solution for generating and making these files available?
Current options are:
build.rsplace files in
OUT_DIRand then searching for this directory. This is obviously hacky, slow, and may break when Cargo stats placing temporary files in dedicated system directories rather than dumping everything in
build.rsplace files in
./target/…/somewhere. This is trickier than it seems, because paths in
targetare different during cross-compilation, and the
build.rsscript isn't told where exactly is the target dir, so scripts have to replicate a Cargo's implementation detail. Also, this means that all crates write to the same shared directory, so they could overwrite each others' files.
Generating the files using a different build system external to Cargo, using custom locations. While this works, it misses out on integration with the Cargo ecosystem. For example,
cargo-debwon't know how to build such crates, and would have to require extra configuration or invent its own non-standard solution for this.
Based on discussion in the Cargo GitHub issue, I suggest the following:
Add a new directive supported in build scripts:
cargo:asset=<path>which tells Cargo that the given path is a build product from the script, and this file should be kept.
Cargo will move/copy/hardlink the asset to a well-defined location, such as
It's in two steps in order to let Cargo track build script outputs and be able to manage the asset directories.
It could be extended, e.g.
cargo:asset=kind=<path> with different kinds for guiding
cargo install and letting it place the assets in appropriate system directories.
cargo:asset=<absolute source path>:<relative dest path> to generate assets with a directory structure instead of "flat" list of files (or the source path could just be a directory in the first place).
What do you think?