Description
Rust 1.35 (currently in beta) changes the way linking order works, probably rust-lang/rust#57018.
For a my project, which uses cc
to build a C wrapper for a (system) C++ library, this is now confusing. At least, it's taken me multiple hours to work out what's going on, and I thought I should write it down somewhere!
cc
adds a cargo:
command to static link the helper library, without me asking it to inside build.rs:
cc::Build::new().file(SRC).compile("libfoo-helper.a");
The app then links both the helper and the actual library:
#[link(name = "foo-helper", kind = "static")]
#[link(name = "foo")]
extern "C" {
This worked on rustc
/cargo
up until +nightly-2019-03-20
, and is broken on +nightly-2019-03-21
, which is 3eb4890df..82e2f3ec2
. After that, you get linker errors.
Why? The reordering now means that, regardless of how you specify your #[link
directives, rustc
reorders the three commands such that the libraries are in the wrong order.
The simplest solution I have is to provide both libraries in the build.rs
. This makes both of my #[link
directives above redundant.
This doesn't feel like a bug in rustc
as such, but I'm .. I'm not happy with the behaviour.
Should cc
provide a hint on how to do this right? Perhaps a way to specify that a build "depends on" a dynamic library, even though this information is not needed during the compilation?
Or maybe rustc
/cargo
is just being unreasonable, and should be reverted?