I have integration tests that invoke
cargo run --bin=xyz. They do this (rather than running the binaries from
target/) for a number of reasons:
- To ensure that the binary target is up to date
- Because something just doesn’t feel kosher about peeking into
- When I call things directly from
target, sometimes they are missing runtime link paths for dynamic libraries
Unfortunately, sometimes problems arise where the test harness apparently runs in an environment that is sufficiently modified from the original build environment that it triggers a rebuild of a
build.rs somewhere down the dependency tree. (example: if the test cds into a temporary directory, it won’t see a project-local
.cargo/config anymore, which might cause it to lose some build flags)
This can turn a quick test into a 20 minute endeavor (ten minutes for the unit test, and then another 10 minutes the next time I build the harness as the environment will be back to normal!). It is a royal pain to debug, and I don’t know of any reliable way to tell what exactly caused it to rebuild.
Cargo guarantees that binaries are built before integration tests are run.
You may not like it, but that’s how the official way to do this looks like Cargo itself does this itself It would be awesome to wrap this path shenanigans into a reusable library.
That is problematic, yeah. I am not familiar enough with this bit, so no advice here
Playing around with it, it looks like
cargo does this by modifying
LD_LIBRARY_PATH to add
cargo:rustc-link-search direcctories. By comparing the output of
std::env::var("LD_LIBRARY_PATH") in an integration test, I see the following entries get added:
Those first four seem highly problematic! There are often unused directories for a crate in
build that are leftover from previous builds, and so when there is more than one pair of directories, I see no easy way to tell which one is the correct one!
Wait a second.
I am a dummy.
I just stated that the integration tests see these paths in
std::env::var("LD_LIBRARY_PATH"). This means that they should be able to call the binaries in
target/ without running into problems…and indeed they can!
Crisis averted, at least for now.