Michael-F-Bryan / rust-ffi-guide

A guide for doing FFI using Rust
https://michael-f-bryan.github.io/rust-ffi-guide/
Creative Commons Zero v1.0 Universal
282 stars 18 forks source link

Primes Cargo.toml not referenced and crate-type not explained #37

Closed gurgalex closed 7 years ago

gurgalex commented 7 years ago
gurgalex commented 7 years ago

What is the difference between a dynamic system library and dynamic Rust library? My guess would be that cdylib exposes the extern C functions so that other languages can call into them. The standard dylib may not do that.

Michael-F-Bryan commented 7 years ago

As far as I know, a dynamic system library (usually *.so or *.dll - corresponding to the cdylib crate-type) is a PE or ELF binary file which follows a well-defined format that your linker can use when stitching together binaries and resolving symbols to make your final compiled executable. You can think of it as a binary containing a bunch of symbols pointing to chunks of executable machine code.

A rlib on the other hand is the Rust compiler's way of representing a compiled artefact, usually a crate. It's completely implementation defined and not meant to be used by anyone other than rustc, although from memory it's pretty much just a standard archive like what you'd get from the ar tool (think of it as a collection of normal object files merged into a single file). Presumably, the rlib could contain Rust-specific information about a crate and not just the compiled code for functions. So stuff like trait definitions, impl blocks, or even some serialized version of MIR.

I'm assuming a dylib is just a version of rlib which can be dynamically linked instead of containing the code for all its dependencies like the static rlib.

I believe you can technically use a rlib in place of a normal object file or archive (*.a) and compile it into your C/C++/whatever programs. However because the rlib format is purposefully not specified and has no stability guarantees, the compiler team reserve the right to change it if they want to.

skade commented 7 years ago

The difference is that Rust dylibs still contain additional Rust metadata (such as the MIR of not-yet specialized generic functions and public traits and such). That might trip some code assuming specific layout (I think I've seen unloading such a lib segfault on OS X) and obviously leads to some bloat. cdylib removes all Rust metadata.

See the RFC for some glimpses (sadly, it's not very detailed). https://github.com/rust-lang/rfcs/blob/master/text/1510-cdylib.md

The RFC uses rdylib and cdylib as a distinction.