-
Notifications
You must be signed in to change notification settings - Fork 707
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
Functional C macros are not expanded. #753
Comments
How is |
As in... If we don't know how |
That being said, even with that it doesn't work (huh, I'd swear we knew how to deal with macro expansions): #define _IO(a_) (a_)
#define UI_DEV_CREATE _IO(1)
#define UI_DEV_DESTROY _IO(2) |
This is probably a bug for rust-cexpr. Indeed, it's a dupe of jethrogb/rust-cexpr#3. |
I guess I can try to add to libclang a way to get whether the macro definition belongs to a functional macro... |
If it helps any:
|
Ok, so libclang provides a |
I've asked @jethrogb about what the best API for this would be. It shouldn't be a big deal to support it in bindgen once cexpr support is there. |
Meanwhile, I used the following in my wrapper.h to workaround the issue: #include <linux/uinput.h>
const __u64 _UI_DEV_CREATE = UI_DEV_CREATE;
#undef UI_DEV_CREATE
const __u64 UI_DEV_CREATE = _UI_DEV_CREATE;
const __u64 _UI_DEV_DESTROY = UI_DEV_DESTROY;
#undef UI_DEV_DESTROY
const __u64 UI_DEV_DESTROY = _UI_DEV_DESTROY; |
Yeah, note that that would only work in libclang 3.9+ though. |
Current state: C preprocessor needed. @emilio can you add "help wanted" label? |
How about the progress of this? |
@clia The state is unchanged as of my latest comment #753 (comment). This issue is marked "help wanted" and waiting for someone (anyone) to implement this functionality. |
Another workaround preserving original names: wrapper.h#include <linux/ioctl.h>
#include <linux/usbdevice_fs.h>
#define MARK_FIX_753(req_name) const unsigned long int Fix753_##req_name = req_name;
MARK_FIX_753(USBDEVFS_CONTROL);
MARK_FIX_753(USBDEVFS_BULK); build.rs...
#[derive(Debug)]
pub struct Fix753 {}
impl bindgen::callbacks::ParseCallbacks for Fix753 {
fn item_name(&self, original_item_name: &str) -> Option<String> {
Some(original_item_name.trim_start_matches("Fix753_").to_owned())
}
}
fn main() {
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.parse_callbacks(Box::new(Fix753 {}))
.generate()
.expect("Unable to generate bindings");
...
} output bindings.rs...
pub const USBDEVFS_CONTROL: ::std::os::raw::c_ulong = 3222820096;
pub const USBDEVFS_BULK: ::std::os::raw::c_ulong = 3222820098; Seems like this workaround shouldn't conflict with future implementation. |
Not sure if this is the same problem, but I'm having issues getting at It's defined thusly:
Without hacks, it's totally absent from I've tried a few workarounds, including @iDawer's wrapper.h:
build.rs:
bindings.rs:
Notice the value is not expanded. It's referenced as an extern :\ Needless to say, trying to use
Questions:
This is bindgen-0.52. |
I encountered both of these problems, which I believe to be two different ones, neither
nor
...shows up in the output at all. Errors from cexpr are swallowed by bindgen and results in no output, and that's what happening here. The regexes are |
bindgen (a tool which generates the "raw" C bindings for Rust) only works (so far) with "simple" C `#define`s. In order to avoid having to manually maintain these constants in the (potential) Rust side, this patch converts them into an `enum`. There may be support in the future for expanding macros that end up in a "numeric" one: rust-lang/rust-bindgen#753. Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This adds helper functions to simplify calling zxio functions from inet sockets. This also adds stubs/missing_includes.h to the syncio library so bindgen can generate zxio shutdown option constants. Without this, bindgen runs into the issue where it can't expand C macros. See: rust-lang/rust-bindgen#753 Change-Id: I8e3e9aa015212a2cb8dabdc678d5c08329060014 Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/729108 Reviewed-by: Adam Barth <abarth@google.com> Commit-Queue: Vickie Cheng <vickiecheng@google.com>
rust-lang/rust-bindgen#753 As a result all V4L2_FWHT_FL_* macros have no bindings generated for them. The github issue describes a suggested workaround, which is applied in this patch which adds a dedicated "runbindgen" utility, and is centered around using a wrapper C header file for the problematic header and defining a custom parse callback. This works for _BITUL(), but unfortunately not for GENMASK() found in v4l2-controls.h, which is included from videodev2.h. However, there are just 2 invocations of GENMASK, so in the fix753.h wrapper we can #undef the 2 masks and define them manually. To generate bindings - inside runbindgen directory: cargo run -- -o ../videodev2_64.rs -I /path/to/kerneldir/usr/include/ cargo run -- -o ../videodev2_32.rs -I /path/to/kerneldir/usr/include/ -s /usr/i686-linux-gnu/ -t i686-linux-gnu
rust-lang/rust-bindgen#753 As a result all V4L2_FWHT_FL_* macros have no bindings generated for them. The github issue describes a suggested workaround, which is applied in this patch which adds a dedicated "runbindgen" utility, and is centered around using a wrapper C header file for the problematic header and defining a custom parse callback. This works for _BITUL(), but unfortunately not for GENMASK() found in v4l2-controls.h, which is included from videodev2.h. However, there are just 2 invocations of GENMASK, so in the fix753.h wrapper we can #undef the 2 masks and define them manually. To generate bindings - inside runbindgen directory: cargo run -- -o ../videodev2_64.rs -I /path/to/kerneldir/usr/include/ cargo run -- -o ../videodev2_32.rs -I /path/to/kerneldir/usr/include/ -s /usr/i686-linux-gnu/ -t i686-linux-gnu
Any updates to this issue? I'm trying to create rust bindings for raylib, but bindgen isn't generating rust bindings for the color macros: /* raylib.h */
/* ... */
/* These aren't being generated in the bindgen output. */
#define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White
#define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black
#define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent)
#define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta
#define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo)
/* ... */ |
In an effort to rewrite `bch2_read_super` from C to Rust, it is neccessary to have `opt_get!` macro defined, and some FMODE_* consts (defined as macro in `include/linux/blkdev.h`) defined as Rust const. Bindgen is currently unable to exapnd C functional macro [1], this this commit use the workaround as introduced in [2]. [1] rust-lang/rust-bindgen#753 [2] rust-lang/rust-bindgen#753 (comment) Signed-off-by: TruongSinh Tran-Nguyen <i@truongsinh.pro>
In an effort to rewrite `bch2_read_super` from C to Rust, it is neccessary to have `opt_get!` macro defined, and some FMODE_* consts (defined as macro in `include/linux/blkdev.h`) defined as Rust const. Bindgen is currently unable to exapnd C functional macro [1], this this commit use the workaround as introduced in [2]. [1] rust-lang/rust-bindgen#753 [2] rust-lang/rust-bindgen#753 (comment) Signed-off-by: TruongSinh Tran-Nguyen <i@truongsinh.pro>
Is there a possible solution in the near feature? I'm trying to convert macros for pin definitions of the harmony framework #define MyGPIO_Get() (((PORT_REGS->GROUP[2].PORT_IN >> 0U)) & 0x01U)
#define MyGPIO_PIN PORT_PIN_PC00 |
@emilio I'd like to propose a temporary and longer term solution that will take a while due to it requiring LLVM. In the short term, @ojeda found a workaround with clang where we should be able to use temporary intermediate files with the macros surrounded by parentheses to evaluate these sorts of expressions to a constant. This may slow down compile time, but it should have the benefit of allowing this particular case to be handled using current clang. In the longer term, @ojeda talked with the clang maintainers and they are open to having someone add functionality to LLVM and clang to essentially keep C preprocessor macro information available for a given parsed file. As you probably already know, currently, a lot of the cpp information is dropped by the time you've parsed the file. The clang maintainer is open to changes that would effectively allow using a header file as a context from which you could evaluate arbitrary macro expressions as I understand it (correct me if I'm wrong, @ojeda, since I wasn't part of this conversation). This would provide bindgen with the ability to have much more robust macro evaluate through clang. For now, would you be willing to accept the shorter term solution if I put up a PR and would you be interested in something like the longer term solution later on? |
@jbaublitz could you expand a bit on how this workaround with intermediate files would work? |
@pvdrz Sure! Just as a heads up, I think @ojeda and I have come up with two similar but slightly different solutions so we're emailing back and forth to get on the same page. However, I've had success in our test case around macros in cryptsetup that use function-like macros in their expansion to define constants using my solution. I've looked at the bindgen code and I feel like we kind of have two routes here. Currently, it looks like we have The first option is a more localized change and could possibly be used as a backup for The other option would be a larger change but would only require one temporary file per header being passed to bindgen. I've had success with the clang crate generating a list of macro definitions in the header file, putting them all in a temporary file, and then evaluating each one, mapping the evaluation to the original macro definition name, returning all of that information in a Do either of these sound acceptable or at least like something we can iterate on to find a solution that would be acceptable for bindgen? I understand that both of them are definitely workarounds and not the ideal solution we hope to get to with LLVM changes, but I think it could provide some quality of life improvements for right now. For example, when we built our Rust bindings for libcryptsetup against a new version that used function-like macros in their |
Yeah, to give an example: void f(void) {
(M);
} Then one can query with a cursor placed at Another way is initializing a variable: int m = M; If one requests
@AaronBallman told me that the C indexing APIs ( The change would involve keeping enough information to be able to evaluate the macros (or perhaps directly saving a map of evaluations, similar to what you suggest later, but on Clang's side). (Thanks a lot @jbaublitz for looking into this) |
FWIW, Clang's C indexing APIs have a TU-level flag named |
Yeah, in my case I just tested via |
@pvdrz Just a few more considerations:
|
@pvdrz Would you prefer to just have the support in LLVM as opposed to the workaround I proposed? |
So I'm generating bindings to <linux/uinput>. This works pretty well, but two c macros in particular do not produce any bindings in the output. Reduced input below:
Input C/C++ Header
Bindgen Invocation
wrapper.h
looks like this:Actual Results
No constant
UI_DEV_CREATE
orUI_DEV_DESTROY
generated in output.Expected Results
Constants
UI_DEV_CREATE
andUI_DEV_DESTROY
generated in output.I'm not really that familiar with the kernel macro
_IO
and not sure if this is technically even possible, but I figured to report just to get a more professional opinion. If it's not possible, workarounds welcome.The text was updated successfully, but these errors were encountered: