# Rust on MontaukOS Phase 1: `no_std` + `alloc` programs, cross-compiled from Linux with a stock nightly toolchain and a custom target spec. No compiler fork. ## Setup (once) ```bash curl --proto '=https' -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none ~/.cargo/bin/rustup toolchain install nightly --component rust-src ``` `rust-toolchain.toml` selects nightly + `rust-src` for this directory. `make programs` builds the Rust programs when that toolchain is present and prints a notice and skips them otherwise. It never downloads a toolchain (`RUSTUP_AUTO_INSTALL=0`). ## Building ```bash make -C programs rust # cargo build --release, copies to bin/os/*.elf cd programs/rust && cargo build --release ``` Output: `target/x86_64-unknown-montauk/release/`, installed as `programs/bin/os/.elf`. Add new binaries to `RUST_PROGRAMS` in `programs/GNUmakefile` and to the workspace `members`. ## Layout | Path | Purpose | |------|---------| | `x86_64-unknown-montauk.json` | Target spec: static non-PIE ET_EXEC, no red zone, local-exec TLS, panic=abort | | `.cargo/config.toml` | `-Zbuild-std=core,alloc`, linker = `x86_64-montauk-gcc` | | `montauk-rt/` | Runtime: syscalls, allocator, `print!`, argv, threads, futex `Mutex`, panic handler | | `rusthello/` | Smoke test (`rusthello`, `rusthello panic`, `rusthello panic-thread`) | The GCC driver links crt1/crti/crtbegin, the libc and libgcc from `toolchain/sysroot`, the same as ports. After changing `programs/lib/libc`, re-run `toolchain/build-montauk-toolchain.sh` so Rust programs pick it up. Syscall numbers and status codes are generated at build time by `montauk-rt/build.rs` from `programs/include/Api/Syscall.hpp` and `kernel/src/Common/StatusCodes.hpp`, so there is nothing to keep in sync by hand. ## Writing a program ```rust #![no_std] #![no_main] extern crate alloc; montauk_rt::entry!(main); fn main() -> i32 { montauk_rt::println!("hello from Rust"); 0 } ``` ## Limits (Phase 1) - No `std`. No `std::fs`, `std::net`, `std::process` or `std::thread`; use `montauk_rt` equivalents where they exist. - `panic = "abort"`. A panic on any thread prints the message and kills the whole process. - Thread stacks are owned by the `JoinHandle`. An unjoined thread leaks its stack. Phase 2 (a forked rustc at `~/dev/mtk/rust` with a native `target_os = "montauk"` std) replaces the JSON spec with a built-in target.