Skip to content
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

Native libraries for the local crate linked in the wrong order #28595

Closed
alexcrichton opened this issue Sep 22, 2015 · 1 comment
Closed

Native libraries for the local crate linked in the wrong order #28595

alexcrichton opened this issue Sep 22, 2015 · 1 comment
Labels
A-linkage Area: linking into static, shared libraries and binaries

Comments

@alexcrichton
Copy link
Member

There's currently a large comment in the compiler explaining how we link artifacts in this order:

  1. The local object file
  2. Rust dependencies
  3. Local native dependencies
  4. Upstream native dependencies

It also explicitly mentions why 2/3 are a little backwards.

Unfortunately, however, it looks like the ordering above causes link errors in otherwise correct situations. For example let's consider (code example at the end of this issue)

  • We have a dependency, B, which statically links the native library libB
  • We are linking a native dependency libA which depends on libB
  • We are also producing an executable.

The ordering of flags on the command line will be:

[ object file ]  [ B rlib + libB ] [ libA ]

The problem here is that libB is contained in B's rlib, so the ordering of the linker is incorrect, libA shows up after libB. This will cause a linker error if the object file doesn't otherwise reference symbols from B's rlib.

I think that the wording for why steps 2/3 above are swapped is far out of date by this point (with Cargo build scripts and modern methods to link native libraries), so it sounds to me like they should be swapped now. This may cause breakage, but it should always be fixable by restructuring the DAG to more accurately reflect the network of dependencies between C libraries and Rust crates.

# Cargo.toml
[package]
name = "a"
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = "build.rs"

[build-dependencies]
gcc = "0.3"
[dependencies]
b = { path = "b" }
// build.rs
extern crate gcc;

fn main() {
    gcc::compile_library("liba.a", &["src/lib.c"]);
}
// src/main.rs
extern crate b;

extern {
    fn a();
}

fn main() {
    unsafe { a(); }
}
// src/lib.c
extern void b(void);

void a(void) {
  b();
}
# b/Cargo.toml
[package]
name = "b"
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = "build.rs"

[build-dependencies]
gcc = "0.3"
// b/build.rs
extern crate gcc;

fn main() {
    gcc::compile_library("libb.a", &["src/lib.c"]);
}
// b/src/lib.c
void b() {}
@alexcrichton alexcrichton added the A-linkage Area: linking into static, shared libraries and binaries label Sep 22, 2015
alexcrichton added a commit to alexcrichton/rust that referenced this issue Sep 23, 2015
This commit swaps the order of linking local native libraries and upstream
native libraries on the linker command line. Detail of bugs this can cause can
be found in rust-lang#28595, and this change also invalidates the test case that was
added for rust-lang#12446 which is now considered a bug because the downstream dependency
would need to declare that it depends on the native library somehow.

Closes rust-lang#28595
@brson
Copy link
Contributor

brson commented Sep 28, 2015

Should we crater this? Sounds frightening.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Oct 1, 2015
This commit swaps the order of linking local native libraries and upstream
native libraries on the linker command line. Detail of bugs this can cause can
be found in rust-lang#28595, and this change also invalidates the test case that was
added for rust-lang#12446 which is now considered a bug because the downstream dependency
would need to declare that it depends on the native library somehow.

Closes rust-lang#28595
bors added a commit that referenced this issue Oct 1, 2015
This commit swaps the order of linking local native libraries and upstream
native libraries on the linker command line. Detail of bugs this can cause can
be found in #28595, and this change also invalidates the test case that was
added for #12446 which is now considered a bug because the downstream dependency
would need to declare that it depends on the native library somehow.

Closes #28595
[breaking-change]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries
Projects
None yet
Development

No branches or pull requests

2 participants