Search code examples
rustrust-cargo

How to detect if some function is available in a library at configuration time?


Some libraries exposes functions and types inconsistently depending on the target platform. Notably libc and nix does that.

How do I detect at configuration time if some function, like libc::mmap64 or libc::posix_fallocate is made available by the crate?

I understand I can't #[cfg()] based on a const value exported by the library, nor the library can export a configuration option up to the user. I guess I would have to use build.rs to detect it, but I am not sure how.


Solution

  • RFC #2523 specified a notation #[cfg(accessible(path))], that can be used to do something like you want (amongst other things): #[cfg(accessible(libc::mmap64))] will be on only if libc::mmap64() is, well, accessible.

    However, this RFC is not completely implemented at this time. Namely, the part of #[cfg(accessible)] is not, due to technical difficulties.

    However, PR #69870 implemented something similar: #[cfg_accessible(path)].

    However, as per my testings I'm not sure it actually works for this case, and also, it cannot be combined with cfg operations - meaning e.g. it cannot be negated: you cannot implement some logic for when something isn't available.

    So, your best bet is to #[cfg()] for the platforms this is implemented on. This is what everyone does.