wg
wg copied to clipboard
Defining libc::c_char, c_long, etc.
With thumbv6m_none_eabi and similar targets, the libc crate does not compile because c_char, c_long, c_ulong, and wchar_t are not defined. This is issue https://github.com/rust-lang/libc/issues/375. We should fix this and add those definitions.
gcc + newlib obviously have definitions for those types, but it looks like the thumb* targets in rustc are designed to not assume newlib. (Some std an libc code use cfg(target_env = "newlib"), but target_env is the empty string in each src/librustc_target/spec/thumb*.rs file in rustc.)
Would cfg(target_arch = "arm", target_os = "none") be an appropriate filter to select targets that all have the same definition of these four types? What would that definition be?
You can use just cfg(target_arch = "arm") for most type definitions.
The ARM Procedure Call Standard defines the mapping between C types and machine types in section 7.1.1. The size and alignment of machine types is defined in section 4.1.
I think the only C type that has no fixed definition is wchar_t which can be u16 or u32. The official ARM compiler (armclang) uses u32 by default but the definition can be changed to u16 using a compiler flag (see section 1.28). The Keil compiler does the opposite: it defaults to u16.
I ended up stuck here (as far as I can understand it), after trying to do a C library -> bingden -> FFI -> lib crate workflow.
Notably, libc will give you "nothing" if building for any Cortex-M, thumbv6m_none_eabi, thumbv7em-none-eabihf, etc, since there is not anything defined for target_env=arm:
https://github.com/rust-lang/libc/blob/master/src/lib.rs#L150
This is my attempt at a solution, and it does appear to work, insofar as I can build a bindgen ouput for a large embedded C library with libc as the only dependency: https://github.com/apullin/libc/commit/d5e73064cd856f431a759b229bd9b338bbe14f5e
With the added note that my use of bingden required passing flags to steer it towards the expected target, i.e. --target=thumbv7em-none-eabi (since I think bindgen is using clang under the hood?) and --ctypes-prefix=libc to coax types from libc rather than std.