Problem
I'm not 100% sure this is a bug, and as an attempt to avoid an X/Y problem, I'll start by describing what I'm ultimately trying to do (which is related to #7825).
I have Rust crates with crate-type = ["cdylib"] or crate-type = ["staticlib"] (or both), and I'd like to run what are essentially integration tests written in C to ensure that my header files are correct, the libraries are built correctly, etc. And I'd really like for those tests to run when I run cargo test.
What I'm currently doing which almost works is that I have two crates: one that produces the C library and the other that exists solely to run the integration tests. The testing crate uses cc to build C code that calls the library produced by the "real" crate; its build.rs looks roughly like this (this example is assuming a staticlib):
fn main() {
cc::Build::new()
.file("src/tests.c")
.include("../real-crate/include")
.compile("c_integration_tests");
let profile_dir = /* ... */; // find "target/release" or "target/debug" based on OUT_DIR
println!("cargo:rustc-link-search=native={}", profile_dir);
println!("cargo:rustc-link-lib=static=real_crate");
}
There are (at least) two problems with this:
- Finding
target/release or target/debug based on OUT_DIR is pretty hacky.
target/release/libreal_crate.a isn't actually built when I run cargo test (even if it's a dependency); only the hash-suffixed library name (target/release/deps/libreal_crate-XXXXXXXXXXXXXXX.a) exists.
The first problem is a little gross but hasn't seemed to be a big deal in practice, although I assume it's something that might change over time. The second is more problematic; a workaround is to cargo build before cargo testing, but it's hard to remember to do that every time, and it's not ideal to have to tell everyone working on the project that that's a requirement.
Steps
- Create a crate with
crate-type = ["staticlib"].
- Create another crate that depends on it.
- Run
cargo test.
- The static lib from the first crate is not built in the target dir.
Possible Solution(s)
I considered finding target/{release,debug}/deps via OUT_DIR then scanning that directory to find the library-with-suffix and linking that, but that seems even more fragile.
Notes
Output of cargo version:
cargo 1.43.0 (3532cf7 2020-03-17)
Problem
I'm not 100% sure this is a bug, and as an attempt to avoid an X/Y problem, I'll start by describing what I'm ultimately trying to do (which is related to #7825).
I have Rust crates with
crate-type = ["cdylib"]orcrate-type = ["staticlib"](or both), and I'd like to run what are essentially integration tests written in C to ensure that my header files are correct, the libraries are built correctly, etc. And I'd really like for those tests to run when I runcargo test.What I'm currently doing which almost works is that I have two crates: one that produces the C library and the other that exists solely to run the integration tests. The testing crate uses
ccto build C code that calls the library produced by the "real" crate; itsbuild.rslooks roughly like this (this example is assuming astaticlib):There are (at least) two problems with this:
target/releaseortarget/debugbased onOUT_DIRis pretty hacky.target/release/libreal_crate.aisn't actually built when I runcargo test(even if it's a dependency); only the hash-suffixed library name (target/release/deps/libreal_crate-XXXXXXXXXXXXXXX.a) exists.The first problem is a little gross but hasn't seemed to be a big deal in practice, although I assume it's something that might change over time. The second is more problematic; a workaround is to
cargo buildbeforecargo testing, but it's hard to remember to do that every time, and it's not ideal to have to tell everyone working on the project that that's a requirement.Steps
crate-type = ["staticlib"].cargo test.Possible Solution(s)
I considered finding
target/{release,debug}/depsviaOUT_DIRthen scanning that directory to find the library-with-suffix and linking that, but that seems even more fragile.Notes
Output of
cargo version:cargo 1.43.0 (3532cf7 2020-03-17)