Rust: Move std::os::raw to libcore?

Created on 1 Sep 2016  Â·  17Comments  Â·  Source: rust-lang/rust

I’m currently playing "embedded" with hardware (ARM Cortex-M CPU with 64 KB RAM). I’m using #![no_std] (there’s no operating system) and FFI to use C and C++ device drivers.

For bindings I’d like to use std::os::raw::c_long and other types in that module. But this module is not available in libcore. Is there a reason for this? If not, I’ll submit a PR to move it (and of course re-export it at its current location).

C-enhancement T-libs

Most helpful comment

Moving these types into core without breaking compatibility with the libc crate (especially for the c_void type) is going to be challenging. I think a better solution would be to move them into a separate no_std crate called ctypes (name subject to the usual bikeshedding). Unlike libc, ctypes does _not_ link to the C library and only provides type definitions and constants. The libc crate will then be modified to re-export the types from ctypes.

All 17 comments

Historically, my understanding is that libcore is not supposed to contain anything os-specific. I think.

My understanding is that it doesn’t depend on API or other things provided at run-time by an OS, but that doesn’t mean it can’t have things that compile differently based on the target/platform. src/libcore already contains cfg attributes or macros for:

  • target_pointer_width
  • target_arch
  • sse2
  • target_endian
  • target_has_atomic

Yes historically we have not done this because of what @steveklabnik said. These types are _OS-specific_, not _architecture specific_, which I believe the other flags you're mentioning @SimonSapin are.

This is also why the libc crate has a #![no_std] mode, for using these types without libstd.

This is also why the libc crate has a #![no_std] mode, for using these types without libstd.

Ohh, I didn’t know about that. Thanks!

Well, current libc doesn’t build on a custom thumbv7em-none-eabi target. (4 thousands and some lines of compile errors: https://github.com/rust-lang/libc/issues/375)

Regardless, I don’t understand why having cfg(windows) conditional compilation in libcore is so much worse than cfg(sse2), long as libcore doesn’t run-time-depend on things from the OS.

Regarding #[cfg(windows)], winapi defines the C types itself https://github.com/retep998/winapi-rs/blob/dev/src/lib.rs#L35. It only relies on std for c_void if that feature is enabled.

I personally don't hold an opinion either way on whether this sort of stuff should be in libcore. If it does get added to libcore, just be very careful to ensure that they are defined correctly for every single obscure platform that libcore can be used on.

These are target specific, not OS specific aren't they? And there's other target specific stuff in core, isn't there? I think it would be useful to interface easily with C using no_std.

Not exactly. For example on x86_64, c_long is 32 bits on Windows and 64 bits everywhere else.

Moving these types into core without breaking compatibility with the libc crate (especially for the c_void type) is going to be challenging. I think a better solution would be to move them into a separate no_std crate called ctypes (name subject to the usual bikeshedding). Unlike libc, ctypes does _not_ link to the C library and only provides type definitions and constants. The libc crate will then be modified to re-export the types from ctypes.

Not exactly. For example on x86_64, c_long is 32 bits on Windows and 64 bits everywhere else.

Yes, but I would say it's because they are different "targets" or ABIs. It's not like they are consistent on an OS, i.e., c_long isn't always 32 bits on Linux irrespective of the target.

I think that if:

  • std::os::raw would be gated on platforms, and
  • core crates wouldn't need a solution to this problem,

the status quo would make sense.

But is std::os::raw gated on anything? If not, the moment LLVM adds support for a new platform the std::os::raw::* types becomes automatically stable for that platform in the next release, because from that point on changing any of it is a breaking change.

Also, calling C code is not uncommon for #[no_std] core-only crates, and compiling a core crate still requires a target triple (or target description) which the definitions of void* and long must match.

Furthermore, a couple of SIMD intrinsics are specified with c_void in stdsimd:

  • fn _mm_prefetch(p: *const c_void, strategy: i8)
  • fn _mm_clflush(p: *mut c_void)

Maybe we should change that, but right now it means that core::vendor requires std 🤣

I've been using the cty crate to get C types in no_std environments, but this really should be part of libcore. The main issue with cty is that its c_void is not compatible with the one from libc.

Could expose cty in core as core::ctypes, and then use it in std::os::raw and libc to make all types be equal? That way we would be able to use them in core, and we wouldn't need to do the dance of converting os::raw::c_void to libc's c_void and vice-versa. pinging @japaric

These types are OS-specific, not architecture specific, which I believe the other flags you're mentioning @SimonSapin are.

Although it’s in an internal implementation detail rather than in a public API, libcore now has:

    #[cfg_attr(not(any(target_os = "emscripten", target_os = "redox",
                       target_endian = "big")),
               repr(simd))]
    struct Block(u64, u64, u64, u64);

which does depend on the OS.

Anyway, I still don’t understand why this distinction is useful. Compiled libcore is distributed together with libstd, in "targets" that are both OS-specific and architecture specific. #[cfg(target_os = "…")] is available to libcore just as well as other cfgs.

New RFC to propose this more formally, but only for c_void for now: https://github.com/rust-lang/rfcs/pull/2521

I've been using the cty crate to get C types in no_std environments, but this really should be part of libcore. The main issue with cty is that its c_void is not compatible with the one from libc.

I like you idea, the ctypes and some basic type should be in a non_std crate and distribute with rust.
We can stablize it day but, doesn't need to be in a single short.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

modsec picture modsec  Â·  3Comments

tikue picture tikue  Â·  3Comments

Robbepop picture Robbepop  Â·  3Comments

pedrohjordao picture pedrohjordao  Â·  3Comments

nikomatsakis picture nikomatsakis  Â·  3Comments