I'm doing some build system integration for Rust, and I'd like the final link line to be defined by the external build-system, not Cargo, while cargo is responsible for fetching dependencies and building Rust code. Is there any way to 1) have cargo build without linking, and 2) get cargo to output the statically-known (i.e. not requiring build scripts to run) object files and rlib files I need to link in my build system?
The most common way to do this is to have cargo generate a static library, and then you can link that static library together with the rest of your code using your linker of choice.
Add something like the following to your Cargo.toml:
[lib]
name = "mylib"
crate-type = ["staticlib"]
Yeah, sorry, maybe my question isn't specific enough. I want to be able to take an existing crate that is either a cdylib
or a bin
, make 0 code changes, and instead link the files myself. This is for build system integration scenario where there may be a bunch of additional link options and libraries that the crate itself doesn't know, but the hosting build system needs applied (say, transitive link dependencies of a C or C++ dependency of the bin
crate). Your answer is fine for the cdylib
scenario - there shouldn't be any reason you can't just link the static library into a shared library pretty easily. However, for bin
crates, it would be kind of irritating if you couldn't just define fn main()
and instead had to define an int main()
or something that then calls the "real" entry point. It would break a lot CLI crates, too.
Ah, I see.
In that case, your best bet might be either a .cargo/config
file or the corresponding environment variables. You can set the linker to any program you want, that way. You can also set arbitrary rustflags, which could include things like -C linker
or -C link-args
.
Yeah, so that's where I'm at right now - I'm already replacing the linker using the environment variable and I plan to pass the link libraries and options I know about via -C link-args
. To be even more explicit, this is for my project Corrosion that does Cargo integration into CMake. You can get a shallow list of dependencies out of a library, but not the transitive dependencies, or at least the "final" transitive dependencies. Only CMake is able to generate a "complete" link line. So my thought is I should just let CMake generate the link line, which would give full resolution. Sounds like that won't be possible, though. I have some ideas to do a 90% job and document the corner cases, but unfortunately that's all I can get to, I think. Basically, I'll need to require that all transitive dependencies are established prior to setting the link dependencies for the cargo crates.