I feel like the answer to this ought to be obvious, but I've been staring at the cargo and cc crate documentation for hours and I can't figure it out.
I have a library crate. It has unit tests.
I want to compile one C source file and link it into the unit tests but not into the library proper. Ideally, build.rs would only compile the C source file when compiling the tests, so you wouldn't need to have a C compiler at all if you weren't going to compile the tests.
Is this a thing that can be done today, and, if so, how? Not necessarily with the cc crate.
(It'd be even nicer if build.rs itself could be marked as only necessary for the tests, but I'm like 98% sure that's not currently possible.)
Uh, maybe it does? Maybe I'm just not seeing how to put it together. I find the documentation of how build.rs works and how it communicates with Cargo very confusing.
The way they communicate is through environment variables and stdout. There are a number of conventional variable names for inputs and output strings that it looks for. Those are the basics, anyway.
Now that I look closer, there is the links key that cargo expects in the package metadata. I actually don't know how that interacts with the link attribute, or whether it is always required.
Iām not very familiar with the details of linking in C code, but based on what I know of the Cargo build process, you need to use two packages:
[package]
name = "foo"
[dev-dependencies]
foo-test-helper = { ... }
[package]
name = "foo-test-helper"
# this package has the build.rs and C library
Now, if I understand correctly, you can put your extern declarations in eitherfoo or foo-test-helper, but the build script will be run, and the C library will only be compiled and linked, when building foo's tests, since foo-test-helper is a dev-dependency rather than a regular dependency.