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
This commit is contained in:
@@ -2,48 +2,69 @@
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is a minimal Rust experiment that builds one executable without Cargo
|
||||
and without linking Rust `core`, `alloc`, or `std`. CMake invokes `rustc`
|
||||
directly. The executable writes `Hello` to stdout and exits.
|
||||
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:
|
||||
|
||||
The project currently contains:
|
||||
- `Result` and formatting from `core`
|
||||
- `Vec` and `vec![]` from `alloc`
|
||||
- project-local `print!` and `println!` macros
|
||||
- direct platform stdout and heap calls
|
||||
|
||||
- `main.rs`: the `#![no_core]` Rust program
|
||||
- `CMakeLists.txt`: the direct `rustc` custom command
|
||||
- `.gitignore`: ignores generated build output
|
||||
The project contains:
|
||||
|
||||
## Non-Negotiable No-Core Design
|
||||
- `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
|
||||
|
||||
- Keep `#![no_core]` in `main.rs`.
|
||||
- Do not replace `#![no_core]` with `#![no_std]`; `no_std` still links
|
||||
Rust `core`.
|
||||
- Do not add Cargo files or invoke Cargo.
|
||||
- Do not import or link `core`, `alloc`, or `std`.
|
||||
- Keep the required language-item and marker-trait definitions local to
|
||||
`main.rs` unless the user explicitly asks for a different design.
|
||||
- Use primitive Rust types and explicit platform FFI instead of library
|
||||
helpers.
|
||||
- Keep unsafe code inside small safe wrappers. The public call site for
|
||||
stdout should remain a normal string call such as:
|
||||
## 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
|
||||
write_stdout("Hello\\n");
|
||||
let values = rslibc::vec![1, 2, 3];
|
||||
rslibc::println!("values = {:?}", values);
|
||||
```
|
||||
|
||||
## Output Implementation
|
||||
## Platform Runtime
|
||||
|
||||
- Unix builds call the libc `write` function with file descriptor `1`.
|
||||
- Windows builds call `GetStdHandle`, `WriteFile`, and `ExitProcess`
|
||||
directly through `kernel32`.
|
||||
- The Windows build must not link the C runtime. This keeps the executable
|
||||
small and uses `/NODEFAULTLIB` with the `kernel32` import library.
|
||||
- Preserve the safe `write_stdout(&str)` interface when changing output.
|
||||
- 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 calls `rustc` through an
|
||||
`add_custom_command`. `find_program(RUSTC rustc REQUIRED)` locates the
|
||||
compiler.
|
||||
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:
|
||||
|
||||
@@ -52,16 +73,28 @@ 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/no_core_write
|
||||
./build/rslibc_example
|
||||
```
|
||||
|
||||
Run it on Windows:
|
||||
|
||||
```powershell
|
||||
.\build\no_core_write.exe
|
||||
.\build\rslibc_example.exe
|
||||
```
|
||||
|
||||
`CMAKE_BUILD_TYPE` is translated explicitly to rustc flags:
|
||||
@@ -70,28 +103,24 @@ Run it on Windows:
|
||||
- `RelWithDebInfo`: `-C opt-level=3 -C debuginfo=2`
|
||||
- Other or unset configurations: `-C opt-level=0 -C debuginfo=2`
|
||||
|
||||
`no_core` is unstable, so CMake passes `RUSTC_BOOTSTRAP=1` to the direct
|
||||
rustc invocation. A nightly compiler may be used instead, but Cargo is
|
||||
still not permitted.
|
||||
|
||||
## Verification
|
||||
|
||||
After changing the source or build configuration, run a clean release build
|
||||
and execute the program:
|
||||
and execute the example:
|
||||
|
||||
```sh
|
||||
rm -rf build
|
||||
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build
|
||||
./build/no_core_write
|
||||
./build/rslibc_example
|
||||
```
|
||||
|
||||
On Windows, use `Remove-Item -Recurse -Force build` and run
|
||||
`build\\no_core_write.exe` instead. Confirm that stdout contains `Hello`.
|
||||
`build\\rslibc_example.exe` instead. Confirm that stdout contains `Hello`.
|
||||
|
||||
When size matters, inspect the Windows executable size after a release
|
||||
build. Avoid adding runtime libraries, formatting code, or Rust library
|
||||
dependencies.
|
||||
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
|
||||
|
||||
@@ -106,7 +135,7 @@ dependencies.
|
||||
|
||||
```text
|
||||
Co-Authored-By: qwen (lmstudio/qwen3.6-27b-mtp): wrote tests + build
|
||||
Co-Authored-By: luna (openai/gpt-5.6-luna): reviewed edge cases
|
||||
Co-Authored-By: luna (openrouter/openai/gpt-5.6-luna): reviewed edge cases
|
||||
```
|
||||
|
||||
## Editing Guidelines
|
||||
@@ -115,5 +144,5 @@ dependencies.
|
||||
- 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, no-core constraints, supported
|
||||
- Update this file when the build workflow, library API, supported
|
||||
platforms, or source layout changes.
|
||||
|
||||
Reference in New Issue
Block a user