Rust - dev-dependencies

Hi,

According to Rust documentation here on specifying dev-dependencies, it says >

Dev-dependencies are not used when compiling a package for building, but are used for compiling tests, examples, and benchmarks.

When I compile my project though, the sources get copied to another location, along with various other resources and at this point dev-dependencies path is invalid.
I am building the project using a build script 'build.rs' where I've defined where to find the 'rlib' of the dependency and the name of library like so

println!("cargo:rustc-link-search=/path/to/rlib/");
println!("cargo:rustc-link-lib=libMyLib.rlib");

But this fails compilation and I get failed to load dependency and cargo is using the dev-dependency path.
However, if I remove the dev-dependency section all together then this works!!

I am not sure I completely understand, I thought this should've worked.

libMyLib - is a RUST library that I created and the crate-type is:

[lib]
crate-type = ["rlib"]

Also, the lib iteself does have a couple of basic tests!! but it's already in a compiled state by the time we get to compile the project, and it's the project that is in build - compile and not the lib!

Any ideas what's going on here..
Regards,

Why are you building an rlib rather than a binary, staticlib or cdylib?

Why?

You can't link an rlib using cargo:rustc-link-lib. You can only link it using the --extern rustc flag, which you can't set from a build script. In general cargo doesn't support using pre-compiled rust dependencies. If you want to use a rust dependency you should declare it in the [dependencies], [dev-dependencies] or [build-dependencies] section of Cargo.toml depending on when you use the dependency.

2 Likes

This workflow is not supported by Cargo. rlib is an internal implemenation detail, and you're not supposed to be using it.

build.rs and cargo:rustc-link-lib are meant for non-Rust dependencies, like system-global C libraries.

1 Like

Using "cargo:rustc-link-lib" does work though strangely enough if I remove the [dev-dependency] section.

I used an rlib, because I thought staticlib is essentially for C libraries, essentially non Rust

It may happen to work due to implementation details if the crate using cargo:rustc-link-lib has all dependencies that the linked rlib has, but this is not guaranteed and may well break in the future.

I am trying replacing a system built (multiple components) in 'C', with a RUST component at a time (and trying to get better at RUST at the same time :smiley:).

Many of these systems it seems use CMake and CMake it seems likes to keep the sources clear from build folders and so does a lot of setting paths, variables, moving folders or sym link them.

So the path to the crate at the time of writing the component becomes invalid at the time of build, cause the CMake has moved the sources to another place together with other (non RUST) components and libraries.
There could be several solutions to this, possibly by hacking around in CMakeLists, but I was looking for something that RUST / Cargo might already provide.
I think I dont want to rethink the build system at this point.

I didnt see the docs say that I'm not supposed to use an rlib and cargo:rustc-link-lib surprisingly worked after I removed[dev-dependencies] section
I would like to know / find out any preferred workflow for projects that have a mix of RUST and C for a time before they completely migrate to RUST.
Thinking about this, it could also be a situation where someone might use docker container to build RUST projects and probably end up in a similar situation, where the paths have changed

The preferred workflow in mixed Rust/C projects is to have a single rust crate that is a staticlib (this crate can have regular rust dependencies) and then link just this staticlib. Or alternatively to build the C parts from a build script, but otherwise treat it as a regular rust project that you build using cargo build.

2 Likes

Yea, that's how I started for the first component,
but now I have two RUST components and hence two staticlibs with shared functionality that I want to pull out into a third staticlib, and use that as dependency in the other two and CMake spoils the party.

This third shared functionality crate is where I used crate-type = ['staticlib', 'rlib']

I have tried, 'paths' override in .cargo/config.toml, but even that fails if the path in [dependencies] or [dev-dependencies] fails

The best supported way is to merge both rust components into one from the perspective of cmake such that there is a single staticlib. They can still use different crates at the cargo side. Keeping both separate components on the cmake side is currently not supported by rustc without using hacks that will likely break in the future. You might want to follow Formal support for linking rlibs using a non-Rust linker · Issue #73632 · rust-lang/rust · GitHub.

3 Likes

Thanks for your replies and for the link, a lot to read on there for me.