-
Notifications
You must be signed in to change notification settings - Fork 743
[WIP] reexport the static inline functions and TLS variables with C/CPP wrapper #1460
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
Conversation
non_upper_case_globals | ||
)] | ||
|
||
c! { # include "generate-c-inline.h" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do these macros come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rust-c has a simple c! {}
implementation for C, and rust-cpp also provides cpp! {}
macro for C++
if you think the way is right, I could add a special implementation to bindgen
, it need add some code to build.rs
, generate some .c
/.cpp
file on building.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be ok to depend on external crates, but then it should be documented and obviously not on-by-default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After read the rust_c
and rust-cpp
crates, I believe we only need a very simple implementation like
macro_rules! c {
() => {};
(#include $filename:tt $($rest:tt)*) => {
c!{ $($rest)* }
};
({ $body:tt } $($rest:tt)*) => {
c!{ $($rest)* }
};
}
and a bindgen-build
crate be added to support extract and build C/C++ code in the build script.
You can check a real example that includes hundreds of static inline functions with some build script, like
bindgen_build::build(binding_file, "rte", |build| {
build
.flag("-march=native")
.include("src")
.include(rte_sdk_dir.join("include"));
for (name, value) in &cpu_features {
build.define(name, value.as_ref().map(|s| s.as_str()));
}
}).unwrap();
besides, I added some code to handle the deprecated functions, like
extern "C" {
#[deprecated]
#[link_name = "\u{1}_rte_bsf64"]
pub fn rte_bsf64(slab: u64, pos: *mut u32) -> ::std::os::raw::c_int;
}
c ! { { int _rte_bsf64 ( uint64_t slab , uint32_t * pos ) { return rte_bsf64 ( slab , pos ) ; } } }
and the generated C/C++ file like
// generated by bindgen; DO NOT EDIT
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# include "rte.h"
...
int _rte_bsf64_safe ( uint64_t v , uint32_t * pos ) { return rte_bsf64_safe ( v , pos ) ; }
...
#pragma GCC diagnostic pop
What's your opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
besides, with the C/C++ wrapper, we could reexport the thread local variable to solve #1187
__thread int i;
extern __thread struct state s;
static __thread char *p;
could generate the getter/setter functions
extern "C" {
pub fn i() -> ::std::os::raw::c_int;
pub fn set_i(v: ::std::os::raw::c_int);
}
c! { { int i ( ) { return i ; } } }
c! { { void set_i ( int v ) { i = v ; } } }
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct state {
_unused: [u8; 0],
}
extern "C" {
pub fn s() -> state;
pub fn set_s(v: state);
}
c! { { struct state s ( ) { return s ; } } }
c! { { void set_s ( struct state v ) { s = v ; } } }
extern "C" {
pub fn p() -> *mut ::std::os::raw::c_char;
pub fn set_p(v: *mut ::std::os::raw::c_char);
}
c! { { char * p ( ) { return p ; } } }
c! { { void set_p ( char * v ) { p = v ; } } }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach works, but there's a lot of unanswered questions related to mangling and such...
I'm sorry for having missed this, btw :(
Maybe a better approach would be to instead add a ParseCallback
when we see a thread-local variable, in order to let the caller to do whatever they want with it, since this seems like a pretty opinionated solution to the problem.
That would allow us not to depend on c!
/ cpp!
in any way.
☔ The latest upstream changes (presumably #1525) made this pull request unmergeable. Please resolve the merge conflicts. |
I'm closing this PR as the |
According the discussion of #1090, I doubt we hard to ask user to provide a customized build library (with
-fkeep-inline-functions
or other options) for FFI binding, we may reexport those static inline functions with auto generated C/CPP wrapper functions base on the rust-c and cpp crates (it's also easy to implement it inbindgen
itself).For example, the c code from
generate-c-inline.h
could be translate to Rust code
and the C++ code from
generate-inline.hpp
could be translate to Rust code