-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build script fails to link #41416
Comments
I am also experiencing this issue. In particular, I'm having issues linking to dynamic libraries. In rust, when I declare the extern block I add I created a super simple toy example to show this. The code is available at: /~https://github.com/sga001/rust-linking-issue I tested the above with the following nightly versions: rustc 1.18.0-nightly (2564711 2017-04-04) works fine. Here's a gist of the output from the latest nightly version. Note that this is not just about Boost. I used boost in the toy example because that's a common library. In my actual application this happens with boost, mpfr, gmp, and gomp (basically all libraries that I'm dynamically linking). Thanks P.S. I also posted this in (rust-lang/cc-rs#155) |
Here's the commit range for the nightly regression range above, for the rust repo. (I'm not sure whether the bug is in Rust or Cargo, so I might be looking in the wrong place.) |
It shouldn't be in Cargo or gcc-rs etc, because they are the same in my case. Only rustc and rust-std are different. |
Thanks for the report @lilydjwg! Looks like @mbrubeck is spot on in a diagnosis. The critical change is that the order of arguments passed to the linker is different than before:
Previously code partitioned linked libraries into static first then dynamic. That was mostly just an accident and not intentional. In 78c3a49 it was changed, however, to not partition. The real bug here is that the order libraries to the linker matters. The You can fix this locally by simply moving the call to cc @vadimcn |
@alexcrichton I think that I follow the issue that you explain I tried adding: println!("cargo:rustc-link-search=/usr/lib/");
println!("cargo:rustc-link-lib=boost_system");
EDIT: It does work as soon as I remove all link attributes and leave the println in the build file. It seemed cleaner before though, where I could specify all libraries to link in link attributes rather than in the build script. |
Although not officially specified anywhere, we pass libraries to the linker in this order:
As Alex mentioned, previously we reordered libraries in step (2) into all static ones followed by all dynamic ones, but that was done purely for convenience in that particular piece of code. In your case, it is important to keep in mind that build script helpers like for l in lib.libs {
println!('cargo:rustc-link-lib={}', l);
}
I don't think this is a good idea: the behavior depended on whether one or both libraries were static or dynamic. I think this is exactly what @sga001 is running into. @sga001: Since #[link(name = "libtest_time")]
#[link(name = "boost_system")]
extern "C" {
fn print_time();
} |
@alexcrichton yes reordering works for me, but it's not as simple as moving lines, since I need to know the include files before compiling my C code. I have to do like this like @vadimcn said: let lib = pkg_config::Config::new().cargo_metadata(false).probe("lua53").unwrap();
let mut gcc = gcc::Config::new();
gcc.file("src/c.c");
for p in lib.include_paths {
gcc.include(p);
}
gcc.compile("libc-sys.a");
for l in lib.libs {
println!("cargo:rustc-link-lib={}", l);
} IMO this thing should be documented somewhere easy to find. I knew it should be ordering issues but I didn't see there was ordering that I could change in the beginning. |
Ok glad to hear it's now working @lilydjwg! Also to confirm @sga001, you've gotten your example to work now as well, right? At the absolute bare minimum I'll tag the relevant PR with The question then is how to ease the transition. If we have a lot of instances of this then we should definitely revert and think of a better strategy, but if the problems are isolated and easy to fix I think we can keep forging ahead. That being said, though, do others on @rust-lang/tools have different opinions? |
@alexcrichton: yeah it was easy to fix. Thanks for the help. |
Ok I'm going to close this as "expected breakage" at this point as the change has hit stable and there's explanations above for what this is and why it's changed from before. |
In the demo, I have Rust calls my C function which links to an external library.
With
rustc 1.17.0-nightly (8c4f2c64c 2017-03-22)
and before, it builds and runs successfully. Withrustc 1.18.0-nightly (666e7148d 2017-04-08)
and later, I getundefined reference
s. I get these Rust's from the official distribution (though without rustup). My system is Arch Linux up-to-date.I've diff'ed
cargo run -vv
, all other parts are the same, only the above error report appears with newer versions.PS: you can replace
lua53
inbuild.rs
with whatever version you have in your system. It shouldn't matter.PPS: this error occurs in Ubuntu 14.04 too.
The text was updated successfully, but these errors were encountered: