https://github.com/rust-lang/rust/compare/master...arcnmx:libsystem
Overview
Suggestion: skip to the tl;dr at the bottom, but let's start with some assertions...
-
libstdneeds some cleaning up. Its implementation of various interfaces is rather adhoc and relies heavily on implementation details. It's written against libc, and does not consider any platforms beyond windows-like and unix-like. -
liblibcis far from ideal. See RFC #1291 - Devs want a way to use Rust and its standard library on platforms where full functionality may not be available. See issue #27701
- Restricting usage to
libcoreis often far from ideal when interacting with the greater Rust ecosystem. Cargo and crates.io dependencies rarely work well with it. A true facade with independent features/pieces as discussed over there recently would be great.
- Restricting usage to
Why do I care? I simply love the language, and want to use it anywhere I can. Everywhere from desktop applications to mobile to embedded userspace to kernel to microcontrollers to the web. I feel like it's a perfect language choice for anything, but there's so much friction around the cross-compiling and embedded story that it's often a pain to use.
What do we need?
- Cargo and crates.io integration with less-capable platforms
- Crates that only require a subset of libstd should be available for use on embedded platforms.
- Need the ability to specify a sysroot to Cargo and rustc, or otherwise tell rustc where to find
libstdand friends.- Cargo could use a --sysroot option, and this needs to interact properly with build dependencies, in the same way that --target does.
- Alternatively it could just build them for you when missing?
- A convenient way to build a
libstdsysroot for a given target, without having to go through the entire rustc build process. - Ease porting libstd to a new platform.
Ways to achieve this and goals
- Clearly define a platform-independent API that provides all functionality
libstdneeds without exposing any implementation details. - Make porting
libstdto new platforms straightforward by isolating all functionality that needs to be provided.- bare metal, kernels, microcontrollers, etc.
- static syscall
libstdthat doesn't depend on any C libraries
- Cut the circular dependencies between
libstd::sysandlibstd - Remove all
#[cfg(target_os..., unix, etc)]branches inlibstd. - Remove
libstd's dependency onliblibc - Implement a
bindfallbacklibsystemimplementation entirely made ofextern fns in order to...- Have a reference implementation that exposes nothing about itself to ensure no implementation details are being relied upon.
- Allow libstd to be used raw without any dependency at all, while lazily linking in any functionality that does end up being necessary.
- Migrate as much as possible away from
rust_builtin(low prio, but would be nice)
Unrelated useless things in this branch:
- Cargo.toml for all of rustc and its stdlib. Not incredibly useful compared to the ongoing cargo-build branch, but I like it as a quick way to build a
libstdsysroot and the rustc compiler without having to deal with the multi-stage build system. - target_family flexible target configuration - the whole world isn't just unix and windows. This probably belongs as a standalone PR?
-
liblibcchanges for a generic target_family. Probably useless, better to just killliblibcas a dependency from everything exceptlibsystem.
tl;dr what actually needs doing:
- Isolate platform dependent behaviour and ensure it only exists in
libstd::sys. Fix up all the current leaky abstractions so there's a single point where the system implementation lives. - Expand the binary
target_familyso libraries may be aware of other platforms. - Remove the circular dependency between
libstdandlibstd::sysso that it can be pulled out intolibsystem.- Type implementations that currently need to be shared and thus make this slightly problematic:
sync::Oncethread_local!()-
io::Error, a newsys::Errortype should be introduced
- This is mostly a bikeshed argument, it'd be fine to still live in libstd. Pulling it out simply makes it easier to assert that certain invariants aren't exposed or accidentally relied upon, and makes for cleaner and well defined abstractions.
- Type implementations that currently need to be shared and thus make this slightly problematic:
- Avoid unnecessary allocations and general cleanup of the system code.
- Related: RFC #862
- Move as much as possible from
rust_builtininto native Rust code.
Comments, thoughts, feedback?
A good way to start would be to do a minor refactor and implement 1. from the list above first. Does this require an RFC, or does anyone object to the idea of it? Then 2. would come next, though our current #[cfg(...)] story could use a facelift...
