-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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 a static native library to a dynamic rust library doesn't necessarily actually link #15460
Comments
Should retitle to indicate that it's not just about static native libraries. |
In your test case you are using This is not a problem using dynamic libraries through the |
Given that |
As discovered in rust-lang#15460, a particular #[link(kind = "static", ...)] line is not actually guaranteed to link the library at all. The reason for this is that if the external library doesn't have any referenced symbols in the object generated by rustc, the entire library is dropped by the linker. For dynamic native libraries, this is solved by passing -lfoo for all downstream compilations unconditionally. For static libraries in rlibs this is solved because the entire archive is bundled in the rlib. The only situation in which this was a problem was when a static native library was linked to a rust dynamic library. This commit brings the behavior of dylibs in line with rlibs by passing the --whole-archive flag to the linker when linking native libraries. On OSX, this uses the -force_load flag. This flag ensures that the entire archive is considered candidate for being linked into the final dynamic library. This is a breaking change because if any static library is included twice in the same compilation unit then the linker will start emitting errors about duplicate definitions now. The fix for this would involve only statically linking to a library once. Closes rust-lang#15460 [breaking-change]
As discovered in #15460, a particular #[link(kind = "static", ...)] line is not actually guaranteed to link the library at all. The reason for this is that if the external library doesn't have any referenced symbols in the object generated by rustc, the entire library is dropped by the linker. For dynamic native libraries, this is solved by passing -lfoo for all downstream compilations unconditionally. For static libraries in rlibs this is solved because the entire archive is bundled in the rlib. The only situation in which this was a problem was when a static native library was linked to a rust dynamic library. This commit brings the behavior of dylibs in line with rlibs by passing the --whole-archive flag to the linker when linking native libraries. On OSX, this uses the -force_load flag. This flag ensures that the entire archive is considered candidate for being linked into the final dynamic library. This is a breaking change because if any static library is included twice in the same compilation unit then the linker will start emitting errors about duplicate definitions now. The fix for this would involve only statically linking to a library once. Closes #15460 [breaking-change]
Hi there, sorry to re-open this many years after, but I can reproduce this on 1.47 stable and 1.48 nightly with the repository found here: https://github.com/Firstyear/demo_r_link Using cargo build then inspecting the resulting .so, "wrapper_add" is not present. Using the linking trick from @steveklabnik's closed issue can force symbols to be included from the static archive. This is using cc and cbindgen, so this "should work". Any advice would be most appreciated. |
@Firstyear in general, especially with a bug this old, it's better to open a new issue, and mention this one in it. A lot has changed since 2014 and most of the details here won't be relevant. |
The problem is that if the dynamic library doesn't actually reference any symbols from the native library then the native library is stripped from the command line.
Possible solutions
-Wl,--as-needed
-Wl,--whole-archive
for immediately dependent static libraries#[link(kind = "static")]
, generate a reference to all symbols in the extern block to force the library to be linked. (in some sort of 0-cost manner)The text was updated successfully, but these errors were encountered: