From 78317bfa1f941a2d8d0f83966c03921509fe76e4 Mon Sep 17 00:00:00 2001 From: japabu Date: Thu, 1 Oct 2026 06:30:45 +0200 Subject: [PATCH 01/11] M2: bootstrap builds LLVM, clang and LLD for a ToyOS host as far as libc lets it Moves `rust` to ToyOSOrg/rust f066099a351, which carries four bootstrap commits and LLVM's ToyOS arms in `Support`: - `configure_cmake` names CMake's system `ToyOS` for a ToyOS target, where it fell to `Generic` and LLVM compiled no `Unix/` implementation of `Support`. - With an external host `llvm-config`, `clang-tblgen` is taken from `llvm-config --bindir`, where `llvm-tblgen` already was, rather than from a host build directory bootstrap never made. - The `Lld` step builds LLD for a target whose LLVM bootstrap builds, where it returned the host's LLD from beside the host's `llvm-config`. - `src/llvm-project` moves to ToyOSOrg/llvm-project ceaf0fbb8: `bit.h` takes ToyOS's ``, and `is_local_impl` calls every ToyOS file local. The fork's main had moved to 2df0b60efd0, #659's std change merged beside #650's, so f066099a351 merges it and this branch carries both. `issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md` now says what stops the build in the order it stops it, all outside bootstrap and LLVM; `issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md` holds the five names no issue held; the M2 track lists them. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- ...ild-llvm-clang-and-lld-for-a-toyos-host.md | 66 +++++++++---------- ...lacks-names-llvm-for-a-toyos-host-calls.md | 23 +++++++ issues/build/toyos-builds-itself.md | 19 ++++-- rust | 2 +- 4 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index 91ecaef0d40..5a175b36eb2 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -6,41 +6,41 @@ opened: 2026-09-30 # Bootstrap cannot build LLVM, clang and lld for a ToyOS host -M2's clang and lld (`issues/build/toyos-builds-itself.md`) are LLVM built for -`x86_64-unknown-toyos`. Read from the fork at `rust/` and from -`src/llvm-project` at `849da7d62`, not run, four things stop bootstrap's LLVM -step for that target: +M2's clang and lld (`issues/build/toyos-builds-itself.md`) are bootstrap's +`Llvm` step, with `clang = true`, and its `Lld` step for +`x86_64-unknown-toyos`, with the store's LLVM (`src/llvm.rs`) as the host's +`llvm-config`. Bootstrap and LLVM carry what is theirs: CMake is told the +system `ToyOS`, `clang-tblgen` is the host LLVM's, LLD is built for a target +whose LLVM bootstrap builds, and LLVM's `Support` reads POSIX's `` +and calls every ToyOS file local. What stops the build is not theirs, in the +order it stops it: -- **`clang-tblgen`.** With `clang = true`, the step for a target that is not - the host panics unless `clang-tblgen` is in the CMake build directory of a - host LLVM bootstrap built itself - (`src/bootstrap/src/core/build_steps/llvm.rs`, `CLANG_TABLEGEN`). Every - compiler build here names the store's LLVM (`src/llvm.rs`) as the host's - `llvm-config`, so bootstrap builds no host LLVM and the file is never there. -- **Its CMake system.** `configure_cmake` names no system for a ToyOS target and - falls back to `Generic`, under which LLVM sets `LLVM_ON_UNIX` to 0 - (`llvm/cmake/modules/HandleLLVMOptions.cmake`) and compiles no `Unix/` - implementation of `Support`. -- **`bit.h`.** `llvm/include/llvm/ADT/bit.h` includes `` on the - systems it lists and `` on any other, ToyOS among them. -- **`is_local_impl`.** `llvm/lib/Support/Unix/Path.inc` reads the BSDs' - `MNT_LOCAL` on a system it does not list. +- **CMake knows no ToyOS**, so `UNIX` is unset and LLVM's configure refuses, + `Unable to determine platform` + (`issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`). +- **Compile.** The first error is `sigemptyset`, undeclared in `Support`'s + `CrashRecoveryContext.cpp`: stage 3's signal-set calls, `wait` and `wait4` + (`issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md`) + and `alarm` (`issues/build/libc-has-no-alarm.md`). Then ORC's `shm_open` and + `shm_unlink`, the interpreter's `scanf` and `llvm-objdump`'s `ctime` + (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), and + clang's `std::ifstream`, which libc++ has only with `std::filesystem`. Built + with it, libc++ asks libc for `setbuf`, `fseeko`, `ftello`, `utimes`, + `truncate`, `pathconf`, `openat`, `unlinkat`, `fdopendir`, `_PC_PATH_MAX`, + `O_DIRECTORY`, `O_NOFOLLOW`, `AT_FDCWD` and `AT_REMOVEDIR` + (`issues/build/libcxx-is-built-without-std-filesystem.md`). +- **Link.** clang needs `lround`, which libc does not define + (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), beside + those above. LLVM's shared libraries, `libLTO`, `libRemarks`, `libclang` and + `libclang-cpp`, do not link against the C sysroot, whose archives are built + for an executable + (`issues/build/a-rust-std-binary-cannot-link-the-cxx-runtime.md`); clang and + lld use none of them. -The last three are ToyOS arms at existing dispatch sites, written as upstream -would take them. ToyOS joins `bit.h`'s `` list, so libc carries -POSIX's `endian.h` (`userland/libc/include/endian.h`) and no BSD name. With -those two arms on `849da7d62` and CMake told the system by hand, the 71 -libraries rustc links compile against the C sysroot but for five objects of -`LLVMSupport`, which stop on `alarm` and on stage 3's `wait`, `wait4` and -signal-set calls; without them, every object that includes `bit.h` stops. -Bootstrap's arm names the system `ToyOS`, which LLVM's configure refuses, -`Unable to determine platform`, until CMake knows ToyOS and sets `UNIX` -(`issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`). - -`clang-tblgen` is no arm, and neither bootstrap nor LLVM changes for it: ToyOS's -build builds the LLVM for a ToyOS host in a bootstrap build that built the -host's LLVM itself, as `src/llvm.rs` builds the store's, never in a compiler -build that names the store's. +With each name declared and defined to abort, libc++ built with +`std::filesystem` against them, the four shared libraries' build options off, +and a `Platform/ToyOS.cmake` on CMake's module path, bootstrap installs clang +and `ld.lld` for `x86_64-unknown-toyos`. **Exit**: bootstrap, with `clang = true`, installs a clang and an `ld.lld` for `x86_64-unknown-toyos`. diff --git a/issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md b/issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md new file mode 100644 index 00000000000..c8deacd4f37 --- /dev/null +++ b/issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md @@ -0,0 +1,23 @@ +--- +status: open +kind: defect +opened: 2026-10-01 +--- + +# libc lacks names LLVM for a ToyOS host calls + +LLVM, clang and lld built for `x86_64-unknown-toyos` +(`issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md`) +call five names libc neither declares nor defines: + +- `shm_open` and `shm_unlink`, with which ORC maps memory on every Unix but + Android (`llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp`, + `TargetProcess/ExecutorSharedMemoryMapperService.cpp`). +- `scanf`, which LLVM's interpreter hands an interpreted program + (`llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp`). +- `ctime`, with which `llvm-objdump` prints a file's time stamp. +- `lround`, which libc++'s `std::lround` calls, from clang's `Basic` and its + static analyzer: clang does not link without it. + +**Exit**: libc declares and defines each, doing what POSIX says or refusing in +POSIX's form, asserted by a guest C case that reads its effect back. diff --git a/issues/build/toyos-builds-itself.md b/issues/build/toyos-builds-itself.md index 53db17f659b..1e7910f3a69 100644 --- a/issues/build/toyos-builds-itself.md +++ b/issues/build/toyos-builds-itself.md @@ -54,13 +54,18 @@ goes when lld runs in the guest: the row, the crate and its host tests go togeth the published crates.io crate is yanked. **What stops M2: LLVM, clang and lld built for a ToyOS host**, in the order -each blocks the next. -- Configure: the `clang-tblgen` and the CMake system of - `issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md`. -- Compile: the bootstrap issue's `bit.h` and `is_local_impl`, and the - signal-set calls, `wait` and `wait4` of the child-process track's stage 3 - with `issues/build/libc-has-no-alarm.md`. -- Link: the same stage 3 names and `alarm`. +each blocks the next, as +`issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md` +measures it. +- Configure: CMake's ToyOS, + `issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`. +- Compile: the signal-set calls, `wait` and `wait4` of the child-process + track's stage 3 with `issues/build/libc-has-no-alarm.md`, + `issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`, and + `issues/build/libcxx-is-built-without-std-filesystem.md`. +- Link: the same names. +- Build: ToyOS's build runs bootstrap for no ToyOS host; `src/llvm.rs` builds + the host's LLVM alone. - Run: what `issues/build/libc-refuses-what-toyos-cannot-yet-answer.md` lists, `issues/build/libc-has-no-pread-or-pwrite.md`, and `issues/build/libc-stat-answers-one-serial-number-for-every-file.md`. diff --git a/rust b/rust index 9151571cae9..f066099a351 160000 --- a/rust +++ b/rust @@ -1 +1 @@ -Subproject commit 9151571cae9014619926872b12fcebf3b0a3c14a +Subproject commit f066099a351064408eb4f927291f31bcff987745 From 23fe451dbf65061b17540009d377ff0b9681ee6a Mon Sep 17 00:00:00 2001 From: japabu Date: Thu, 1 Oct 2026 07:24:27 +0200 Subject: [PATCH 02/11] rust: pin wt-toyos-m2, main's pin with #650's std and the ToyOS LLVM arms alone The previous pin, f066099a351, merged the fork's moved main and with it #659's std commit 336c8a8e141, which builds `SpawnArgs { place, .. }` and calls `toyos::endow::this_process()`: neither exists in this tree, so the toolchain did not build here. The pin is now 61adcea7362 on the fork's `wt-toyos-m2`: main's pin aca5f527fcb, #650's 9151571cae9 (std's `aligned_alloc`, which this branch's libc relies on), the `configure_cmake` arm that names CMake's system `ToyOS` (25da73337eb), `src/llvm-project` at ceaf0fbb8 (`bit.h`'s `` and `is_local_impl`'s arms), and two reverts. `clang-tblgen` from an external host LLVM (61f2a91fffa, df7bd9c942e) and LLD only beside the target's own `llvm-config` (d622a37189e) were cross-platform changes to bootstrap, made to suit the store's host LLVM: a bootstrap build that names no `llvm-config` for the build triple needs neither, because it builds that triple's LLVM itself, with `clang-tblgen` in its build directory and no `lld` beside its `llvm-config`. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- rust | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust b/rust index f066099a351..61adcea7362 160000 --- a/rust +++ b/rust @@ -1 +1 @@ -Subproject commit f066099a351064408eb4f927291f31bcff987745 +Subproject commit 61adcea736292d85bd311f0b9c568aa44cc315c0 From 9dc023fc1389a2afa3e8e37fe5709c128556b925 Mon Sep 17 00:00:00 2001 From: japabu Date: Thu, 1 Oct 2026 07:24:47 +0200 Subject: [PATCH 03/11] build: every C sysroot carries CMake's ToyOS, a toolchain file and its platform module CMake ships no platform module for ToyOS, so a configure that names the system `ToyOS` prints `System is unknown to cmake` and leaves `UNIX` unset: `src/libcxx.rs` set `UNIX=ON` by hand, and LLVM's configure for a ToyOS host refuses, `Unable to determine platform`. Each C sysroot now carries what CMake's own answer to an unknown system asks for, as wasi-sdk and Emscripten carry theirs: `Platform/ToyOS.cmake` and `Platform/ToyOS-Initialize.cmake`, laid out as CMake's `Modules/Platform` lays out a Unix-like system (the `-Initialize` module sets `UNIX` before the compiler is identified, the other includes `Platform/UnixPaths`; `dlopen` is the C library's, so `CMAKE_DL_LIBS` is empty), and `toolchain.cmake`, which names the system, the processor, the target and the sysroot it sits in, and puts the platform module on CMake's module path. It names no compiler: the caller's are its own. One declaration, `clang::CMAKE`, is written by `libc::build_c` and is part of the sysroot's key. `src/libcxx.rs` configures with the toolchain file instead of `CMAKE_SYSTEM_NAME`, `UNIX`, the processor, the target and the sysroot. Bootstrap's LLVM and LLD steps take the same file from `CMAKE_TOOLCHAIN_FILE_x86_64_unknown_toyos`, which cmake-rs reads for both, so bootstrap needs no change for it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- src/clang.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libc.rs | 7 +++--- src/libcxx.rs | 19 +++++---------- src/sysroot.rs | 13 +++++----- 4 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index 8473447f5e3..d2d180a66a5 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -40,6 +40,28 @@ pub(crate) const LLVM_CONFIG: &str = "download-ci-llvm = false\n\ /// What a toolchain directory's `bin` must hold for C. const TOOLS: [&str; 3] = ["llvm-ar", "clang", "ld.lld"]; +/// CMake's description of ToyOS, which CMake does not ship, as every C sysroot +/// carries it: a toolchain file that names the system, the target and the +/// sysroot it sits in, and puts beside it on CMake's module path the platform +/// module, laid out as CMake's `Modules/Platform` lays out a Unix-like system. +/// The compilers are the caller's. `@PROCESSOR@` and `@TARGET@` are the +/// sysroot's. +pub(crate) const CMAKE: [(&str, &str); 3] = [ + ( + "toolchain.cmake", + "set(CMAKE_SYSTEM_NAME ToyOS)\n\ + set(CMAKE_SYSTEM_PROCESSOR @PROCESSOR@)\n\ + set(CMAKE_SYSROOT \"${CMAKE_CURRENT_LIST_DIR}\")\n\ + set(CMAKE_C_COMPILER_TARGET @TARGET@)\n\ + set(CMAKE_CXX_COMPILER_TARGET @TARGET@)\n\ + set(CMAKE_ASM_COMPILER_TARGET @TARGET@)\n\ + list(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")\n", + ), + ("Platform/ToyOS-Initialize.cmake", "set(UNIX 1)\n"), + // `dlopen` and its kin are the C library's own. + ("Platform/ToyOS.cmake", "set(CMAKE_DL_LIBS \"\")\n\ninclude(Platform/UnixPaths)\n"), +]; + /// `lib/rustlib//bin` of `toolchain`, where `rust-lld` is. fn bin(toolchain: &Path) -> PathBuf { toolchain.join("lib/rustlib").join(host_triple()).join("bin") @@ -56,6 +78,8 @@ pub struct CSysroot { pub ar: PathBuf, /// The guest target, as clang's `--target` spells it. pub target: &'static str, + /// Its architecture, as CMake's `CMAKE_SYSTEM_PROCESSOR` spells it. + processor: &'static str, } impl CSysroot { @@ -67,6 +91,23 @@ impl CSysroot { clang: bin(toolchain).join("clang"), ar: bin(toolchain).join("llvm-ar"), target, + processor: arch.name(), + } + } + + /// Its CMake toolchain file, the first of [`CMAKE`]. + pub fn cmake_toolchain(&self) -> PathBuf { + self.dir.join(CMAKE[0].0) + } + + /// Write [`CMAKE`] into it. + pub fn write_cmake(&self) { + for (name, text) in CMAKE { + let path = self.dir.join(name); + let parent = path.parent().expect("a file in the sysroot"); + fs::create_dir_all(parent).unwrap_or_else(|e| panic!("create {}: {e}", parent.display())); + let text = text.replace("@PROCESSOR@", self.processor).replace("@TARGET@", self.target); + fs::write(&path, text).unwrap_or_else(|e| panic!("write {}: {e}", path.display())); } } @@ -228,4 +269,28 @@ mod tests { fs::remove_file(bin(&stage2).join("llvm-ar")).unwrap(); assert!(defect(&stage2).is_some(), "a missing llvm-ar went unnoticed"); } + + /// **A C sysroot's toolchain file names a system whose platform module is + /// where it puts CMake's module path**, and its architecture and target + /// are the sysroot's. + #[test] + fn the_cmake_toolchain_finds_its_platform_module() { + let base = TempDir::new("cmake"); + let c = CSysroot::of(&base, Arch::Aarch64); + c.write_cmake(); + let toolchain = fs::read_to_string(c.cmake_toolchain()).unwrap(); + assert!(!toolchain.contains('@'), "a placeholder is left: {toolchain}"); + for line in ["set(CMAKE_SYSTEM_PROCESSOR aarch64)", "set(CMAKE_CXX_COMPILER_TARGET aarch64-unknown-toyos)"] { + assert!(toolchain.lines().any(|l| l == line), "no {line} in {toolchain}"); + } + assert!(toolchain.contains("list(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")"), "{toolchain}"); + let system = toolchain + .lines() + .find_map(|l| l.strip_prefix("set(CMAKE_SYSTEM_NAME ")?.strip_suffix(')')) + .expect("a system name"); + for module in [format!("{system}.cmake"), format!("{system}-Initialize.cmake")] { + let path = c.cmake_toolchain().with_file_name("Platform").join(module); + assert!(path.is_file(), "{} is missing", path.display()); + } + } } diff --git a/src/libc.rs b/src/libc.rs index b7728248db8..b4ffba8e3b8 100644 --- a/src/libc.rs +++ b/src/libc.rs @@ -110,14 +110,15 @@ pub fn build_c(root: &Path, toolchain: &Path, target_dir: &Path, arch: Arch) { "toyos-libc's staticlib for {target} did not build:\n{}", String::from_utf8_lossy(&output.stderr), ); - let c = crate::clang::CSysroot::of(toolchain, arch).dir; - let lib = c.join("lib"); + let c = crate::clang::CSysroot::of(toolchain, arch); + let lib = c.dir.join("lib"); fs::create_dir_all(&lib).unwrap_or_else(|e| panic!("create {}: {e}", lib.display())); let archive = target_dir.join(format!("{target}/release/libtoyos_libc.a")); fs::copy(&archive, lib.join("libtoyos_c.a")) .unwrap_or_else(|e| panic!("copy {} into {}: {e}", archive.display(), lib.display())); empty_libraries(&lib); - crate::sysroot::clone_tree(&root.join(CRATE).join("include"), &c.join("include")); + crate::sysroot::clone_tree(&root.join(CRATE).join("include"), &c.dir.join("include")); + c.write_cmake(); } /// The libraries POSIX has a C compiler take, `-lc` and `-lm` among them, whose diff --git a/src/libcxx.rs b/src/libcxx.rs index a9027628d2a..abac7d228df 100644 --- a/src/libcxx.rs +++ b/src/libcxx.rs @@ -12,7 +12,6 @@ use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; -use crate::arch::Arch; use crate::clang::CSysroot; /// This file, which the release tag hashes. @@ -23,14 +22,10 @@ pub(crate) const SOURCE: &str = file!(); /// compiles in. pub(crate) const SOURCES: [&str; 7] = ["runtimes", "cmake", "llvm/cmake", "libunwind", "libcxxabi", "libcxx", "libc"]; -/// The runtimes' CMake options beyond the target's and the tools'. -pub(crate) const OPTIONS: [(&str, &str); 20] = [ +/// The runtimes' CMake options beyond the target's, which the C sysroot's +/// toolchain file names (`clang::CMAKE`), and the tools'. +pub(crate) const OPTIONS: [(&str, &str); 18] = [ ("CMAKE_BUILD_TYPE", "Release"), - // CMake has no platform module for ToyOS, and `UNIX` is how it says what - // the runtimes' build needs to know of one: an ELF system with POSIX threads - // (`issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`). - ("CMAKE_SYSTEM_NAME", "ToyOS"), - ("UNIX", "ON"), ("LLVM_ENABLE_RUNTIMES", "libunwind;libcxxabi;libcxx"), ("LLVM_INCLUDE_TESTS", "OFF"), ("LLVM_INCLUDE_DOCS", "OFF"), @@ -94,10 +89,10 @@ pub fn ninja(root: &Path) -> PathBuf { ninja } -/// Build `arch`'s C++ runtime from the runtimes' `sources` into `c`, which holds +/// Build `c`'s C++ runtime from the runtimes' `sources` into it, which holds /// the C library already, under `ninja`, in `scratch`, which it removes when /// done. -pub fn build(c: &CSysroot, arch: Arch, sources: &Path, ninja: &Path, scratch: &Path) { +pub fn build(c: &CSysroot, sources: &Path, ninja: &Path, scratch: &Path) { eprintln!("Building the C++ runtime for {} under {}", c.target, ninja.display()); if scratch.exists() { fs::remove_dir_all(scratch).unwrap_or_else(|e| panic!("remove {}: {e}", scratch.display())); @@ -110,14 +105,12 @@ pub fn build(c: &CSysroot, arch: Arch, sources: &Path, ninja: &Path, scratch: &P .unwrap_or_else(|e| panic!("symlink {} -> {}: {e}", ranlib.display(), c.ar.display())); let path = |p: &Path| p.display().to_string(); let mut definitions: Vec<(String, String)> = OPTIONS.iter().map(|(n, v)| (n.to_string(), v.to_string())).collect(); - definitions.push(("CMAKE_SYSTEM_PROCESSOR".into(), arch.name().into())); + definitions.push(("CMAKE_TOOLCHAIN_FILE".into(), path(&c.cmake_toolchain()))); for lang in ["C", "CXX", "ASM"] { definitions.push((format!("CMAKE_{lang}_COMPILER"), path(&c.clang))); - definitions.push((format!("CMAKE_{lang}_COMPILER_TARGET"), c.target.into())); } definitions.push(("CMAKE_AR".into(), path(&c.ar))); definitions.push(("CMAKE_RANLIB".into(), path(&ranlib))); - definitions.push(("CMAKE_SYSROOT".into(), path(&c.dir))); definitions.push(("CMAKE_INSTALL_PREFIX".into(), path(&c.dir))); definitions.push(("CMAKE_MAKE_PROGRAM".into(), path(ninja))); diff --git a/src/sysroot.rs b/src/sysroot.rs index 1112f497de1..1bc5ce4679f 100644 --- a/src/sysroot.rs +++ b/src/sysroot.rs @@ -65,9 +65,9 @@ const SOURCES: &str = "SOURCES"; /// std build's recipe below. Moving it moves every key. const RECIPE: &str = "bootstrap stage-0 local rebuild, profile compiler, no LLVM or Ninja, \ libtoyos_c merged, libraries from the stamp, linked by rust-lld, \ - a C sysroot of libc's staticlib, the empty libraries beside it, and headers \ - per target, and its C++ runtime built under n2 from the runtimes' sources \ - of the compiler's LLVM; 10"; + a C sysroot of libc's staticlib, the empty libraries beside it, headers and \ + CMake's description of ToyOS per target, and its C++ runtime built under n2 \ + from the runtimes' sources of the compiler's LLVM; 10"; /// Every sysroot on this host. pub fn sysroots_dir(rust_dir: &Path) -> PathBuf { @@ -193,9 +193,10 @@ fn source_files(checkout: &Path, paths: &[&str], out: &mut Vec) { pub fn key(root: &Path, compiler: &Compiler, fork: &Path) -> String { let parts = [ format!( - "{RECIPE}; cargo {STAGE0_CARGO}; targets {}; C++ runtime {:?}", + "{RECIPE}; cargo {STAGE0_CARGO}; targets {}; C++ runtime {:?}; CMake {:?}", GUEST_TARGETS.join(" "), - crate::libcxx::OPTIONS + crate::libcxx::OPTIONS, + crate::clang::CMAKE, ), witness(root), tree_identity(fork, &["library", "src/bootstrap"]), @@ -355,7 +356,7 @@ fn build(root: &Path, rust_dir: &Path, compiler: &Compiler, fork: &Path, key: &s for arch in Arch::ALL { let scratch = dir.with_extension(format!("libcxx-{}", arch.name())); let c = crate::clang::CSysroot::of(partial, arch); - crate::libcxx::build(&c, arch, &llvm.dir.join("src"), &ninja, &scratch); + crate::libcxx::build(&c, &llvm.dir.join("src"), &ninja, &scratch); } // The sources the key named are the ones built, or this is not that key's. From 03cb0453b8e59cd5624a94ea74cea341deb434da Mon Sep 17 00:00:00 2001 From: japabu Date: Thu, 1 Oct 2026 09:23:39 +0200 Subject: [PATCH 04/11] issues: M2's route needs no bootstrap change; CMake's ToyOS met; shared objects recorded `bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md` names the route the build takes, a bootstrap build that builds the build triple's LLVM and `clang-tblgen` itself, and the C sysroot's toolchain file as what CMake reads. Its exit names ToyOS's own build with nothing supplied by hand: a measurement with every missing name stubbed already installs clang and `ld.lld`. It decides the four shared libraries, `libLTO`, `libRemarks`, `libclang` and `libclang-cpp`: clang and lld use none, so ToyOS's build turns them off. `a-shared-object-does-not-link-against-the-c-sysroot.md` is what stops those four, measured in the stubbed build's tree with `ninja -k 0`: `main` and `__tls_get_addr` undefined in each but `libclang-cpp`, `R_X86_64_TPOFF32` against libc++abi's `eh_globals` in `libLTO` and `libclang`, and 20 `R_X86_64_PC32` against libc++'s stream and `regex_error` vtables in `libclang-cpp` before lld stopped counting. `the-cxx-runtime-names-toyos-to-cmake-as-unix.md` is met and closed: `src/libcxx.rs` sets no `UNIX`, and with the C sysroot's toolchain file neither the runtimes' configure nor LLVM's for a ToyOS host prints `System is unknown to cmake`, where #650's definitions printed it 77 times in the runtimes' configure. `cmake-ships-no-platform-module-for-toyos.md` records that the module is carried in the SDK until CMake ships it. The track's Configure, Compile, Link and Build bullets copied the bootstrap issue and go; its pointer to that issue stays. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L --- ...ect-does-not-link-against-the-c-sysroot.md | 28 +++++++++++++++++++ ...ild-llvm-clang-and-lld-for-a-toyos-host.md | 28 ++++++------------- ...make-ships-no-platform-module-for-toyos.md | 16 +++++++++++ ...xx-runtime-names-toyos-to-cmake-as-unix.md | 20 ------------- issues/build/toyos-builds-itself.md | 9 ------ 5 files changed, 53 insertions(+), 48 deletions(-) create mode 100644 issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md create mode 100644 issues/build/cmake-ships-no-platform-module-for-toyos.md delete mode 100644 issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md diff --git a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md new file mode 100644 index 00000000000..d89320860f6 --- /dev/null +++ b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md @@ -0,0 +1,28 @@ +--- +status: open +kind: defect +opened: 2026-10-01 +--- + +# A shared object does not link against the C sysroot + +ToyOS loads shared objects, a program's `DT_NEEDED` and `dlopen`'s, and its +clang links one with `-shared`. None links against the C sysroot: LLVM built +for `x86_64-unknown-toyos` +(`issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md`) +builds `libLTO`, `libRemarks`, `libclang` and `libclang-cpp`, linked +`-shared -z defs`, and each stops on what the sysroot's archives were built +for, an executable: + +- `main`, undefined: `libtoyos_c.a`'s entry point, `start_c`, sits in an + object the link takes for other names. +- `__tls_get_addr`, undefined: a shared object reaches a thread-local, its own + (LLVM's `PrettyStackTrace.cpp`, clang's `Stack.cpp`) or libc's, through it, + and only std defines it. +- `R_X86_64_TPOFF32` against libc++abi's `eh_globals`, and `R_X86_64_PC32` + against libc++'s vtables: the C++ runtime is compiled for an executable + (`issues/build/a-rust-std-binary-cannot-link-the-cxx-runtime.md`). + +**Exit**: a C and a C++ shared object link against the C sysroot with +`-z defs`, LLVM's four build for ToyOS with their options on, and a guest case +`dlopen`s the C one and calls into it. diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index 5a175b36eb2..a0c18d8e011 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -8,16 +8,12 @@ opened: 2026-09-30 M2's clang and lld (`issues/build/toyos-builds-itself.md`) are bootstrap's `Llvm` step, with `clang = true`, and its `Lld` step for -`x86_64-unknown-toyos`, with the store's LLVM (`src/llvm.rs`) as the host's -`llvm-config`. Bootstrap and LLVM carry what is theirs: CMake is told the -system `ToyOS`, `clang-tblgen` is the host LLVM's, LLD is built for a target -whose LLVM bootstrap builds, and LLVM's `Support` reads POSIX's `` -and calls every ToyOS file local. What stops the build is not theirs, in the +`x86_64-unknown-toyos`, in a bootstrap build that names no `llvm-config` for +the build triple and so builds that triple's LLVM, and its `clang-tblgen`, +itself. CMake takes the C sysroot's `toolchain.cmake` from +`CMAKE_TOOLCHAIN_FILE_x86_64_unknown_toyos`. What stops the build, in the order it stops it: -- **CMake knows no ToyOS**, so `UNIX` is unset and LLVM's configure refuses, - `Unable to determine platform` - (`issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`). - **Compile.** The first error is `sigemptyset`, undeclared in `Support`'s `CrashRecoveryContext.cpp`: stage 3's signal-set calls, `wait` and `wait4` (`issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md`) @@ -32,15 +28,9 @@ order it stops it: - **Link.** clang needs `lround`, which libc does not define (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), beside those above. LLVM's shared libraries, `libLTO`, `libRemarks`, `libclang` and - `libclang-cpp`, do not link against the C sysroot, whose archives are built - for an executable - (`issues/build/a-rust-std-binary-cannot-link-the-cxx-runtime.md`); clang and - lld use none of them. + `libclang-cpp`, do not link against the C sysroot + (`issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md`). + clang and lld use none of them, and ToyOS's build turns them off. -With each name declared and defined to abort, libc++ built with -`std::filesystem` against them, the four shared libraries' build options off, -and a `Platform/ToyOS.cmake` on CMake's module path, bootstrap installs clang -and `ld.lld` for `x86_64-unknown-toyos`. - -**Exit**: bootstrap, with `clang = true`, installs a clang and an `ld.lld` for -`x86_64-unknown-toyos`. +**Exit**: ToyOS's build, with nothing supplied by hand, has bootstrap install +a clang and an `ld.lld` for `x86_64-unknown-toyos`. diff --git a/issues/build/cmake-ships-no-platform-module-for-toyos.md b/issues/build/cmake-ships-no-platform-module-for-toyos.md new file mode 100644 index 00000000000..7d41eead640 --- /dev/null +++ b/issues/build/cmake-ships-no-platform-module-for-toyos.md @@ -0,0 +1,16 @@ +--- +status: open +kind: tooling +opened: 2026-10-01 +--- + +# CMake ships no platform module for ToyOS, and each C sysroot carries one + +CMake knows a system by its `Modules/Platform/.cmake` and ships none for +ToyOS. Each C sysroot carries `Platform/ToyOS.cmake` and +`Platform/ToyOS-Initialize.cmake` beside the `toolchain.cmake` that puts them +on CMake's module path (`src/clang.rs`, `CMAKE`). No upstream merge request +carries them, because none is sent for now. + +**Exit**: CMake ships ToyOS's platform module, and the C sysroot carries only +its toolchain file. diff --git a/issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md b/issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md deleted file mode 100644 index a2c8085f6f4..00000000000 --- a/issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -status: open -kind: defect -opened: 2026-09-30 ---- - -# The C++ runtime's configure names ToyOS to CMake as `UNIX` - -CMake has no platform module for ToyOS, so `src/libcxx.rs` configures the -runtimes with `CMAKE_SYSTEM_NAME=ToyOS` and sets `UNIX=ON` beside it: the one -fact a platform module would give that the runtimes' build branches on. CMake -says so on every configure, once per check it runs: `System is unknown to -cmake, create: Platform/ToyOS to use this system`. Everything else a platform -module sets (library prefixes and suffixes, search paths, the shared-library -flags) CMake leaves at its defaults, which the runtimes' static-only build -happens not to read. - -**Exit**: CMake knows ToyOS, a `Modules/Platform/ToyOS.cmake` that sets what -its Unix-like neighbours set, and `UNIX=ON` goes from `src/libcxx.rs` with the -line every configure prints. diff --git a/issues/build/toyos-builds-itself.md b/issues/build/toyos-builds-itself.md index 1e7910f3a69..efacf81a8e3 100644 --- a/issues/build/toyos-builds-itself.md +++ b/issues/build/toyos-builds-itself.md @@ -57,15 +57,6 @@ the published crates.io crate is yanked. each blocks the next, as `issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md` measures it. -- Configure: CMake's ToyOS, - `issues/build/the-cxx-runtime-names-toyos-to-cmake-as-unix.md`. -- Compile: the signal-set calls, `wait` and `wait4` of the child-process - track's stage 3 with `issues/build/libc-has-no-alarm.md`, - `issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`, and - `issues/build/libcxx-is-built-without-std-filesystem.md`. -- Link: the same names. -- Build: ToyOS's build runs bootstrap for no ToyOS host; `src/llvm.rs` builds - the host's LLVM alone. - Run: what `issues/build/libc-refuses-what-toyos-cannot-yet-answer.md` lists, `issues/build/libc-has-no-pread-or-pwrite.md`, and `issues/build/libc-stat-answers-one-serial-number-for-every-file.md`. From 39d8d3eee756fb1fd4620a05f70b9d6fe950b320 Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 13:28:04 +0200 Subject: [PATCH 05/11] clang: the sysroot build is the check of CMake's ToyOS; its unit test goes `the_cmake_toolchain_finds_its_platform_module` held three string constants that sit side by side in `CMAKE` to each other, which a reader does, and it stayed green with the system named `Toyos` on a host whose file system ignores case. CMake is the judge of those files and already runs on them: every sysroot build configures both architectures' C++ runtime through the toolchain file, and a platform module CMake does not find ends that configure with LLVM's `Unable to determine platform`. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- src/clang.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/clang.rs b/src/clang.rs index d2d180a66a5..3da13297ba6 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -269,28 +269,4 @@ mod tests { fs::remove_file(bin(&stage2).join("llvm-ar")).unwrap(); assert!(defect(&stage2).is_some(), "a missing llvm-ar went unnoticed"); } - - /// **A C sysroot's toolchain file names a system whose platform module is - /// where it puts CMake's module path**, and its architecture and target - /// are the sysroot's. - #[test] - fn the_cmake_toolchain_finds_its_platform_module() { - let base = TempDir::new("cmake"); - let c = CSysroot::of(&base, Arch::Aarch64); - c.write_cmake(); - let toolchain = fs::read_to_string(c.cmake_toolchain()).unwrap(); - assert!(!toolchain.contains('@'), "a placeholder is left: {toolchain}"); - for line in ["set(CMAKE_SYSTEM_PROCESSOR aarch64)", "set(CMAKE_CXX_COMPILER_TARGET aarch64-unknown-toyos)"] { - assert!(toolchain.lines().any(|l| l == line), "no {line} in {toolchain}"); - } - assert!(toolchain.contains("list(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")"), "{toolchain}"); - let system = toolchain - .lines() - .find_map(|l| l.strip_prefix("set(CMAKE_SYSTEM_NAME ")?.strip_suffix(')')) - .expect("a system name"); - for module in [format!("{system}.cmake"), format!("{system}-Initialize.cmake")] { - let path = c.cmake_toolchain().with_file_name("Platform").join(module); - assert!(path.is_file(), "{} is missing", path.display()); - } - } } From 33d7f1f763ab8b70a5295ee08faf3e10ed48a8cd Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 14:25:21 +0200 Subject: [PATCH 06/11] rust: bootstrap is main's again; the pin carries LLVM's two ToyOS arms alone The gitlink is the fork's 95960d6c214, which reverts `configure_cmake`'s `toyos` arm (25da73337eb) on top of 01b8626673f. The C sysroot's toolchain file names the system to CMake, and with it the arm decided nothing: bootstrap's own configure command for the `Llvm` step, run with the arm's `-DCMAKE_SYSTEM_NAME=ToyOS` and with the `Generic` bootstrap defines for a target it has no arm for, wrote byte-identical `CMakeSystem.cmake`, `llvm-config.h`, `config.h` and `build.ninja`. Over main's pin 6c7f996a4fe the fork now differs in `src/llvm-project` alone, ceaf0fbb844: `bit.h`'s `` list and `is_local_impl`. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- rust | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust b/rust index 01b8626673f..95960d6c214 160000 --- a/rust +++ b/rust @@ -1 +1 @@ -Subproject commit 01b8626673fcbe92000950d7be27a946e6b9a465 +Subproject commit 95960d6c214338e9375b1c7c6c0d4e5ece4c4ba3 From d6f279456a8592ab1c51eabf09aac6b1e09bf09a Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 15:07:47 +0200 Subject: [PATCH 07/11] issues: what stops LLVM for a ToyOS host, measured against main's libc With #650's libc the signal-set calls are defined, and the build at fork commit 95960d6c214 against sysroot c7ac8a31dd22a958 stops first in `Support`: `Unix/Program.inc` on `wait4`, `wait` and `alarm`, `Unix/Watchdog.inc` on `alarm`. The two objects fail in either order, n2 running both: in one run the log's first error was `Watchdog.inc:23`'s `alarm`, in the next `Program.inc:340`'s `wait4`. The rest of the list is unchanged and measured again: `shm_open`, `shm_unlink`, `scanf`, `ctime`, `std::ifstream`, the fourteen names libc++ with `std::filesystem` asks libc for, `lround` at the link, and the four shared libraries. The shared-object issue no longer names the two files lld happened to list first for `__tls_get_addr`: this run's were libc's own and LLVM's `TimeProfiler.cpp`, of 89 references. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- ...ared-object-does-not-link-against-the-c-sysroot.md | 3 +-- ...annot-build-llvm-clang-and-lld-for-a-toyos-host.md | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md index d89320860f6..1442046d048 100644 --- a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md +++ b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md @@ -17,8 +17,7 @@ for, an executable: - `main`, undefined: `libtoyos_c.a`'s entry point, `start_c`, sits in an object the link takes for other names. - `__tls_get_addr`, undefined: a shared object reaches a thread-local, its own - (LLVM's `PrettyStackTrace.cpp`, clang's `Stack.cpp`) or libc's, through it, - and only std defines it. + or libc's, through it, and only std defines it. - `R_X86_64_TPOFF32` against libc++abi's `eh_globals`, and `R_X86_64_PC32` against libc++'s vtables: the C++ runtime is compiled for an executable (`issues/build/a-rust-std-binary-cannot-link-the-cxx-runtime.md`). diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index a0c18d8e011..c7d2787fbea 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -14,11 +14,12 @@ itself. CMake takes the C sysroot's `toolchain.cmake` from `CMAKE_TOOLCHAIN_FILE_x86_64_unknown_toyos`. What stops the build, in the order it stops it: -- **Compile.** The first error is `sigemptyset`, undeclared in `Support`'s - `CrashRecoveryContext.cpp`: stage 3's signal-set calls, `wait` and `wait4` - (`issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md`) - and `alarm` (`issues/build/libc-has-no-alarm.md`). Then ORC's `shm_open` and - `shm_unlink`, the interpreter's `scanf` and `llvm-objdump`'s `ctime` +- **Compile.** The first errors are `Support`'s: `Unix/Watchdog.inc` and + `Unix/Program.inc` call `alarm` (`issues/build/libc-has-no-alarm.md`), and + `Program.inc` stage 3's `wait` and `wait4` + (`issues/kernel/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md`). + Then ORC's `shm_open` and `shm_unlink`, the interpreter's `scanf` and + `llvm-objdump`'s `ctime` (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), and clang's `std::ifstream`, which libc++ has only with `std::filesystem`. Built with it, libc++ asks libc for `setbuf`, `fseeko`, `ftello`, `utimes`, From f4c11b2d6822444db6c4063af1683388a9e932bd Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 15:53:41 +0200 Subject: [PATCH 08/11] clang: CMake's ToyOS says how a library is named and where a find looks Round 3 of #661, the review's second BLOCKER and first two NOTEs. Platform/ToyOS.cmake sets the soname flag, the exports flag and CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME, as Linux.cmake, Fuchsia.cmake and SerenityOS's modules do. ToyOS's loader finds a library by the name DT_NEEDED holds, beside its executable or in /system/lib (kernel/src/loader/mod.rs, load_needed_libs), and without the flag CMake gives a shared library no soname, so what links it by path records the build's path. LLVM's build for a ToyOS host links four: libLTO, libRemarks, libclang and libclang-cpp. With the flag its build.ninja names each `SONAME_FLAG = -Wl,-soname,`; without it, none. Seven of its executables ask for exports (clang-repl, bugpoint, lli, lli-child-target, llvm-jitlink, llvm-jitlink-executor, opt) and got no flag. No runtime-path flag is set. The loader acts on no DT_RUNPATH (toyos-elf/src/dynamic.rs), and with Linux.cmake's four rpath variables the same configure put `-Wl,-rpath,$ORIGIN/../lib` on 118 links, clang-22's among them: a path in every binary that nothing on ToyOS reads. toolchain.cmake sets CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER and _LIBRARY, _INCLUDE and _PACKAGE ONLY. Without them the ToyOS LLVM configure, with LLVM_ENABLE_ZSTD left on, took /opt/homebrew/lib/libzstd.a and put /opt/homebrew/include on 3681 lines of build.ninja; with them it finds none. issues: the fourteen names libc++ with std::filesystem asks of libc move to the issue whose exit waits on them, and its sentence that libc has no dirent.h goes: userland/libc/include/dirent.h is in the tree. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- ...ild-llvm-clang-and-lld-for-a-toyos-host.md | 5 +--- .../libcxx-is-built-without-std-filesystem.md | 8 +++-- src/clang.rs | 29 +++++++++++++++---- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index c7d2787fbea..06658c824f8 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -21,10 +21,7 @@ order it stops it: Then ORC's `shm_open` and `shm_unlink`, the interpreter's `scanf` and `llvm-objdump`'s `ctime` (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), and - clang's `std::ifstream`, which libc++ has only with `std::filesystem`. Built - with it, libc++ asks libc for `setbuf`, `fseeko`, `ftello`, `utimes`, - `truncate`, `pathconf`, `openat`, `unlinkat`, `fdopendir`, `_PC_PATH_MAX`, - `O_DIRECTORY`, `O_NOFOLLOW`, `AT_FDCWD` and `AT_REMOVEDIR` + clang's `std::ifstream`, which libc++ has only with `std::filesystem` (`issues/build/libcxx-is-built-without-std-filesystem.md`). - **Link.** clang needs `lround`, which libc does not define (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), beside diff --git a/issues/build/libcxx-is-built-without-std-filesystem.md b/issues/build/libcxx-is-built-without-std-filesystem.md index ff743a45db6..7a98601903e 100644 --- a/issues/build/libcxx-is-built-without-std-filesystem.md +++ b/issues/build/libcxx-is-built-without-std-filesystem.md @@ -7,9 +7,11 @@ opened: 2026-09-30 # libc++ for ToyOS is built without `std::filesystem` `src/libcxx.rs` configures the C++ runtime with `LIBCXX_ENABLE_FILESYSTEM=OFF`, -so a ToyOS C++ program that includes `` does not compile. libc++'s -filesystem is written on the POSIX directory, `stat` and path calls, and libc -has no `dirent.h`. +so a ToyOS C++ program that includes `` does not compile, and +`` goes with the option: `std::ifstream` and `std::ofstream` are +undefined templates. Built with it, libc++ asks libc for `setbuf`, `fseeko`, +`ftello`, `utimes`, `truncate`, `pathconf`, `openat`, `unlinkat`, `fdopendir`, +`_PC_PATH_MAX`, `O_DIRECTORY`, `O_NOFOLLOW`, `AT_FDCWD` and `AT_REMOVEDIR`. **Exit**: libc carries what libc++'s `src/filesystem` calls, the option goes, and a guest test lists a directory through `std::filesystem`. diff --git a/src/clang.rs b/src/clang.rs index 3da13297ba6..22b6ecaedd9 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -42,10 +42,12 @@ const TOOLS: [&str; 3] = ["llvm-ar", "clang", "ld.lld"]; /// CMake's description of ToyOS, which CMake does not ship, as every C sysroot /// carries it: a toolchain file that names the system, the target and the -/// sysroot it sits in, and puts beside it on CMake's module path the platform -/// module, laid out as CMake's `Modules/Platform` lays out a Unix-like system. -/// The compilers are the caller's. `@PROCESSOR@` and `@TARGET@` are the -/// sysroot's. +/// sysroot it sits in, has CMake find a library, a header and a package there +/// alone and a program on the host alone, and puts beside it on CMake's module +/// path the platform module, laid out as CMake's `Modules/Platform` lays out a +/// Unix-like system. The compilers are the caller's, and so is the root of any +/// package it built outside the sysroot (`CMAKE_FIND_ROOT_PATH`). `@PROCESSOR@` +/// and `@TARGET@` are the sysroot's. pub(crate) const CMAKE: [(&str, &str); 3] = [ ( "toolchain.cmake", @@ -55,11 +57,26 @@ pub(crate) const CMAKE: [(&str, &str); 3] = [ set(CMAKE_C_COMPILER_TARGET @TARGET@)\n\ set(CMAKE_CXX_COMPILER_TARGET @TARGET@)\n\ set(CMAKE_ASM_COMPILER_TARGET @TARGET@)\n\ + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n\ + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)\n\ + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)\n\ + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)\n\ list(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")\n", ), ("Platform/ToyOS-Initialize.cmake", "set(UNIX 1)\n"), - // `dlopen` and its kin are the C library's own. - ("Platform/ToyOS.cmake", "set(CMAKE_DL_LIBS \"\")\n\ninclude(Platform/UnixPaths)\n"), + // `dlopen` and its kin are the C library's own. The loader finds a library + // by the name `DT_NEEDED` holds, beside its executable or in `/system/lib`, + // so a library carries its soname and one without is linked by name; and it + // reads no runtime path, so no flag asks the linker for one. + ( + "Platform/ToyOS.cmake", + "set(CMAKE_DL_LIBS \"\")\n\ + set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG \"-Wl,-soname,\")\n\ + set(CMAKE_EXE_EXPORTS_C_FLAG \"-Wl,--export-dynamic\")\n\ + set(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)\n\ + \n\ + include(Platform/UnixPaths)\n", + ), ]; /// `lib/rustlib//bin` of `toolchain`, where `rust-lld` is. From 2ad47ab44f378ad997a47c8092be49b5a1afc0e2 Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 16:23:29 +0200 Subject: [PATCH 09/11] issues: the Lld step is handed the ToyOS LLVM's install as a find root Round 3 of #661. Under the sysroot's CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY, bootstrap's Lld step for x86_64-unknown-toyos stops in its configure: lld/CMakeLists.txt:27, find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}"), finds no LLVMConfig.cmake, because CMake re-roots the hint under the sysroot. Handed a toolchain file that includes the sysroot's and appends the ToyOS LLVM's install to CMAKE_FIND_ROOT_PATH, the same step configures, builds and installs ld.lld. The issue that owns the build says which file bootstrap is handed. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- ...p-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index 06658c824f8..09d6065d987 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -10,9 +10,12 @@ M2's clang and lld (`issues/build/toyos-builds-itself.md`) are bootstrap's `Llvm` step, with `clang = true`, and its `Lld` step for `x86_64-unknown-toyos`, in a bootstrap build that names no `llvm-config` for the build triple and so builds that triple's LLVM, and its `clang-tblgen`, -itself. CMake takes the C sysroot's `toolchain.cmake` from -`CMAKE_TOOLCHAIN_FILE_x86_64_unknown_toyos`. What stops the build, in the -order it stops it: +itself. CMake takes its toolchain file from +`CMAKE_TOOLCHAIN_FILE_x86_64_unknown_toyos`: one that includes the C sysroot's +`toolchain.cmake` and adds the ToyOS LLVM's install to `CMAKE_FIND_ROOT_PATH`, +because the `Lld` step names that LLVM to `find_package` by a hint, and the +sysroot's file has CMake find a package under a root alone. What stops the +build, in the order it stops it: - **Compile.** The first errors are `Support`'s: `Unix/Watchdog.inc` and `Unix/Program.inc` call `alarm` (`issues/build/libc-has-no-alarm.md`), and From 3fe7d29ea5c9f0f790fc554e542651cbd5688819 Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 17:47:28 +0200 Subject: [PATCH 10/11] clang: the platform module says which of its neighbours' link flags it leaves out The review of #661 at 2f46d2e3b found the module silent on what CMake 4.4.3's Linux.cmake, Fuchsia.cmake and SerenityOS-GNU.cmake set beside the soname: the six CMAKE_{SHARED_LIBRARY,SHARED_MODULE,EXE}_LINK_{STATIC,DYNAMIC}_C_FLAGS (-Wl,-Bstatic and -Wl,-Bdynamic), and, in Linux.cmake and Haiku.cmake, CMAKE_LINK_GROUP_USING_RESCAN with its _SUPPORTED. They stay out, by the measurement the runtime path was decided by. At 2f46d2e3b, against sysroot c54f9128630496ae, bootstrap's own configure of LLVM for x86_64-unknown-toyos was run with the module as it is, with the six, with the two and with all eight appended: build.ninja and rules.ninja are byte-identical in every arm, and of the 454 files the configure wrote the two that differ, .n2_db and CMakeConfigureLog.yaml, differ between two runs of the module as it is. The same comparison sees a module line: with Linux.cmake's runtime-path flags appended, 118 links gain -Wl,-rpath,. The C++ runtime's configure, the one build in the tree that reads the module, writes the same build.ninja and rules.ninja with all eight, for both architectures. No CMake file of llvm-project at ceaf0fbb844 names LINK_SEARCH_START_STATIC, LINK_SEARCH_END_STATIC or LINK_GROUP. What a project that does ask gets, through the same sysroot copy: a library named `libm.a` is linked as `-lm` where with the six it is `-Wl,-Bstatic -lm -Wl,-Bdynamic`, and `$` is refused by CMake by name, "Feature 'RESCAN' ... is not supported for the 'C' link language", where with the two it links between --start-group and --end-group. The CMAKE text is unchanged, so no key moves. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- ...object-does-not-link-against-the-c-sysroot-with-z-defs.md} | 0 src/clang.rs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) rename issues/build/{a-shared-object-does-not-link-against-the-c-sysroot.md => a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md} (100%) diff --git a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md similarity index 100% rename from issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md rename to issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md diff --git a/src/clang.rs b/src/clang.rs index 1425c2e5653..17bc8e7e548 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -75,7 +75,9 @@ pub(crate) const CMAKE: [(&str, &str); 3] = [ // `dlopen` and its kin are the C library's own. The loader finds a library // by the name `DT_NEEDED` holds, beside its executable or in `/system/lib`, // so a library carries its soname and one without is linked by name; and it - // reads no runtime path, so no flag asks the linker for one. + // reads no runtime path, so no flag asks the linker for one. The flags that + // switch a link between static and shared libraries and the `RESCAN` link + // group are left out too: no build of ToyOS's asks CMake for either. ( "Platform/ToyOS.cmake", "set(CMAKE_DL_LIBS \"\")\n\ From 5d7cf8d86fefb4d76ae071640b6894452e84d80d Mon Sep 17 00:00:00 2001 From: japabu Date: Fri, 2 Oct 2026 17:47:29 +0200 Subject: [PATCH 11/11] issues: a shared object does not link against the C sysroot with -z defs The issue's heading, its slug and its second sentence said no shared object links against the C sysroot. One does: a C library of one function, built by CMake through the sysroot's toolchain file, links with exit 0. What does not link is one with -z defs, the exit's own words: the same library with -Wl,-z,defs stops on `__tls_get_addr` and `main`, as LLVM's four do. And the one that linked is refused by what links it: lld ends the executable's link with "undefined reference: __tls_get_addr ... referenced by libfoo.so (disallowed by --no-allow-shlib-undefined)", and links it under -Wl,--allow-shlib-undefined. Measured at 2f46d2e3b against sysroot c54f9128630496ae. The slug moves with the body, and its one citation, the bootstrap issue's, with it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013UDZQ6fSKw14e4w2TKTRfm --- ...ect-does-not-link-against-the-c-sysroot-with-z-defs.md | 8 +++++--- ...ap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md index 1442046d048..96722376b4b 100644 --- a/issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md +++ b/issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md @@ -4,11 +4,13 @@ kind: defect opened: 2026-10-01 --- -# A shared object does not link against the C sysroot +# A shared object does not link against the C sysroot with `-z defs` ToyOS loads shared objects, a program's `DT_NEEDED` and `dlopen`'s, and its -clang links one with `-shared`. None links against the C sysroot: LLVM built -for `x86_64-unknown-toyos` +clang links one with `-shared`. None links against the C sysroot with +`-z defs`. A C one linked without it leaves `__tls_get_addr` undefined, and +lld refuses the executable that links it for that name. LLVM built for +`x86_64-unknown-toyos` (`issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md`) builds `libLTO`, `libRemarks`, `libclang` and `libclang-cpp`, linked `-shared -z defs`, and each stops on what the sysroot's archives were built diff --git a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md index 09d6065d987..c2cc7c6442e 100644 --- a/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md +++ b/issues/build/bootstrap-cannot-build-llvm-clang-and-lld-for-a-toyos-host.md @@ -30,7 +30,7 @@ build, in the order it stops it: (`issues/build/libc-lacks-names-llvm-for-a-toyos-host-calls.md`), beside those above. LLVM's shared libraries, `libLTO`, `libRemarks`, `libclang` and `libclang-cpp`, do not link against the C sysroot - (`issues/build/a-shared-object-does-not-link-against-the-c-sysroot.md`). + (`issues/build/a-shared-object-does-not-link-against-the-c-sysroot-with-z-defs.md`). clang and lld use none of them, and ToyOS's build turns them off. **Exit**: ToyOS's build, with nothing supplied by hand, has bootstrap install