Crate omnicopy_to_output
source ·Expand description
Provides a generalized implementation for a “post build copy” operation, which isn’t well-supported in rust at time of writing. This crate is inspired by https://github.com/prenwyn/copy_to_output, but implements more managed helpers + addresses some of the missing scenarios (again, at time of writing).
As the name implies, the goal here is to provide coverage for all possible build scenarios as a stand-in until (if) there is a native solution in the rust tooling. If anything is missing, please contribute!
§Examples
-
Use in
build.rs
with automatic discovery.Path is relative to project root. If your resources are in your project, cargo will automatically detect changes and invalidate the cache as needed.
use omnicopy_to_output::copy_to_output; fn main() { // Copy everything recursively from the res folder and place into output. copy_to_output("res").expect("Could not copy"); }
-
Use in
build.rs
with custom target (e.g. if your have different shared libraries for debug).Note, if you used both your builds will fail. Each target directory only exists when that build is run. A full example would have conditional logic.
use omnicopy_to_output::copy_to_output_for_profile; fn main() { // Manually specify the profile (i.e. env:PROFILE) copy_to_output_for_profile("res/foo.dll", "release").expect("Could not copy"); copy_to_output_for_profile("res/food.dll", "debug").expect("Could not copy"); }
-
Invalidate Cache for external resources
Large resources may not exist in your project. We can still copy those to output, but cargo will not detect changes and invalidate the cache. Emitting cargo:rerun-if-changed instructions will inform cargo these files exist, but then will change cache invalidation to only what you specify. Note, as soon as you do this in one place the default “anything in package” rules no longer apply. This is something you ideally are configuring anyway though.
use omnicopy_to_output::{copy_to_output, cargo_rerun_if_changed}; fn main() { let path_to_large_resources = "/path/to/large/resources"; cargo_rerun_if_changed(path_to_large_resources); copy_to_output(path_to_large_resources).expect("Could not copy"); }
§Scenario Coverage
Key motivations for the original fork were supporting workspaces + managed experience for cargo cache instructions.
We support accommodating:
- Build types (e.g. retail vs test; integration tests see files)
- cargo::CompileKind
- Target
- Cross compilation (special case target)
- Workspace or single crate build
§Considerations
This is in lieu of a better solution from cargo directly. In particular, it’s worth noting that build scripts should not modify any files outside the OUT_DIR directory. We’re not modifying, but it’s still not necessarily in the “spirit” of the instructions.
§How it Works
To locate the target directory, we must know the project root and the target.
- Determine if the output directory was overridden with
env:CARGO_TARGET_DIR
- If yes, use that path directly
- If not, the path will default to
{workspace_root}/target
which we determine using project_root.
- Determine which
CompileKind
is used. Cargo doesn’t expose this directly. This crate is intended to be used in build scripts. Cargo providesenv:OUT_DIR
for build scripts. This isn’t where we want to place these assets, but it does allow us to infer theCompileKind
. If the triple + profile ({target}/{profile}
) appears in the path, thenCompileKind::Target
was used. Otherwise,CompileKind::Host
was used. Profile comes fromenv:Profile
and target from build_target::target_triple.- For
CompileKind::Host
we concatenate/{profile}
- For
CompileKind::Target
we concatenate/{target}/{profile}
- For
Functions§
- Emits cargo:rerun-if-changed. NOTE: Once any
rerun-if-changed
is emitted, only the files specified are monitored. You can emit multiple times. - Emits cargo:rerun-if-changed. NOTE: Once any
rerun-if-changed
is emitted, only the files specified are monitored. You can emit multiple times. - Copies files to output recursively
- Copies files to output recursively
- Copies files to output recursively
- Copies files to output recursively