I want to make -sys crates for a few C libraries, however I’m stuck due to the number of different ways of handling various aspects of it.
First, it’s pretty clear that I want to be using bindgen to automate most if not all of the code creation. Should I call it from
build.rs of my crate, or should I pre-generate bindings myself and publish the complete set of
.rs files to save users from a libclang dependency that isn’t yet of the required version on some Linux distributions (see this issue) or that could be an additional pain to install on Windows?
How should I handle versioning? Should I depend on a specific version of the library and fail if the version is wrong, should I always support and generate bindings to whatever version is present on the user’s system exposing the differences through Cargo features (like ffmpeg-sys), or maybe create different versions of the crate for different library versions and publish them as separate crate versions (like llvm-sys)? I know that some distributions have older versions of the library than I do so support for that is desired.
How should I find the library sources and the object file to link against? pkg-config is an obvious choice, but that doesn’t work on Windows, and a way of manually specifying the library folder is often desired (an example is older versions of the openssl-sys crate needing a manual override because the system library is too new or vice versa). Should I fall back to downloading and building the library from source if all other methods fail? Perhaps only when the user specifically asks for it (if they just don’t have the library installed yet they might want to get a heads up and use their package manager instead of the crate deciding to compile the library right away)? How do I handle library compile dependencies and different possible library feature flags in this case?
Should the crate link to the library statically or dynamically? Static linking often means having to build the library from source to get the required object files. What if some user of my crate wants to dynamically load the library at runtime and obtain the function pointers this way, like is frequently done with OpenGL? Is there a way to support that use case without having to write two separate crates with essentially the same code?
I wish there was a single good way when it comes to building -sys crates but so far it seems to me like everyone’s doing it in their own ways with various advantages or disadvantages to each.