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...
-
libstd
needs 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. -
liblibc
is 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
libcore
is 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
libstd
and 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
libstd
sysroot 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
libstd
needs without exposing any implementation details. - Make porting
libstd
to new platforms straightforward by isolating all functionality that needs to be provided.- bare metal, kernels, microcontrollers, etc.
- static syscall
libstd
that doesn't depend on any C libraries
- Cut the circular dependencies between
libstd::sys
andlibstd
- Remove all
#[cfg(target_os..., unix, etc)]
branches inlibstd
. - Remove
libstd
's dependency onliblibc
- Implement a
bind
fallbacklibsystem
implementation entirely made ofextern fn
s 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
libstd
sysroot 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?
-
liblibc
changes for a generic target_family. Probably useless, better to just killliblibc
as 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_family
so libraries may be aware of other platforms. - Remove the circular dependency between
libstd
andlibstd::sys
so that it can be pulled out intolibsystem
.- Type implementations that currently need to be shared and thus make this slightly problematic:
sync::Once
thread_local!()
-
io::Error
, a newsys::Error
type 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_builtin
into 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...