diff --git a/README.md b/README.md new file mode 100644 index 0000000..d85900d --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# rslibc + +A small `no_std` Rust common library and runtime built without Cargo. +CMake invokes `rustc` directly to compile a host-side proc macro, the +library rlib, and a minimal example executable. + +## Features + +- `Result` and formatting from `core` +- `Vec` and `vec![]` from `alloc` +- project-local `print!` / `println!` macros +- direct platform stdout with no C I/O layer +- OS heap allocator (`malloc`/`free`, `HeapAlloc`/`HeapFree`) +- `panic=abort` with a minimal panic handler +- Tokio-style `#[rslibc_macros::main]` for sync and async entry points + +## Requirements + +- Rust toolchain (`rustc`) on `PATH` +- CMake 3.20 or newer +- A CMake generator such as Ninja + +No Cargo, no `std`, no external crates. + +## Build + +```sh +cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release +cmake --build build +``` + +Run the example: + +```sh +# Unix +./build/rslibc_example +``` + +```powershell +# Windows +.\build\rslibc_example.exe +``` + +The release example prints `Hello, World!`. The Windows executable is +about 4 KiB and depends only on `KERNEL32.dll` and `VCRUNTIME140.dll`. + +Individual targets: + +| Target | Builds | +| ---------------- | ------------------------------- | +| `rslibc_macros` | host-side proc macro DLL | +| `rslibc_library` | `librslibc.rlib` common library | +| `rslibc_example` | example executable (default) | + +## Usage + +```rust +#![no_std] +#![no_main] + +#[rslibc_macros::main] +async fn main() { + let values = rslibc::vec![1, 2, 3]; + let result: rslibc::Result = Ok(values.len()); + rslibc::println!("values = {:?}, result = {:?}", values, result); +} +``` + +The macro renames the user function, then emits a synchronous platform +entry point, the global allocator, the panic handler, and — for async +functions — a call to `rslibc::runtime::block_on`. Plain (non-async) +`fn main()` works the same way. + +## Layout + +```text +macros/src/lib.rs host-side #[rslibc_macros::main] proc macro +src/lib.rs no_std common library API +src/io.rs core::fmt stdout backend +src/runtime.rs allocator, block_on executor, entry helpers +runtime/main.rs minimal example entry point +CMakeLists.txt direct rustc build commands +``` + +## Platform runtime + +- Unix: stdout via libc `write(1, ...)`, allocation via `malloc`/`free`. +- Windows: stdout via `GetStdHandle` + `WriteFile` from `kernel32`, + allocation via `HeapAlloc`/`HeapFree`. Only `kernel32` and + `vcruntime` are linked; a local `strlen` shim keeps the UCRT out. + +## Limitations + +- The async entry point runs on a polling executor: a future that stays + pending spins the CPU. There is no I/O reactor, timers, or task + spawning yet. +- Formatting and allocation pull in parts of `core`/`alloc`; keep the + library surface small when size matters. + +## Documentation + +See `AGENTS.md` for project conventions, build details, and commit +message rules.