Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rust-bindgen generate from C macro #3065

Open
cppcoffee opened this issue Jan 3, 2025 · 6 comments
Open

rust-bindgen generate from C macro #3065

cppcoffee opened this issue Jan 3, 2025 · 6 comments

Comments

@cppcoffee
Copy link

cppcoffee commented Jan 3, 2025

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:

aya-rs/aya#1128

aya-rs/aya#1129

@ojeda
Copy link
Contributor

ojeda commented Jan 3, 2025

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

@cppcoffee
Copy link
Author

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))

@ojeda
Copy link
Contributor

ojeda commented Jan 3, 2025

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 #2369.

@jbaublitz
Copy link
Contributor

Hi @ojeda, is this something that would be considered another desired feature for Rust for Linux?

@ojeda
Copy link
Contributor

ojeda commented Jan 6, 2025

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.

@jbaublitz
Copy link
Contributor

So you're suggesting actually converting from C macros to Rust macros?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants