-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Linking dylib fails in some cases, "undefined reference to `rust_begin_unwind" #18807
Comments
Duplicating all rlibs on the command line makes the error go away. Which means this is a link ordering issue between Rust rlibs. |
I believe that this is because the program here isn't actually using any symbols from the standard library. We do actually do a topological sort of the libs on the command line. The linker command line looks like:
However, this program doesn't actually use any symbols from the standard library's rlib, so the linker actually discards The best way to solve this... I'm not entirely sure! I've thought in the past that each object generated by rustc needs a symbol which can be referenced by objects to guarantee the linker doesn't strip any of them, which would definitely help here but is slightly heavy-handed... |
@alexcrichton, if we topologically sort them, shouldn't -lstd have come after -lcore? I thought we simply piled all upstream libraries onto linker command line. Can you point me to the code that does topo-sorting? |
My current understanding of linkers leads me to believe that we need a topological sorting with the outermost dependencies at the far left and their own dependencies to the right. For example, if I have a crate c1 that links to c2 which links to c3, we have two options:
|
Oops, posted too soon! Anyway, let's assume that c1 calls c2 functions, but does not call any c3 functions. We do know, however, that c2 calls c3 functions. This means that in the first example, there are outstanding undefined references when In the second case, when the linker looks at The current topo-sort is here: rust/src/librustc/metadata/cstore.rs Lines 156 to 184 in 351f7af
|
I think linker works ever simpler than that: it goes through the libraries on the command line left-to-right, and at each step tries to resolve currently outstanding symbols. It never examines libraries to the left of the current one. |
@alexcrichton, I wonder if we have circular dependencies in this case. Does anything in std depend on core? |
You can't actually encode a circular dependency in Rust itself, but std/core do have a circular relationship where std depends heavily on core for all its symbols and core depends on the "weak lang items" coming from std (aka rust_begin_unwind). That's the source of the problem here sadly :( |
If it's a one-off, I suppose it doesn't make sense to build the logic for dealing with circular dependencies into |
Yeah I'm ok with adding a linker flag for specifically symbol for now. |
No luck, |
@roeyskatt, just make sure that you call |
@vadimcn hehe, thanks :) |
I have the same issue when not building with Cargo, without rlibs, on handmade_no_std. Wait, nevermind, I'm just being dumb. |
This commit adds support for x86_64-unknown-linux-musl as a target of the compiler. There's some comments in the commit about some of the more flavorful flags passed to the linker as it's not quite as trivial as the normal specs.
Workaround is to add println!(""); in a spare function you never use. This somehow forces the compiler to link things correctly, as far as I can tell. #[no_mangle]
pub extern "C" fn mandel(x: f32, y: f32, dwell: i32) -> i32 {
//your code here
}
#[allow(dead_code)]
fn spare() { println!(""); } //adding this (doesn't have to be named "spare") makes the compilation work.
// you don't even need to add this function signature where you're using these functions. |
This fixes a linking issue with integers, and updates the Python code to run the correct interpreter and use the proper DLL names. # `integers` The problem here is that, on Windows, if you don't use any symbols from the standard library *and* create a dynamic library, linking will fail. This is a known issue (rust-lang/rust#18807) and the only half-way decent solution is to include a dead function that *does* use something from the standard library. # Python Two changes. First, I've added a hashbang to invoke the correct Python interpreter. On Windows, it's common to execute scripts directly without specifying the interpreter. In addition, it is *not* common to have multiple versions of Python accessible on the PATH at one time. As such, Python on Windows comes with a "launcher" that reads the hashbang and executes the appropriate version of Python. Anyone with Python 3.x installed will almost certainly have *that* as the default, so indicating that the script needs Python 2.x specifically is a really good idea. Also, the existing examples do not correctly determine the name of the Windows libraries being loaded. Two things: they end in `.dll` and they *do not* start with `lib`.
I'm having the same issue on Linux with cargo with a setup like the following: Library crate #![no_std]
pub fn do_panic() -> ! {
panic!("test")
} Bin crate: #![no_main]
extern crate corepanic;
#[no_mangle]
pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
corepanic::do_panic()
} @domgetter's workaround works in this case too |
I'm currently playing around with calling Rust code from a bunch of different languages and was having the same problem (Ubuntu Linux). The workaround @domgetter mentioned of using something from the std library to make sure it's linked in works. I had to Without the $ rustc --version
rustc 1.14.0-nightly (16eeeac78 2016-10-18)
$ rustc prime.rs -O --crate-type cdylib
$ nm libprime.rs
00000000000183b0 T is_prime And with the $ nm libprime.rs
000000000004c150 T is_prime
00000000000872c0 T __rust_allocate
...
00000000000811f0 T __rust_start_panic
000000000004c1d0 T spare Are there any special flags you can pass into rustc/cargo in order to make sure it links in the necessary things from std? |
This indeed is no longer a Windows-specific issue. I believe that the introduction of @jethrogb and @Michael-F-Bryan, could you help me confirm my suspicion? Were you using @alexcrichton, would you mind updating the labels to reflect this change? |
Certainly! |
- move all bindings into libc.rs - fix failing doc error - removed unneeded dependencies - tried to get it to compile on linux, no-main still fails, commented out f01-main.rs and f04-echo.rs for now until rust-lang/rust#18807 is fixed - silence rust compiler warnings
@shepmaster: yes I'm seeing that on Linux as well now:
Linux version: I started with the second example in of no stdlib but needed to remove |
Confirmed; I hit this today when building a minimal cdylib library intended for calling from C. The |
This commit fixes a longstanding issue with the compiler with circular dependencies between libcore and libstd. The `core` crate requires at least one symbol, the ability to unwind. The `std` crate is the crate which actually defines this symbol, but the `std` crate also depends on the `core` crate. This circular dependency is in general disallowed in Rust as crates cannot have cycles amongst them. A special exception is made just for core/std, but this is also unfortunately incompatible with how GNU linkers work. GNU linkers will process undefined symbols in a left-to-right fashion, only actually linking an rlib like libstd if there are any symbols used from it. This strategy is incompatible with circular dependencies because if we otherwise don't use symbols from libstd we don't discover that we needed it until we're later processing libcore's symbols! To fix this GNU linkers support the `--start-group` and `--end-group` options which indicate "libraries between these markers may have circular dependencies amongst them. The linker invocation has been updated to automatically pass these arguments when we're invoking a GNU linker and automatically calculate where the arguments need to go (around libstd and libcore) Closes rust-lang#18807 Closes rust-lang#47074
…oerister rustc: Group linked libraries where needed This commit fixes a longstanding issue with the compiler with circular dependencies between libcore and libstd. The `core` crate requires at least one symbol, the ability to unwind. The `std` crate is the crate which actually defines this symbol, but the `std` crate also depends on the `core` crate. This circular dependency is in general disallowed in Rust as crates cannot have cycles amongst them. A special exception is made just for core/std, but this is also unfortunately incompatible with how GNU linkers work. GNU linkers will process undefined symbols in a left-to-right fashion, only actually linking an rlib like libstd if there are any symbols used from it. This strategy is incompatible with circular dependencies because if we otherwise don't use symbols from libstd we don't discover that we needed it until we're later processing libcore's symbols! To fix this GNU linkers support the `--start-group` and `--end-group` options which indicate "libraries between these markers may have circular dependencies amongst them. The linker invocation has been updated to automatically pass these arguments when we're invoking a GNU linker and automatically calculate where the arguments need to go (around libstd and libcore) Closes #18807 Closes #47074
Here's a minimal code example that reproduces the error:
And part of the error:
Version:
This also happens on the x86_64 nightly
The text was updated successfully, but these errors were encountered: