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

4.7 KiB

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:

    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:

cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
cmake --build build

Build only the host macro with:

cmake --build build --target rslibc_macros

Build only the common library with:

cmake --build build --target rslibc_library

Run it on Unix:

./build/rslibc_example

Run it on Windows:

.\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:

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:

    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.