At first glance, these features look quite general to me and not particularly tied to the kernel, they are important utilities for doing this kind of programming in the real world.
At first glance, these features look quite general to me and not particularly tied to the kernel, they are important utilities for doing this kind of programming in the real world.
These new features are all about making things that the kernel devs need possible in safe Rust. This often requires support for some quite fancy abstractions, some of which cannot be expressed in current stable Rust.
Only if you primarily work with `cargo` and want to interact with C from Rust. The other way around has far less support and `rustc` does not standardize the object generation. This is actively preventing projects like `systemd` to adopt Rust into their project as an example.
In what way(s) does Rust's C interop depend on cargo?
> The other way around has far less support and `rustc` does not standardize the object generation.
I believe in this context the understanding is that you're going to be using `extern "C"` and/or `#[repr(C)]` in your Rust code, which gives you a plain C interface. I think attempting to use "raw" Rust code from other languages is a rare phenomenon, if it's even attempted at all.
> This is actively preventing projects like `systemd` to adopt Rust into their project as an example.
Could you point out specific instances from that thread? From a quick glance I didn't see any obvious instances of someone saying that using Rust from C is problematic.
Do rust and cargo allow for multiple interpretations of the same C header file across different objects in the same program? That's how C libraries are often implemented in practice due to preprocessor tricks, though I wish it wasn't normal to do this sort of thing.
If the header files are consumed by C code that is then consumed by Rust then you'll have full support for what C supports because it will be compiled by a C compiler.
However, some people use cargo's build scripts to build c programs, which then you can link into your Rust program. Support would then depend on whatever the person wrote with the script, which in my experience usually delegates to whatever build system that project uses. So it should work fine.
I guess looking at that pedantically that's "just" a tooling issue, rather than an issue with the Rust language itself. That's not really a useful distinction from an end user's perspective, though; it's friction either way, and worth addressing.
I am currently working on a fairly involved C & Rust embedded systems project and getting the inter-language interface stable and memory-leak free took a good amount of effort. It probably didn't help that I don't have access to valgrind or gdb on this platform.
There is some C++/rust interop in the past that I've worked on that would have enjoyed the arbitrary self types feature, but not particularly because of the C++ part of the equation. In fact I think if it had been a pure rust project it would also have enjoyed that feature just as much so... eh... take it for what little it's worth I guess.
Writing Rust code to be called from C (but within the same application)? Doable but somewhat painful.
Writing Rust code to act like a C shared library? Quite painful and some pretty important features are missing (proper symbol versioning support being the most obvious one). Theoretically doable if you're willing to compromise.
There's also some aspects of FFI-safety that are very subtle and easy to mess up:
* #[repr(C)] enums still have the same requirements as Rust enums and so C callers can easily trigger UB, so you need to use something like open_enum. Thankfully cbindgen is too dumb to know that #[open_enum] is a proc macro and produces a non-enum type.
* Before io_safety in Rust 1.63, dealing with file descriptors from C without accidentally closing them was horrific (though this was a wider problem in Rust). BorrowedFd is quite nice -- though Rustix will panic if you use negative fds and so you need to add validation and your own type in practice. However, #[repr(transparent)] is very nice for this.
* Lots of reading about unsafe Rust is necessary when doing most non-trivial things with C FFI.
* You need to make use of a lot of compiler internals, build scripts, and other magic to get the output you want.
* Tools like cargo-c and cbindgen are nice and probably work great for 80% of projects, but the 20% really suffer from no useful tooling. I haven't tried to use rustc directly to work around some of the remaining issues, but I suspect it'd be even more painful.
I would say that the C interop with Rust is pretty good but it has lots of room for improvement and it feels like very few resources have been spent on it after they got the core stuff working.Source: I've been writing a Rust library intended to be used primarily via C FFI and run into a lot of issues...