I'm in the process of writing bindings to Pugl, a graphics library that supports OpenGL and Cairo backends. Pugl's maintainer requests that distributors provide a separate package for each backend to keep dependencies to a minimum, which seems reasonable. However, this seems to be an awkward fit for the structure of crates; I'm not sure how I could accommodate Pugl's preferred distribution approach without duplicating my build code and/or forcing users to build Pugl repeatedly.
Pugl is only provided as source, and its build script (which uses Waf) builds a platform-specific core library and two backend libraries, one for each backend, provided that OpenGL and/or Cairo development libraries are present on the host. The way it does this is involved enough that I'd rather use it directly than try to copy it with cc or something.
Here are the possible strategies I see for setting up crates around this library, none of which seem ideal:
- Separate pugl-sys, pugl-cairo-sys, and pugl-gl-sys crates, each mapping onto one of the three libraries that Pugl builds. Users would depend on either pugl-cairo-sys or pugl-gl-sys, which in turn would each depend on pugl-sys. This allows for keeping all the dependencies separate (i.e. pugl-cairo-sys could bring in cairo-rs and the others could leave it out). It also allows the bindings for the core library and both backend libraries to be maintained in one place each. However, it would force users to build Pugl twice when installing the crates and would require duplicating the same build.rs across all three crates.
- Two crates, pugl-cairo-sys and pugl-gl-sys. This allows users to run the build once and get the whole library as they want it, and keep dependencies for each backend separate. However, it would require duplicating the bindings for the core library across both crates, as well as the build.rs.
- One crate, pugl-sys. This would link the core with both backends and bring in dependencies for both OpenGL and Cairo, going against the wishes of the Pugl maintainer and adding bloat and complexity to projects depending on pugl-sys. However, it would be the easiest to maintain and install, allowing for one build.rs, one set of bindings, and one build process.
The situation gets further complicated when you consider building Rust-friendly Cairo and OpenGL frontends to the -sys crates.
What should I do here? Is there a better solution I haven't considered, or a way around the problems I've brought up? Linux distros often provide some way to do a "split package" or the like for cases like these, where one build script and one set of sources can be used to generate multiple packages. Cargo doesn't seem to support that kind of approach, but I'm still new to Rust, so maybe there's something I'm missing.