This is an attempt to "port" libstd to run in unconventional environments. Unconventional here means: no networking, no filesystem, no environment and in general no system calls. Think OS kernel but different: you do want allocation and collections, you do want floating point numbers, you do want standard Rust abstractions such as io::Write, etc. Using no_std is really inconvenient in these situations because a lot of std is missing. Examples of such environments are emscripten¹ and Intel SGX.
This PR adds a target_os = "none" configuration. The approach I've taken is to base everything of off the unix base, removing the dependency on libc, and returning errors from all functions that used libc. I've borrowed some ideas from the Linux and emscripten implementations here and there.
In some places the existing unix code needed only minor modifications and #[cfg()] additions, in these cases I've modified the files inline. In other cases, it made more sense to reimplement the sys API in a new file. See libstd/sys/none/mod.rs.
In general these areas have been modified:
fsjust mostly return io::Error. UNIX-compatible Path/OsString handling is still supportednetjust mostly return io::Error. Addressing structures are still supportedprocessjust mostly return io::Errorenvjust mostly return io::Errorthreadjust mostly return io::Error (notestd::thread::spawncalls unwrap internally...)stdiouse "fake stdio" as is used on Windows when there is no consolesyncreplace all primitives with single-threaded primitives without any locking. If you do somehow end up in a multi-threaded environment, this means things are totally and utterly racy and unsafe.timeSystemTimeis like the Linux version and you can do time math, but callingnowwill panic.
I'm aware that the current state of the PR is nowhere near merging. I just want to announce my plans and solicit feedback. I already know that the following things need work:
- tests. I have not tried to run any tests yet. It's not even clear how to run tests as there is no generic way to run binaries compiled for this target. Even if there were, I imagine many tests are going to fail. What would be a good approach to handling this?
- formatting. I'm pretty sure that I'm not adhering to proper style everywhere
- copyright headers for new files. These will be added later
- librustc_back target. For now you need to use the JSON target file.
Rather, I'm looking for technical feedback.
You can build this branch like so:
RUST_TARGET_PATH=/somewhere cargo rustc --lib --release --target x86_64-unknown-none-gnu --manifest-path src/rustc/std_shim/Cargo.toml
You can then link the deps directory to the approriate lib/rustlib in your rust installation to test building with this target. Here's what you need to supply to make it link:
- an allocator crate
rlibcor similar- an implementation for
extern fn getrandom(buf: *mut u8, len: usize);
I made a sample application that takes this std and adds some Linux system calls around it, it works.
¹: If I understand the state of the emscripten port correctly based on discussions with @brson, if you're trying to use functionality that doesn't exist on the platform you'll just get linker errors. That's of course not very ergonomic.
r? @brson