-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
How should dynamic linking work in Rust? #3573
Comments
Note that the current behavior exists for backwards compatibility at this point. Long ago a cdylib didn't exist so the only way to create a dynamic library was through the dylib crate type, so Cargo must preserve the current behavior today. That diamond dependencies don't work is a bug (rust-lang/rust#34909) and it should be fixable at any time really. The use case for dynamic libraries in Rust has basically never been gamed out. As a result a bug like this is likely much broader in terms of "how should dynamic linking work in Rust" at all. I don't think that just building a bunch of dylibs will solve the real problem at hand, so this seems unlikely to be a quick bug fix in Cargo. |
@alexcrichton, you said in your other comment:
I'm sorry if this is the wrong spot to ask and I'll be happy to move this discussion somewhere else if necessary, but if you use The problem with What if Rust provided a way to automatically create direct "C" bindings for a Rust crate, not with the intention of having C programs link to it, but with the purpose of giving Rust a stable ABI over which to dynamically link other Rust crates. For example, there could be:
If you build a crate as an As far as the developer is concerned, they don't have to manually create any bindings, and they can now safely dynamically link to other Rust libraries. The motivation for this is the desire to be able to create a Rust plugin interface. I've attempted a tutorial which is based on using Anyway, I would appreciate your thoughts on the subject as I think that dynamic linking would be really helpful to me if there was a way to get it to work. If there is already a way to do this without changes to Cargo or Rust that I'm not aware of, that would be great. 🙂 |
Another thought is that you might be able to implement this without modifying In a similar manner, you could create a macro for importing the crate that would expand to all of the extern blocks necessary to link to it. That would be a good way to prove out the concept. |
For designing a system of official supported dynamic libraries in Rust I'd recommend the internals/users forum rather than an old issue on the Cargo issue tracker. It's likely to definitely need rustc changes and require an RFC eventually. |
How should I do with cargo if I really want to build every dependencies with |
I don't think you can have it build every crate as a dylib. I think that will just dynamically link the standard library with Here is some perspective that might help a little: https://users.rust-lang.org/t/what-is-the-difference-between-dylib-and-cdylib/28847/3?u=zicklag |
@zicklag thanks for kindly reply. Maybe now cargo doesn't support make |
Ah, yes, those are pretty much the reasons that I tried to figure out how to use dylib. I create a tutorial based on my attempts to get that working and you're welcome to check it out, but I pretty much decided it probably wasn't going to work well enough. I'm not sure if it will end up helping you or not. I know that the bevy engine had dynamic plugin loading at one point, but I don't know how it worked. Also take a look a ABI Stable Crates which might be your best bet. |
I have an idea for how dynamic linking should work but I have no idea if it is even feasible because I have no idea how dynamic linking works. The ultimate version of this might look like downloading a super small executable which when run looks for specific dependencies on the system and downloads them if they don't exist. |
It would be great to have at least for debug builds an option to compile all the dependencies as dynamic libs, when you have a lot of dependencies the linking time is horrible for the minimal change |
If I set
crate-type=["dylib"]
inCargo.toml
, I would expect it to not only compile the top-level crate as dynamic, but also all its transitive dependencies, and link with them dynamically (ie, with-C prefer-dynamic
semantics).Right now if you try this, it builds all the dependencies as static, and statically links them into the dynamic crate it builds. If this dynamic crate is subsequently used to build an executable with a diamond dependency graph (ie two of its dependencies have the same transitive dependency), rustc fails because of the crate that's duplicated by being linked into two other dynamic crates. This happens most often with
libstd
, but it can happen with any shared dependency. This suggests that the default for any dynamic crate should be "prefer dynamic" for its dependencies, since the current default is only useful in very niche cases.If you specify
-C prefer-dynamic
as a build flag, then it will not include the dependent crates in the dynamic output - but it also won't build the dependencies at all.Further, if you specify
crate-type=["dylib", "rlib"]
, I would like it to build the crate twice as static and dynamic (this does work currently), and all its dependencies (this does not).Related: #3408
The text was updated successfully, but these errors were encountered: