Thanks for writing up a detailed ticket @ryankurte. I've done quite a lot of work with FFI and by far the most annoying step in making a
*-sys crate is getting the thing to build reliably.
I follow a process quite similar to @kornelski's Making a *-sys crate article and it works fairly well.
bindgen outputs often do not match target architecture sizes
- tooling should build bindgen at compile time, with appropriate target arguments
- guide should specify that bindgen should be run at compile time
I can understand the appeal in running
bindgen at compile time, but I'd prefer to avoid it if possible. Adding a direct dependency on
bindgen means anyone wanting to use your crate will need to either have
libclang on their system, and given how
*-sys crates tend to be very deep in the dependency graph it means it'll affect a lot of crates.
As an alternate proposal, what if you could tell
bindgen to emit bindings for a selection of targets use conditional compilation to enable/disable items? It'd mean bindings files get significantly longer, but consumers now no longer need
libclang and the associated hassles when building or additional compile time.
Package discovery, compilation (and linking) typically doesn't work cross platform
This is a big one, but it's a bit too interrelated to easily split.
Package discovery is another can of worms entirely. The problem is that the various platforms each have their own way of installing something or reusing libraries.
For example, in Windows you'll often bundle the libraries you need with your program because there's no central, consistent place to store DLLs. *nix platforms use a package manager which will typically store system libraries in some sort of
/lib directory, setting things up so version conflicts are avoided.
About the only way you're going to get a consistent experience is if you compile from source during the build process, because then you've got access to any dynamic or static libraries you need.
Also, keep in mind there's only so much you can do from the Rust side. Unfortunately, C/C++ build systems are a massive mess and were designed before things like cross-platform and package managers became ubiquitous, so you've got an uphill battle ahead of you...
cmake and git submodules make things considerably easier, but even then it's nowhere near as seamless as