Porting Rust's Std to Rustix
blog.sunfishcode.online
blog.sunfishcode.online
(For a bit of background info: It might seem counterintuitive, but on Windows, a “native” application “should” actually call the programming language agnostic Kernel32.dll functions directly. At least that’s the documented, stable way of doing things. Instead, Rust’s std currently goes through libc, which is also fine, but on Windows is an abstraction built on top of the Windows APIs, and is historically a lot less stable. This can cause code bloat and distribution hassles.
This is a bit different from Linux, where the abstractions are layered the other way round: the OS (POSIX) spec mostly assumes an existing libc. As a result, on Linux, going libc-less is a bit harder in my limited experience — though certainly possible if you know what you’re doing.)
Edit: I'm not altogether sure why this is being downvoted, but in case it wasn't clear: this is a sincere question and not some kind of pedantic rhetorical question. (I don't really mind whether people upvote or downvote the comment, except to the extent that it's a signal that I perhaps wasn't clear in what I was asking.)
Personally I'm also in favour of cutting out libc and invoking the windows API directly. But others might argue that using it as a shared abstraction that's very similar on Windows, Linux, OSX, BSD, is worth it.
And "native" is ill defined. It's just one more abstraction layer in the libc -> Win32-API -> NT-API -> Kernel chain. Libc isn't comparable to a java runtime or electron, which is what people usually mean when they talk about applications not being "native".
The recent thread about cutting down the startup of C applications on Linux proves the point it isn't a zero cost library.
Are you sure about this? Rust's std's File::open calls CreateFile on Windows, not libc open. Isn't CreateFile correct Kernel32.dll API to call?
https://github.com/rust-lang/rust/blob/master/library/std/sr...
To be clear, this is feasible but it'll require someone knowledgable to put in the work of rewriting this in Rust.
https://docs.microsoft.com/en-us/windows/win32/debug/vectore...
Granted, they are more cumbersome to use and probably not worth the effort to try to avoid them other than special cases.
IIRC llvm itself generates calls to __CxxFrameHandler3 when SEH is being used, making it awkward to replace with something that's not compatible.
FWIW the POSIX spec assumes libc, but on Linux specifically the syscall interface is stable.
However, most computers in the world run Linux nowadays.
For programming - whatever you use and are comfortable with is the best. One does not need to concern what others like / use as long as it does not impede one's own work.
Many devs targeting embedded and mobile devices are painfully aware of that reality.
I'd be interested in hearing more about this. I have a lot of thoughts about sandboxing and Rust, including both build and runtime sandboxing. Would be cool to understand if others are working on this and chat about it. I'm familiar with cap-std, but curious about any other initiatives or where the discussions are happening.
Now I think Rust has enough resource to try this.
Anyone have any personal favorite books or articles that would be good for getting up to speed on this kind of thing?
Such wonderful news! This will enable so many good things, easier cross builds and being able to run Rust code and the ecosystem in more places.
Thank you!
x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl
Note that statically linked musl binaries run fine on glibc Linux, so you can just distribute musl binaries. That works right now. In the future, you will just distribute Rustix binaries, which will be hopefully smaller than musl binaries (because it doesn't need to support C API).
* glibc linked dynamically
* musl linked dynamically
* musl linked statically
* direct syscalls from rust
and possibly additional options choosing if math functions, memcpy, etc. should use an implementation shipped with rust or one shipped with libc.
The big question is if we'll get to a point where almost all rust application don't use a libc at all.
> * musl linked statically
This is handled through the orthogonal "crt-static" target-feature.
IIRC each supported CRT has a preference, but for some that can be overridden (musl would be one of those, possibly one of few of those since statically linking glibc is generally recommended against, and so's pretty much every non-linux libc, when that's an option at all).
Wonder if that means it would be easier to verify the correctness of `unsafe` use inside Rust itself?
> Wonder if that means it would be easier to verify the correctness of `unsafe` use inside Rust itself?
If you mean usage of unsafe inside std (which the Rust compiler does depend upon), that is one of the explicit goals of Rustix. The usage of unsafe will be much more narrow overall, mostly surrounding the system calls themselves.
In any case, I hope it remains separate. Third-party no_std code would benefit from it.
[1] Like a typical RTOS, that may provide some basic communication primitives, thread creation, and a hardware abstraction layer (HAL).
Libc is necessary, but not good.