I'm playing around with Microsoft's
com-rs crate. I have the following setup:
- COM implementation library - a
cdylib containing COM classes that can be registered.
- COM client - a binary app that makes use of the COM classes.
- COM interfaces library - a common library between the first two containing definitions of GUIDs and COM interfaces.
To maximize reuse, the COM interfaces library is built into a
dylib that is used by both the implementation library and the client. The downside of this solution is that all three depend on std.dll, which is almost 3 MB in size (after stripping).
Now, I realize that Rust doesn't have a stable ABI and for the sake of this sample I assume the three are always being built and redistributed together.
My question is: is there a way to build Rust's std library as a
dylib together with these three crates, so it only contains parts of std that are being used? So, basically, is there a way to build a private copy of std?
I might be able to achieve this with Xargo maybe (any advice here is also much appreciated ) , but I also wonder if there is a way to do so with current or nightly Cargo?
Yes, Xargo allows rebuilding
std. There are instructions available here for building
std from the
rust-src component. Coincidentally, the linked instructions provide details for using link-time optimization to remove the unused parts of
std from your binary via dead code elimination. This only works if
std is statically linked, as the linker will be unable to tell which exports are actually unused in a dynamically linked library.
In general, rust interfaces cannot be safely used across
dylib boundaries, only extern C functions with all
#[repr(C)] types.You can end up with bad behavior even on the same version of rust, from things like different optimization choices for struct layout or different allocators (or different instances of the same allocator). Plus, I don't believe Rust supports any sort of generic interfaces for
Just from this information, I don't believe there is any way to link all of
std as a
dylib. The rust interface just can't be expressed as a dylib interface.
If you're only using limited parts of
std, might I suggest making each user a
#[no_std] application, and making a new interface (either
#[repr(C)] or using
abi_stable) between your crates and a dylib which calls into
If you're using a lot of std though, or generic parts, I don't think it's at all feasible. @parasyte's suggestion of building a custom std with more removal of unused parts might be the best way to trim down size.
@daboross Thank you for the explanation!
If what you're describing is the actual state of things, then I don't get the use of
[dylib] crate type and
-C prefer-dynamic compiler flag. The former allows one to build a Rust dynamic library (as opposed to
cdylib), and the latter links all the dependencies including
@parasyte Thanks for the link, I'll try this out! I was wondering though is it ever going to be included in the stable Cargo code?
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.