I have a Rust cdylib, which contains bindings to a C ffi api (github link, if relevant). This API has several versions, all slightly incompatible with each other. Using cargo features like version1
, version2
, etc has worked well with some downfalls:
- Someone is able to specify more than one version (eg. they want their library to be compatible with
version1
andversion2
, but in reality it's one or the other). - There isn't a default feature, as one of the version features must be selected to compile sucessfully. This causes
cargo package
to fail as there is not a way to communicate "hey package up everything, but for verification let's useversion1
". Usingcargo package --no-verify
feels dirty.
I know that the Mutually exclusive features has already been raised in the cargo repo. Using environment variables in build.rs
was presented, but how is the ergonomics of this approach? I feel like environment variables are treated as second class compared to features. Will end users of my library need a build script (where one wasn't needed previously)? Will I need to extract all my tiny #[cfg(feature = "version1")]
sections into a separate files as (AFAIK) cfg doesn't support environment variables?
Is sticking with features my best bet, should I invest into a build system driven through environment variables, or is there a better solution?