rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

No bindings generated for macros using enums in bitshifts

Open cmazakas opened this issue 1 year ago • 5 comments

liburing will define macros as such:

enum io_uring_sqe_flags_bit {
	IOSQE_FIXED_FILE_BIT,
	IOSQE_IO_DRAIN_BIT,
	IOSQE_IO_LINK_BIT,
	IOSQE_IO_HARDLINK_BIT,
	IOSQE_ASYNC_BIT,
	IOSQE_BUFFER_SELECT_BIT,
	IOSQE_CQE_SKIP_SUCCESS_BIT,
};

/*
 * sqe->flags
 */
/* use fixed fileset */
#define IOSQE_FIXED_FILE	(1U << IOSQE_FIXED_FILE_BIT)
/* issue after inflight IO */
#define IOSQE_IO_DRAIN		(1U << IOSQE_IO_DRAIN_BIT)
/* links next sqe */
#define IOSQE_IO_LINK		(1U << IOSQE_IO_LINK_BIT)
/* like LINK, but stronger */
#define IOSQE_IO_HARDLINK	(1U << IOSQE_IO_HARDLINK_BIT)
/* always go async */
#define IOSQE_ASYNC		(1U << IOSQE_ASYNC_BIT)
/* select buffer from sqe->buf_group */
#define IOSQE_BUFFER_SELECT	(1U << IOSQE_BUFFER_SELECT_BIT)
/* don't post CQE if request succeeded */
#define IOSQE_CQE_SKIP_SUCCESS	(1U << IOSQE_CQE_SKIP_SUCCESS_BIT)

bindgen fails to generate these constants, because it doesn't seem to handle the case where an enum is being used

The macros are correctly generated if the enums are removed and replace with integer literals

cmazakas avatar Oct 16 '24 20:10 cmazakas

what happens if you use the clang macro fallback?

pvdrz avatar Oct 16 '24 20:10 pvdrz

what happens if you use the clang macro fallback?

lmao dumb question, but how would I do that? I'm actually kind of a noob at bindgen.

cmazakas avatar Oct 16 '24 20:10 cmazakas

--clang-macro-fallback if you're using the CLI or .clang_macro_fallback() if you're using the library.

pvdrz avatar Oct 16 '24 20:10 pvdrz

Hmm, this seems like it'll make rust-analyzer happy but now my code fails to generate bindings with:

error[E0428]: the name `MSG_OOB` is defined multiple times
    --> /home/exbigboss/rust/fiona/target/x86_64-unknown-linux-gnu/release/build/fiona-ce644692b051eae2/out/liburing_bindings.rs:1905:1
     |
288  | pub const MSG_OOB: u32 = 1;
     | --------------------------- previous definition of the value `MSG_OOB` here
...
1905 | pub const MSG_OOB: _bindgen_ty_1 = 1;
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MSG_OOB` redefined here
     |
     = note: `MSG_OOB` must be defined only once in the value namespace of this module

My build.rs has:

    let bindings = bindgen::Builder::default()
        .clang_macro_fallback()
        .clang_args(
            liburing_pkg
                .include_paths
                .iter()
                .map(|path_buf| format!("-I{}", path_buf.to_str().unwrap())),
        )
        .clang_arg("-std=c11")
        .clang_arg("-D_POSIX_C_SOURCE=200809L")
        .header("include/liburing_wrapper.h")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

with a liburing_wrapper.h:

#pragma once

#define IOURINGINLINE
#include <liburing.h>

cmazakas avatar Oct 16 '24 20:10 cmazakas

That happens thanks to this beautiful piece of C in sockets.h:

/* Bits in the FLAGS argument to `send', `recv', et al.  */
enum
  {
    MSG_OOB		= 0x01,	/* Process out-of-band data.  */
                                /* ... and more */
  };

My best fix for it so far has been to block all the items that start with MSG_ using --blocklist-item="MSG_.*"

pvdrz avatar Oct 17 '24 14:10 pvdrz