Files
rslibc/README.md
T
portersky cd1c9ab97d docs: add project README
Document the no_std library layout, CMake build flow, platform runtime
behavior, and the async entry macro.

Co-Authored-By: qwen (lmstudio/qwen3.8-27b@q3_k_xl): wrote README
2026-09-05 05:01:34 +02:00

104 lines
2.8 KiB
Markdown

# 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<usize, &str> = 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.