Crate origin_studio

source ·
Expand description

Origin Studio

An alternative `std`-like implementation built on Origin

Github Actions CI Status zulip chat crates.io page docs.rs docs

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:

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.

What are those commands doing?

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/^/#![no_std]\n#![no_main]\norigin_studio::no_problem!();\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.

Similar crates

Other alternative implementations of std include steed, tiny-std and veneer.

Mustang and Eyra are crates that use origin to build a libc implementation that can slide underneath existing std builds, rather than having their own std implementations.

relibc also includes a Rust implementation of program and thread startup and shutdown.

Why?

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!

Modules

  • Memory allocation APIs
  • Utilities for dynamic typing or type reflection.
  • SIMD and vendor intrinsics module.
  • Utilities for the array primitive type.
  • Operations on ASCII strings and characters.
  • A module for working with borrowed data.
  • The Box<T> type for heap allocation.
  • Shareable mutable containers.
  • Utilities for the char primitive type.
  • The Clone trait for types that cannot be ‘implicitly copied’.
  • Utilities for comparing and ordering values.
  • Collection types.
  • Traits for conversions between types.
  • The Default trait for types with a default value.
  • Inspection and manipulation of the process’s environment.
  • Constants for the f32 single-precision floating point type.
  • Constants for the f64 double-precision floating point type.
  • Utilities related to FFI bindings.
  • Utilities for formatting and printing Strings.
  • Asynchronous basic functionality.
  • Generic hashing support.
  • Hints to compiler that affects how code should be emitted or optimized. Hints may be compile time or runtime.
  • i8Deprecation planned
    Redundant constants module for the i8 primitive type.
  • i16Deprecation planned
    Redundant constants module for the i16 primitive type.
  • i32Deprecation planned
    Redundant constants module for the i32 primitive type.
  • i64Deprecation planned
    Redundant constants module for the i64 primitive type.
  • i128Deprecation planned
    Redundant constants module for the i128 primitive type.
  • Traits, helpers, and type definitions for core I/O functionality.
  • isizeDeprecation planned
    Redundant constants module for the isize primitive type.
  • Composable external iteration.
  • Primitive traits and types representing basic properties of types.
  • Basic functions for dealing with memory.
  • Numeric traits and functions for the built-in numeric types.
  • Overloadable operators.
  • Optional values.
  • Panic support in the standard library.
  • Types that pin data to its location in memory.
  • The Rust Prelude
  • This module reexports the primitive types to allow usage that is not possibly shadowed by other declared types.
  • Manually manage memory through raw pointers.
  • Single-threaded reference-counting pointers. ‘Rc’ stands for ‘Reference Counted’.
  • Error handling with the Result type.
  • Utilities for the slice primitive type.
  • Utilities for the str primitive type.
  • A UTF-8–encoded, growable string.
  • Useful synchronization primitives.
  • Types and Traits for working with asynchronous tasks.
  • Native threads.
  • Temporal quantification.
  • u8Deprecation planned
    Redundant constants module for the u8 primitive type.
  • u16Deprecation planned
    Redundant constants module for the u16 primitive type.
  • u32Deprecation planned
    Redundant constants module for the u32 primitive type.
  • u64Deprecation planned
    Redundant constants module for the u64 primitive type.
  • u128Deprecation planned
    Redundant constants module for the u128 primitive type.
  • usizeDeprecation planned
    Redundant constants module for the usize primitive type.
  • A contiguous growable array type with heap-allocated contents, written Vec<T>.
  • assert_matchesExperimental
    Unstable module containing the unstable assert_matches macro.
  • async_iterExperimental
    Composable asynchronous iteration.
  • errorExperimental
    Interfaces for working with Errors.
  • intrinsicsExperimental
    Compiler intrinsics.
  • netExperimental
    Networking primitives for IP communication.
  • panickingExperimental
    Panic support for core
  • simdExperimental
    Portable SIMD module.
  • unicodeExperimental

Macros

  • Asserts that a boolean expression is true at runtime.
  • Asserts that two expressions are equal to each other (using PartialEq).
  • Asserts that two expressions are not equal to each other (using PartialEq).
  • Evaluates boolean combinations of configuration flags at compile-time.
  • Expands to the column number at which it was invoked.
  • Causes compilation to fail with the given error message when encountered.
  • Concatenates literals into a static string slice.
  • Asserts that a boolean expression is true at runtime.
  • Asserts that two expressions are equal to each other.
  • Asserts that two expressions are not equal to each other.
  • Inspects an environment variable at compile time.
  • Prints to the standard error.
  • Prints to the standard error< with a newline.
  • Expands to the file name in which it was invoked.
  • Constructs parameters for the other string-formatting macros.
  • Parses a file as an expression or an item according to the context.
  • Includes a file as a reference to a byte array.
  • Includes a UTF-8 encoded file as a string.
  • Expands to the line number on which it was invoked.
  • Returns whether the given expression matches any of the given patterns.
  • Expands to a string that represents the current module path.
  • 🌟
  • Optionally inspects an environment variable at compile time.
  • Panics the current thread.
  • Prints to the standard output.
  • Prints to the standard output, with a newline.
  • Stringifies its arguments.
  • Indicates unfinished code.
  • tryDeprecated
    Unwraps a result or propagates its error.
  • Indicates unimplemented code by panicking with a message of “not implemented”.
  • Indicates unreachable code.
  • Creates a Vec containing the arguments.
  • cfg_matchExperimental
    A macro for defining #[cfg] match-like statements.
  • concat_bytesExperimental
    Concatenates literals into a byte slice.
  • concat_identsExperimental
    Concatenates identifiers into one identifier.
  • const_format_argsExperimental
    Same as format_args, but can be used in some const contexts.
  • format_args_nlExperimental
    Same as format_args, but adds a newline in the end.
  • log_syntaxExperimental
    Prints passed tokens into the standard output.
  • trace_macrosExperimental
    Enables or disables tracing functionality used for debugging other macros.
  • Writes formatted data into a buffer.
  • Writes formatted data into a buffer, with a newline appended.