Files
rslibc/AGENTS.md
T
portersky 812278a22f feat: add no-std common runtime
Add an alloc-backed common library with direct platform I/O.

Build a host attribute macro for async entry points and keep runtime
boilerplate outside application code. Compile the library, macro, and
example directly with rustc through CMake.

Co-Authored-By: luna (openrouter/openai/gpt-5.6-luna): runtime work
2026-09-05 04:48:25 +02:00

149 lines
4.7 KiB
Markdown

# AGENTS.md
## Project Overview
This project is a small Rust common library and runtime built without Cargo.
CMake invokes `rustc` directly. The library provides a low-footprint subset
of standard-library-like functionality:
- `Result` and formatting from `core`
- `Vec` and `vec![]` from `alloc`
- project-local `print!` and `println!` macros
- direct platform stdout and heap calls
The project contains:
- `src/lib.rs`: the `#![no_std]` common library API
- `src/io.rs`: the `core::fmt::Write` stdout backend
- `src/runtime.rs`: allocator, async polling, and platform entry helpers
- `macros/src/lib.rs`: host-side `#[rslibc_macros::main]` attribute macro
- `runtime/main.rs`: minimal example entry point
- `CMakeLists.txt`: direct `rustc` library, macro, and executable commands
## No-Std Design
- Keep `#![no_std]` in both the library and runtime.
- Do not add Rust `std` to the target library or runtime, and do not add
Cargo unless explicitly requested.
- The host-side procedural macro may use `proc_macro` and host libraries;
it is not linked into the target executable.
- `core` is allowed and is the foundation for `Result`, formatting, slices,
and other basic language-library functionality.
- `alloc` is allowed through `extern crate alloc`; it supplies `Vec` and
related heap-backed types.
- The final runtime must provide its own global allocator and panic handler;
`rslibc::entry!` supplies them to an executable.
- Keep OS integration in small FFI modules. Do not pull in a general-purpose
runtime or C I/O layer for basic output.
- `rslibc_macros::main` can wrap `async fn main()` with the small `block_on`
executor. It is only a polling loop and does not provide Tokio-style I/O,
timers, or a reactor.
- Keep unsafe code inside small safe wrappers. Application code should be
able to use calls such as:
```rust
let values = rslibc::vec![1, 2, 3];
rslibc::println!("values = {:?}", values);
```
## Platform Runtime
- Unix stdout calls libc `write` with file descriptor `1`.
- Windows stdout calls `GetStdHandle` and `WriteFile` through `kernel32`.
- Windows allocation calls `HeapAlloc` and `HeapFree` through the system
heap.
- The Windows runtime dynamically links only the platform support needed by
`alloc` and the compiler runtime. Do not statically link the full C
runtime.
- Keep `panic=abort` enabled.
## Build System
CMake is configured with `LANGUAGES NONE` and invokes `rustc` through three
custom commands:
1. Compile `macros/src/lib.rs` as a host procedural macro.
2. Compile `src/lib.rs` and its modules to `librslibc.rlib`.
3. Compile the minimal `runtime/main.rs` and link it against that rlib.
Configure and build a release executable with Ninja:
```sh
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
cmake --build build
```
Build only the host macro with:
```sh
cmake --build build --target rslibc_macros
```
Build only the common library with:
```sh
cmake --build build --target rslibc_library
```
Run it on Unix:
```sh
./build/rslibc_example
```
Run it on Windows:
```powershell
.\build\rslibc_example.exe
```
`CMAKE_BUILD_TYPE` is translated explicitly to rustc flags:
- `Release`: `-C opt-level=3 -C debuginfo=0`
- `RelWithDebInfo`: `-C opt-level=3 -C debuginfo=2`
- Other or unset configurations: `-C opt-level=0 -C debuginfo=2`
## Verification
After changing the source or build configuration, run a clean release build
and execute the example:
```sh
rm -rf build
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/rslibc_example
```
On Windows, use `Remove-Item -Recurse -Force build` and run
`build\\rslibc_example.exe` instead. Confirm that stdout contains `Hello`.
When size matters, inspect the Windows executable after a release build.
Avoid adding formatting, allocation, or OS dependencies unless they are
needed by the library API.
## Commit Messages
- Follow the 50/72 rule: subject lines are at most 50 characters and body
lines are wrapped at 72 characters.
- Use conventional prefixes such as `feat:`, `fix:`, `docs:`, `chore:`,
and `ci:`.
- Separate the subject from the body with a blank line.
- Keep commit messages concise.
- Include a `Co-Authored-By:` trailer for every agent or model that
contributed to the commit, one trailer per co-author:
```text
Co-Authored-By: qwen (lmstudio/qwen3.6-27b-mtp): wrote tests + build
Co-Authored-By: luna (openrouter/openai/gpt-5.6-luna): reviewed edge cases
```
## Editing Guidelines
- Keep changes minimal and directly related to the request.
- Use four-space indentation in Rust and CMake.
- Keep normal text in Markdown within 80 columns where practical.
- Do not add speculative abstractions or dependencies.
- Update this file when the build workflow, library API, supported
platforms, or source layout changes.