-
Notifications
You must be signed in to change notification settings - Fork 440
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
Rust link arguments are not passed transitively to dependant rust targets #78
Comments
Afaiu #61 handles the build step on osx, but doesn't correctly set the rpath. You can try commenting out compute_rpaths from the pr branch (I don't have a mac to test on) to get it to build, then using LD_LIBRARY_PATH to get it to run. At this point we should be asking @mhlopko for advice on not reinventing cross platform dylib linking, in the context of the cc Skylark project. (I have no idea if collecting link args is a generally correct thing to do.) |
@mfarrugi Just to clarify, the linked repro case also doesn't link on Linux for me without commenting in the |
On the PR branch? If so, I'll take a look as transitive dylibs ought to be handled. |
Do you happen to know off hand what Cargo's current treatment of If it is indeed an oversight, we'll probably need to promote this flag to a rule-level attr so that the transitives can be tracked. |
@mfarrugi I will try next week. |
I think you'll eventually want to have transitive linkopts-like attribute on rust_library anyway. It is true though that it could be emulated by
but this cannot be implemented currently because we would need bazelbuild/bazel#4570 to be implemented. |
I've been dealing with the same issue, which shows up immediately once you try writing Rust bindings to a C++ library. The way I've tried to go about this is by writing C API wrapper ( In other words, I have a dep chain that looks like this: From the digging I've done so far into how the cc rules and rust rules work, it seems there is a conceptual impedance mismatch with how things are implemented right now.
There are actually two errors that I see here. Fixing these should bring the Rust rules conceptually in line with what the cc rules do:
Does that logic seem correct? I'm particularly curious what you think, @mhlopko. |
@bobsomers is right. I actually have a failure mode right now that is not properly handled by the way rust rules are currently linking. I have a So the rust rules must not link everything until the binary level, just as bazel does for c++. |
Quick update: I have the transitive linking issues mostly fixed. I still need to fix up the conflicting rlib name example, but otherwise you can properly transitively link as I described above. I have an example that produces a The solution is mostly orthogonal to #61, so merging this transitive fix with shared library support should be doable. If anyone wants to play around with it while I fix the last few things and get it ready for a PR, here's my branch: https://github.com/bobsomers/rules_rust/tree/transitive_linking The example of interest is |
Cc_library actually doesn't necessarily do any linking (when using gold linker we only compile to objects and then link everything in cc_binary with --start-lib a.o b.o c.o --end-lib). The main reason for "underlinking" is to make the build not so quadratic. Imagine we have this dep graph: bin -> liba -> libb -> libc. When we change libc, ideally we won't have to rebuild liba and libb. Ideally we wouldn't have to relink everything even in the binary, but that's how C++ works so meh. Plus the diamond problem as @SirVer mentioned is a chapter on its own. So if we can, we should make rust_library to be a bunch of objects, or a static archive at most. |
@bobsomers was there anything we need to make you patch work? |
@GregBowyer It probably needs to be rethought now that Bazel has redesigned how C++ toolchains work. I haven't had the time to get up to speed on the new toolchains or work on this due to a new infant at home. |
is there any short term solution for this problem? |
Humm is there a test case, this might be solved by #217, if not it might not be terribly hard to support excluding WASM |
at least for me this is the issue #264 |
This is not just a problem for Bazel. I've seen it for two different FFI libraries, where the C library is underlinked. rust -> libpmc.so -> libc++.so In both cases, specifying the transitive dependency in build.rs is insufficient; Rust binaries only link to the direct dependency. |
I found a solution when using Cargo. You need to pass the println!("cargo:rustc-link-lib=dylib:-as-needed=zutil"); https://rust-lang.github.io/rfcs/2951-native-link-modifiers.html |
Does #849 address the issues reported in this issue? |
That and a bunch of other changes we made over the course of 2021. Can somebody try with the latest rules to see if it is still a problem? If yes, could you share a tiny reproduction case? Is the problem occuring on Linux or also on other platforms? In any case I feel like we made a lot of progress - we are building some mixed Rust / C++ binaries internally and everything seems to be working, and I expect that the problem mentioned in thiss issue is either fixed, or is not reproducible on Linux (we don't do Windows or Darwin builds). |
There's a problem with rust pkg-config (cargo-raze?) and OS X. But locate libpulse-simple.0.dylib
/usr/local/Cellar/pulseaudio/14.2/lib/libpulse-simple.0.dylib
/usr/local/lib/libpulse-simple.0.dylib |
I think it does (at least, I have successfully had linker arguments passed from a However, in one particular edge case (
Stated differently: the assumption in A workaround is to manually add the target that is listed in |
I believe 1 is not part of the problem; although we collect the deps in a depset, we flatten the depset here: https://github.com/bazelbuild/rules_rust/blob/main/rust/private/rustc.bzl#L207. |
Simple repro case is in this branch.
bazel run @examples//hello_world
exposes the problem.The example is a simple dependency chain:
rust_binary
("hello_world") depends onrust_library
("hello_from_c_sys") which depends oncc_library
("hello_from_c"). The c library requires c++, therefore needs linking with-lstdc++
. It should be sufficient to specify this in therust_library
rule, but right now allrust_binary
rules that transitively depend on the lib need to specify it as well: https://github.com/bazelbuild/rules_rust/compare/master...SirVer:link_example?expand=1#diff-e85472ad14a7cde9a8510d9beae332c5R18The text was updated successfully, but these errors were encountered: