portersky c3a7680e36 docs: note why native CMake Rust is skipped
CMake 4.4's experimental Rust support compiles each source as its own
crate, links libraries into executables as native .lib inputs instead
of --extern, and has no proc-macro crate type. Keep direct rustc.

Co-Authored-By: qwen (lmstudio/qwen3.8-27b@q3_k_xl): documented decision
2026-09-05 05:17:16 +02:00
2026-09-05 05:09:50 +02:00
2026-09-05 04:32:27 +02:00
2026-09-05 04:48:25 +02:00
2026-09-05 05:09:50 +02:00

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, plus String and format!
  • busy-wait sleep on a monotonic clock
  • 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

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

Run the example:

# Unix
./build/rslibc_example
# Windows
.\build\rslibc_example.exe

The release example runs an animated loading loop (progress bar plus spinner) and then prints a short log. The Windows executable is about 27 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

#![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

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.

S
Description
Experimental Rust (Low Memory Footprint)
Readme 53 KiB
Languages
Rust 69.9%
CMake 30.1%