Currently, cfg attributes are passed in via flags to rustc; however, I believe that there is also a case for crates exposing CFG attributes as well.
eventfd is a function that is available on Linux as of 2.6.27. Rust supports Linux as of 2.6.18, so in order to write crates that are compatible with all platforms that Rust supports, it is not possible to assume the presence of
The nix crate provides the bindings to more advanced *nix platform APIs. The nix crate would have a
build.rs script that would feature detect whether
eventfd is present on the system (though, in practice, it would also allow the user to opt out even if it is present), and conditionally expose the
eventfd binding if it is available.
The problem is that, mio would like to use
eventfd if it exists, but has no way of knowing whether or not
eventfd has been defined.
Cargo features are not a solution to this problem since the availability of
eventfd is not opt-in by the user, but detected based on the system. Also, cargo features must be “re-exported” by each dependency where as, this case is really an environmental concern: does
eventfd exist on the target platform.
What I propose is for crates to be able to expose attributes that are usable by dependencies via the CFG system.
For example, in the nix crate, I could do the following:
#[cfg(has_event_fd)] // detected by builders attribute event_fd = "yes";
Then, in the mio crate, I could do the following:
extern crate nix; #[cfg(nix::event_fd)] // use eventfd #[cfg(not(nix::event_fd)] // fallback on using a self pipe strategy
Another option that wouldn’t require a keyword could be to annotate a constant. In the nix crate again:
#[attribute = "event_fd"] const HAS_EVENTFD: &'static str = "yes";
I’m not sure what the best way to “export” attributes from a crate would be and am hoping to get community feedback!