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
Building cdylibs and plugins with cargo #8628
Comments
|
Here's some of the behaviour I'd expect for these type of crates, compared to the current behaviour of lib and bin crates:
The last two columns are very similar. So this suggests that the answer to question 1 and 2 would be that a new |
|
After thinking about this a bit more, I think the best way forward is indeed a new section in the toml, something like Other than some bikeshedding about the exact name ( So I propose adding
Special linker flags (e.g. I can work on implementing this, but would first like some confirmation from the Cargo team that this change would be acceptable/wanted. |
|
@m-ou-se Thank you for working on this. What you describe satisfies my use case almost perfectly. One other thing to consider is what happens with
|
|
This is a great feature, and it covers a lot of use cases. Some i can think of now: 1. Creation of plugins to be consumed by other languages/applications.As already said, the ability to use a library made with rust in other environments is very welcome, I've seen several similar issues, and I'm interested in it myself. One problem I encountered was making a plugin system, where a library exports an extern "C" function to get a pointer to the plugin. This works perfectly with a cdylib, through dynamic loading, however if the plugin is statically linked as an rlib, the function name collides when linking, as noted: That way we could concentrate the plugin code, being able to have an api usable as a normal rust lib, and allowing external use through the dynamic library. 2. The possibility of having more than one cdylib per package.More or less related to the previous topic. This possibility would be interesting, for reusing the code of the main lib, and having variations in multiple cdylibs, without the need to create another package. An example of these variations would be how it is done in Unreal Engine, where it is possible to have more than one "module" per project. These modules are nothing less than a dynamic library. If I think of any more pertinent cases I'll add them here later. And it would be nice to know the opinion of more people, each person has different experiences and can come up with amazing ideas |
|
While this functionality doesn't go forward, I'm using an [[example]], as it's the only way to create multiple cdylibs. It's not ideal, but for now it works. I've been looking into the cargo source code, to see if I could help. |
|
I just remembered I actually implemented this a while ago. I've just not been able to test any of it yet. (And there's probably a bunch of things to clean up and fix.) I'll try to find some time to dig it up and send it as a PR to get this thing going. |
|
Is there any follow-up to this issue? |
There's a few open issues related to building plugins for other software (as cdylibs) with cargo. With this issue I want to summarize them and try to work to a single solution.
The use case
Software like Python, PostgreSQL, and many others can dynamically load plugins. These plugins are dynamic libraries (i.e.
cdylibsin Rust, aka .so/.dylib/.dll files) with certain symbols exposed. We're looking here at making such plugins using Rust.The problems
[lib]or[[bin]]crates.[[bin]]s cannot becdylibs, but a package can currently only contain one[lib]. These plugins will not be 'consumed' by other Rust crates as dependencies, so this limitation is unnecessary for this type of crate. #6351cdylib[lib]is not made available to integration tests to test. #8311 #7152 #8193required-features = ..is ignored for[lib].lib{cratename}.so, even though it might need to be something like{cratename}.plugin,python-{cratename}.pyd, etc. #1706 (comment)-Clink-arg=-undefined=dynamic_lookupon Mac. It might also require not depending on a library that a regular bin target should depend on. #5881[lib]crate will be linked into the[[bin]]crates: dependencies frombuild.rsare added to the[lib]crate but not the[[bin]]crates, to avoid duplicate symbols. Plugin crates should not be linked into[[bin]]crates. #7506Package::include_lockfile(). This is done for examples and binaries, but not for libraries.cdylibs by default, andbintargets don't handle thread locals in a way that they can be loaded into other binaries. (Probably not a cargo issue.)Possible solutions
#6351 suggests allowing
crate-type = ["cdylib"]for[[bin]]s. Although these type of crates share some properties with[[bin]]crates, there's also properties they do not share: Binaries should be installed withcargo install, but plugins should probably not (or at least not into /usr/bin). Binaries have their private items documented by default (as they have no public items), but plugin crates do have public items. Binaries can be run bycargo run, but these should not.#6351 (comment) suggests adding a new
[[clib]]instead. This would be a much bigger change to cargo, as the set of target types (lib, bins, examples, tests, benches) are used in a lot of places (including command line flags).Questions
Is a 'plugin' fundamentally different from a binary? Should they be
[[bin]]s, or do they need more special treatment?If not
[[bin]]s, are they fundamentally different from othercdylibs? Would a[[clib]]work for both plugins and other type of dynamic C libraries? Or does it need a separate[[cplugin]]orcplugin = trueinCargo.tomlto be handled correctly?Should 'cdylibs with an entry point' be supported? If so, as "libraries that also have an entry point" (e.g.
[[clib]] also_bin = true), or as "binaries that are also loadable" (e.g.[[bin]] export_stuff = true)?Probably more questions?
The text was updated successfully, but these errors were encountered: