4

I'm aware that the libc crate in Rust contains much of C's standard macros and functions for use in Rust, but it also states that it is not concerned with portability between systems. I'm porting some code that uses C's preprocessor macros extremely heavily from C to Rust, and only includes some code if a given macro is defined: in this case O_BINARY. Is it possible to check whether the O_BINARY macro is defined on my system in Rust, and if so, what does this look like?

I'm looking for a construct that can replicate this C syntax rather closely:

#ifdef O_BINARY
// Some extra code here
#endif
// Regular code
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
wfehrn
  • 105
  • 1
  • 11
  • You could just run your Rust code through the C preprocessor before compiling. This is basically what Haskell devs do when they want C-style preprocessing. Whatever C compiler you use surely has a setting to *just* run the preprocessor. – Silvio Mayolo Jul 07 '19 at 23:14
  • @SilvioMayolo that can't work. Something as simple as `#[derive(Debug)] struct Foo;` would give `a.rs:1:2: error: invalid preprocessing directive #[` using `cpp (GCC) 8.3.0`. – mcarton Jul 07 '19 at 23:39
  • 1
    Have you had a look at rust-bindgen? – mcarton Jul 07 '19 at 23:41

1 Answers1

5

You can run the C preprocessor in a build script and inspect the output. If the macro is defined, we can then pass along a feature flag to the Rust code.

Cargo.toml

[build-dependencies]
cc = "1.0.37"

build.rs

fn main() {
    let check = cc::Build::new().file("src/o_binary_check.c").expand();
    let check = String::from_utf8(check).unwrap();
    if check.contains("I_HAVE_O_BINARY_TRUE") {
        println!("rustc-cfg=o_binary_available");
    }
}

src/o_binary_check.c

#ifdef O_BINARY
I_HAVE_O_BINARY_TRUE
#else
I_HAVE_O_BINARY_FALSE
#endif

Tweak this file as appropriate to find your macros.

src/main.rs

fn main() {
    if cfg!(feature = "o_binary_available") {
        println!("O_BINARY is available");
    } else {
        println!("O_BINARY is not available");
    }
}

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366