rust-bindgen generate from C macro
I want to generate corresponding Rust macro definitions from C language macro definitions, input C header as follow:
// test.h
enum { FRAME_TYPE, FRAME_TYPEP, FRAME_LUA };
#define frame_type(f) ((f) & FRAME_TYPE)
Run bindgen command:
$ bindgen ./test.h --default-enum-style moduleconsts --no-layout-tests --no-derive-default --use-core --ctypes-prefix ::aya_ebpf::cty --generate functions,types,vars,methods,constructors,destructors --no-doc-comments --no-prepend-enum-name --rust-target 1.82.0 --clang-macro-fallback -- -Wno-unknown-attributes
Output rust as follow:
/* automatically generated by rust-bindgen 0.71.1 */
pub mod _bindgen_ty_1 {
pub type Type = ::aya_ebpf::cty::c_uint;
pub const FRAME_TYPE: Type = 0;
pub const FRAME_TYPEP: Type = 1;
pub const FRAME_LUA: Type = 2;
}
The expectation is to have the frame_type macro definition.
Here is the related issue:
https://github.com/aya-rs/aya/issues/1128
https://github.com/aya-rs/aya/pull/1129
The expectation is to have the frame_type macro definition.
What do you mean by "macro definition"? A Rust macro? A const fn? i.e. please post the expected Rust code you would like to see generated.
The Clang macro fallback linked above is (so far, and as far as I always understood it) intended to resolve macros that evaluate to a constant, not to generate code for arbitrary macros.
This would be closer to a --wrap-static-fns but for macros.
Cc @jbaublitz
Generating corresponding Rust code from C language macro definitions would be sufficient, whether as Rust functions or Rust macros.
This approach would be better for C projects that involve numerous macro definitions.
Like this:
#define frame_type(f) (frame_ftsz(f) & FRAME_TYPE)
#define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP)
#define frame_islua(f) (frame_type(f) == FRAME_LUA)
#define frame_ftsz(f) ((ptrdiff_t)(f)->ftsz)
#define frame_pc(f) ((const BCIns *)frame_ftsz(f))
#define frame_prevl(f) ((f) - (1+LJ_FR2+bc_a(frame_pc(f)[-1])))
#define bc_a(i) ((BCReg)(((i)>>8)&0xff))
Generating corresponding Rust code from C language macro definitions would be sufficient, whether as Rust functions or Rust macros.
That would be very useful indeed (even if only for a small subset of cases) -- please see https://github.com/rust-lang/rust-bindgen/pull/2369.
Hi @ojeda, is this something that would be considered another desired feature for Rust for Linux?
I think in general a tool that would automate some of these would be quite useful for some projects, e.g. in Linux we already had to rewrite ioctl macros (like _IOC(dir,type,nr,size), e.g. see rust/kernel/ioctl.rs).
However, it is non-trivial (it gets closer to a transpiler), and especially with macros, since there may be different potential useful solutions for each macro depending on the use case (how they are called).
For instance, for a f(x) macro that expands to x * 2, cmacro (used in the PR) converts it (from a quick look to its tests, Cc @reitermarkus) to a Rust macro doing exactly the same syntax-wise. However, in some use cases the user may be interested in reproducing particular semantics of C types (e.g. wrapping for unsigned integers, i.e. not expecting a panic), rather than actually using Rust's * operator as-is. One could pass Rust types that mimic behavior for those operators, I guess, but in many cases a const fn with particular types, or possibly generic, may make more sense.
So it is possible extra input/information/context from the user may be needed to decide. Perhaps this is the sort of problem where such a tool is best used to get potential solutions and then the developer picks and adapts the right one.
So you're suggesting actually converting from C macros to Rust macros?