rust-highfive · GitHub

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:

  • fs just mostly return io::Error. UNIX-compatible Path/OsString handling is still supported
  • net just mostly return io::Error. Addressing structures are still supported
  • process just mostly return io::Error
  • env just mostly return io::Error
  • thread just mostly return io::Error (note std::thread::spawn calls unwrap internally...)
  • stdio use "fake stdio" as is used on Windows when there is no console
  • sync replace 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.
  • time SystemTime is like the Linux version and you can do time math, but calling now will 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
  • rlibc or 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

Read the original on github.com ↗