origin-stdio is an alternative [std
]-like implementation built on [origin
].
At this time, it only works on Linux (x86-64, aarch64, riscv64, 32-bit x86),
requires Rust nightly, lacks full std
compatibility, and is overall
experimental. But it supports threads and stuff.
Quick start:
In an empty directory, on Linux, with Rust nightly, run these commands:
sh
cargo init
cargo add origin_studio
cargo add compiler_builtins --features=mem
echo 'fn main() { println!("cargo:rustc-link-arg=-nostartfiles"); }' > build.rs
sed -i '1s/^/#![no_std]\n#![no_main]\norigin_studio::no_problem!();\n\n/' src/main.rs
cargo run --quiet
This will produce a crate and print "Hello, world!".
Yes, you might say, I could have already done that, with just the first and
last commands. But this version uses origin
to start and stop the program,
and [rustix
] to do the printing.
And beyond that, origin-studio uses origin
to start and stop threads,
[rustix-futex-sync
] and [lock_api
] to do locking for threads,
[rustix-dlmalloc
] to do memory allocation, and [unwinding
] to do stack
unwinding, so it doesn't use libc at all.
cargo init
This creates a new Rust project containing a "Hello, world!" program.
cargo add origin_studio
This adds a dependency on origin_studio
, which is this crate.
cargo add compiler_builtins --features=mem
This adds a dependency on compiler_builtins
, which is a crate that provides
definitions of library functions that rustc
and libcore
use. The mem
feature enables implementations of memcpy
, memset
, strlen
, and others.
echo 'fn main() { println!("cargo:rustc-link-arg=-nostartfiles"); }' > build.rs
This creates a build.rs file that arranges for [-nostartfiles
] to be passed
to the link command, which disables the use of libc's crt1.o
and other startup
object files. This allows origin to define its own symbol named _start
which
serves as the program entrypoint, and handle the entire process of starting the
program itself.
sed -i '1s/^/#![nostd]\n#![nomain]\noriginstudio::noproblem!();\n\n/' src/main.rs
This inserts three lines to the top of src/main.rs:
- #![no_std]
, which disables the use of Rust's standard library
implementation, since origin-studio provides its own implementation that
using rustix and origin.
- #![no_main]
, which tells Rust to disable its code that calls the user's
main
function, since origin-studio
will be handling that.
- origin_studio::no_problem!()
inserts code to set up a Rust panic handler,
and optionally a global allocator (with the "alloc" feature).
cargo run --quiet
This runs the program, which will be started by origin, prints "Hello, world!"
using origin-studio's println!
macro, which uses origin-studio's
std::io::stdout()
and std::io::Write
and rustix-futex-sync
's Mutex
to
do the locking, and rustix
to do the actual I/O system call, and ends the
program, using origin.
Other alternative implementations of std include [steed], [tiny-std] and [veneer].
[mustang] is a crate that uses origin to build a libc implementation that can slide underneath existing std builds, rather than having its own std implementation.
[relibc] also includes a Rust implementation of program and thread startup and shutdown.
Right now, this is a demo of how to use origin
. If you're interested in
seeing this grow into something specific, or interested in seeing projects
which might be inspired by this, please reach out!