$ bindgen /usr/include/stdint.h --use-core | rg 'std'
pub type __u_char = ::std::os::raw::c_uchar;
pub type __u_short = ::std::os::raw::c_ushort;
pub type __u_int = ::std::os::raw::c_uint;
pub type __u_long = ::std::os::raw::c_ulong;
pub type __int8_t = ::std::os::raw::c_schar;
pub type __uint8_t = ::std::os::raw::c_uchar;
pub type __int16_t = ::std::os::raw::c_short;
pub type __uint16_t = ::std::os::raw::c_ushort;
pub type __int32_t = ::std::os::raw::c_int;
pub type __uint32_t = ::std::os::raw::c_uint;
[...]
This is mostly a dupe/expansion of #1015, #448, #628, #1439.
I'm afraid that you don't like the discussion anymore, but in my eyes this isn't closed. If I want to build a !#[no_std] crate which relies on "no std" c libraries, it isn't possible in the current form.
I know, that some of types can't be expressed in core(, but e.g. why is int8_t defined as c_schar instead of i8?), but currently my workaround is to opaque all the types. This isn't feasible. The workaround with libc is also not possible for me, because I don't have a libc running on bare metal.
Bindgen should be able to deduce the types, because it knows the target and therefore knows what c_uchar, c_ushort, ... are, e.g. if they are u8 or u16 or anything else. They can be mapped directly to the corresponding types.
What I would like to see is either an option to skip all std dependent types (e.g. by using --skip-std-types). I see two possibilities here:
One could also print a message to stdout, that a specific type (e.g. clock_t) has been skipped, because of that option above.
Is that something one could provide? What alternatives are (expect for blacklisting all the types :|).
Maybe one could also provide meta variables, which is then an alias for e.g. std::os::raw::c_int, e.g.
pub type r_c_int = std::os::raw::c_int;
[...]
pub type __int32_t = r_c_int;
pub type __mode_t = r_c_int;
[...]
and then I only have to specify the types r_c_int which can be done by using the blacklist feature again :)
The expected way to use --use-core is also using --ctypes-prefix.
So ./target/debug/bindgen /usr/include/stdint.h --use-core --ctypes-prefix=libc, for example.
You can perfectly do something like: ./target/debug/bindgen /usr/include/stdint.h --use-core --ctypes-prefix=myctypes
And define something like:
pub mod myctypes {
pub type c_int = i64; // yolo
}
It's not clear to me how that is different from your proposed solution, or am I missing something?
I know, that some of types can't be expressed in core(, but e.g. why is int8_t defined as c_schar instead of i8?), but currently my workaround is to opaque all the types. This isn't feasible. The workaround with libc is also not possible for me, because I don't have a libc running on bare metal.
int8_t is treated internally in bindgen as i8, __int8_t, which is what you show above, is a typedef that your standard C headers happen to have.
So
./target/debug/bindgen /usr/include/stdint.h --use-core --ctypes-prefix=libc, for example.
As said, libc is not feasible here :/
You can perfectly do something like: ./target/debug/bindgen /usr/include/stdint.h --use-core --ctypes-prefix=myctypes
But I do not know the types, but my compiler does (I honestly don't care if an int is 16 or 32 bits wide and I don't think this is an ideal solution that the user should supply the exact types).
I'm not really sure how to handle this, but IMHO the --use-core experience is not very ideal and lead to some frustration when I first used it.
Ah, I see. So what you want is a way to generate bindings for whatever target clang bindgen invoked against, is that right?
That means that the bindings will no longer be portable, but maybe that's ok as long as you opt into that.
I just want to add I'm in the same predicament. Bare metal embedded, no libc. I don't care about portability of the bindings I'm generating for a specific hardware target, what I want is for bindgen to generate no_std bindings without having to hand-define all the c_types, which seems to be the case.
Ok, so I'll assume https://github.com/rust-lang/rust-bindgen/issues/1583#issuecomment-506438359 is the right understanding of the issue.
If so, this should be pretty easy to implement. Just add a new switch and then in this match here:
We need to do something similar to what we do for wchar_t already, but instead of doing it when parsing the type we should do it later. Indeed, there's no reason wchar_t works that way so I sent https://github.com/rust-lang/rust-bindgen/pull/1596 to clean it up.
Doing the same for the other integer types under a flag should be pretty straight-forward.
Has there been any further work towards this issue?
It feels a bit odd to require users to specify their definition of c_int and friends using --ctypes-prefix, especially when a lot of my headers explicitly use the types from stdint.h (i.e. int32_t and uint8_t) which have unambiguous equivalents in Rust.
I've also run into this, I'm trying to generate bindings for GRUB. Is there anything I can do, or do I need to figure out what types the c types correspond to and map them by hand?
https://github.com/rust-lang/libc seems to suggest it might be possible to use libc with no_std? std: by default libc links to the standard library. Disable this feature remove this dependency and be able to use libc in #![no_std] crates.
Is it possible to use libc's types without needing to actually link / whatever the binary to the final result?
Edit: after grepping a bit, if I did it right, it seems like I really only need to map 12 or so simple basic types, so maybe it's not so bad.
Edit 2: assuming this is correct, it seems easy enough to copy: https://github.com/rust-lang/libc/blob/58b2706e75df705813dd94c50b1f18e852519c33/src/unix/mod.rs
Yeah. Alternatively as a reply to the comments above no, there hasn't been any work towards this feature, but https://github.com/rust-lang/rust-bindgen/issues/1583#issuecomment-514436948 should still be an accurate description of what needs to get done.
I don't plan to work on this myself but I'll happily review a patch or mentor someone interested in doing so.
I found the hints in https://docs.rust-embedded.org/book/interoperability/c-with-rust.html#automatically-generating-the-interface useful:
[dependencies]
cty = "0.2.1"
let bindings = bindgen::Builder::default()
.use_core()
.ctypes_prefix("cty");
Most helpful comment
I just want to add I'm in the same predicament. Bare metal embedded, no libc. I don't care about portability of the bindings I'm generating for a specific hardware target, what I want is for bindgen to generate
no_stdbindings without having to hand-define all the c_types, which seems to be the case.