Repository navigation
n2 is the only Ninja: the LLVM build runs it first on PATH, and Ninja leaves every install step and the tool list - #652
Conversation
The owner ruled to keep n2 over Ninja. The scout built LLVM, clang and LLD with n2 linked as the only `ninja` on PATH, exit 0, with no change to LLVM, Rust or CMake, and the output matched a Ninja-built LLVM of the same key except for paths and dates. n2's install moves out of `src/libcxx.rs` into `src/n2.rs`, unchanged: the pin, the directory its arguments name, and `ninja`, which installs n2 once and returns the `ninja -> n2` link. Its test moves with it, and the stand-in it plants becomes a helper the LLVM test plants too. The C++ runtime still names that link to CMake by path and runs it by path. `llvm::build_in_fork` now takes the root n2 is installed under. It installs n2 there, and runs bootstrap with that `bin` directory first on PATH and the cleared environment's PATH after it. It uses PATH because bootstrap refuses an LLVM build unless PATH has a `ninja` or `ninja-build` (`src/bootstrap/src/lib.rs`, `Build::ninja`). CMake's Ninja generator also takes the first `ninja` on PATH (`CMakeNinjaFindMake.cmake`: `find_program` with `NAMES_PER_DIR`), so n2 runs even on a host that still has Ninja later on PATH. The directory holds nothing but n2 and its link, so nothing else on PATH is shadowed. n2 is installed only when an LLVM is actually built. The LLVM key does not change. The build tool does not decide the bytes, and every stored LLVM stays valid. The release tag now hashes `src/n2.rs`, as it hashed the pin while the pin lived in `src/libcxx.rs`, so moving the pin still rebuilds the published toolchain under the new n2. The tag test now mutates the pin. `the_caller_s_environment_reaches_neither_the_build_nor_the_key` plants the stand-in n2 and now asserts that the build's PATH is exactly the caller's with n2's `bin` first. Before, it only asserted that some PATH existed. Ninja goes from everywhere a developer or a runner was told to install it: the `build` job's apt step (renamed "disk, QEMU and CMake"), both portability jobs, `src/main.rs`'s `ALSO_USED`, which was only Ninja and goes with its note loop, and the README. The host-tools issue loses its Ninja row, and its row for the `build` step follows the rename. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
…s fork Found while running this branch's LLVM gate. A linked worktree's fork checkout leaves src/llvm-project empty. Bootstrap's update_submodule then reads the fork's own HEAD there and runs `git submodule update --init` for it in the linked worktree, which is the command the implementer prompt forbids there. This is read from the code at fork aca5f527; it was not run. The gate avoided it by hand: src/llvm-project became a detached worktree at the gitlink, from a clone that holds the commit. That clone was sparse, so the worktree inherited only clang, libcxx and libcxxabi, and CMake stopped, exit 101, until `git sparse-checkout disable` in the new worktree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
|
Review round 1, head 50dd1b0. CI is ready for review. The
Bootstrap and CMake are untouched:
BLOCKER
NOTE
REMOVE
SEND BACK |
Review round 1 of #652: - Root CLAUDE.md's Dependencies sentence no longer lists Ninja among the declared C and C++ tools. n2 is the only Ninja, so the sentence's own condition, "where no Rust tool does the job", rules Ninja out. - `n2::bin(root)` installs n2 and returns its `bin` directory, and `n2::ninja` is the link in it. `llvm::build_in_fork` puts that directory first on PATH. The unreachable panic on `ninja.parent()` is gone. An unset PATH is now refused by name instead of read as empty. - The issue about bootstrap running `git submodule` for `src/llvm-project` is folded into issues/build/the-fork-checkout-runs-git-submodule-in-a-linked-worktree.md as a third arm, because that issue's exit already covers it. The arm keeps the way around it and the sparse-clone constraint, and drops the gates and worktrees of the investigation. The folded file is deleted. Nothing in the tree cited it: `git grep` for its slug and for its distinctive suffix found nothing. - Removed the rewritten Ninja comments in nightly.yml, the README clause about n2, and the list of callers in src/n2.rs's module doc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
|
Review round 2, head ad827a6. Scope: CI at ad827a6: run 36811457420, job
The merge 048a752 carries the branch's diff unchanged. Its diff against 9efafcc equals the diff from 49f4938 to 50dd1b0, apart from index lines and hunk offsets. Round 1
The body says BLOCKER NOTE REMOVE LAND |
src/llvm.rs conflicted in `keyed_and_built` only: #652 gave `build_in_fork` the root whose n2 leads the build's PATH, and this branch writes the LLVM key, now a `Key`, through `as_str()`. The resolution keeps both: `build_in_fork(&root, &fork)` and `key.as_str()`. Every other hunk of either side merged clean; n2's install directory is not a keyed store, so `n2::installed` keeps `sysroot::short`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
…toyos-noredlist #588 landed first, and its `usb_stick_left` arms `usb-transport-break`, `usb-reset-moves`, `usb-reset-moves-after` and `usb-reset-moves-configured` again, its T14 row (`usbbreak`) arms `usb-transport-break`, and its metal record carries the `usbbreak` rows. Those stay, with `msc::transport_break`, `msc::reset_moves`, `RECOVERING` and `Quiet::Staged`. Everything else this branch deleted with `usb_transport_break` (90ecefe, b5c59cb, 402107b, 9ebf080) stays deleted: no test on either side arms it. Conflicts, every hunk: - `kernel/src/actuator.rs`, two hunks. First: main's eight USB rows. Kept `usb_transport_break`, `usb_reset_moves`, `usb_reset_moves_after` and `usb_reset_moves_configured`, with `usb_reset_moves`' doc losing its citation of the deleted `usb_transport_break`; dropped `usb_transport_offline`, `usb_reset_break`, `usb_transport_break_owed` and `usb_transport_break_flushed`, armed only by the deleted `usb_transport_break`, `log_flush_retry` and `partition_claim_departure`. Second: dropped `watch_window` (`blocking_read_window`, deleted in dc62efc), kept #634's `handler_post`. - `kernel/src/drivers/xhci/wait/msc.rs`, fourteen hunks, misaligned by #588's rewrite of the file. Resolved as main's file with this branch's deletions applied to it: `Asks` and `bot`'s `asks` argument at its five call sites; `transport_break`'s owed and flushed half (`WROTE`, `FLUSHED`, `AFTER_A_FLUSH`, `wrote`, `flushed`, their calls in `MscDevice::wrote` and the flush, and `arm`'s argument), so `arm` reads `usb-transport-break` alone; `return_silent` and its hook in `served`; `reset_break` and the wrapper around `climb`, whose body `climb_until_in_step` carries again; `short_read` and its hold and release around the data phase; `staged` and its checks in `bot`, the bad signature, the withheld CBW, the gone port and the unanswered wait; the bind's `slow_return` stall and INQUIRY staging, and `slow_return` itself; `read_serial`'s short ask. `reset_moves`, its three holds and `RECOVERING` are main's as they stand. - `kernel/src/watch.rs`, one hunk: dropped the `window` module (`watch-window`), kept #634's `handler_post` module. - `toyos-sched/src/watch.rs`, one hunk: the same, `window` dropped and `handler_post` kept. - `src/lib.rs`, one hunk: kept #652's `pub mod n2`, dropped `pub mod redlist`. - `tests/common/power.rs`, one hunk: main's only change there renamed `transport_break_chain`'s doc to `usb_stick_left`; its one caller is the deleted `usb_transport_break`, so it stays deleted. - `tests/common/usb.rs`, one hunk holding main's whole `usb_transport_break` region. Kept #588's `Held`, `usb_stick_left`, `a_stick_that_left_under_its_rung`, `transport_break_on_metal`, `transport_break_recovered` (which `tests/checks/usb.rs` judges) and `broke_on`; the rest is `usb_transport_break`'s and stays deleted: `a_read_whose_first_wait_spent_its_budget_goes_out_again`, `serial_short_is_not_read`, `cpu_of`, `line_with`, `Moved`, `a_stick_its_reset_moved_carries_on`, `abandoned_write_is_taken_offline`, `no_command_was_refused`, `port_gone_is_left_to_the_teardown`, `control_requests`, `command_blocks`, `every_reset_is_followed_by_a_test_unit_ready`, `is_a_rungs_configuration`, `every_port_reset_is_followed_by_a_test_unit_ready`, `every_reset_is_followed_by_both_clears` and `transport_gives_up`. - `tests/toyos.rs`, five hunks. `MACHINE_TESTS`: kept `usb_stick_left` and #634's `handler_post_without_a_pass`; dropped `usb_transport_break`, `xhci_full_speed_device` (5e42235), `blocking_read_window` and `user_copy_races_munmap` (7ea6be1). `METAL`: kept #588's `usb_stick_left` row. Dispatch: kept `usb_stick_left` and `handler_post_without_a_pass`; dropped `usb_transport_break`, `xhci_full_speed_device` and `smp_failed_ap_leaves_no_hole` (aedcf17). Outside the conflicts: - `kernel/src/drivers/xhci/wait/mod.rs`: `Quiet::Staged` and its line come back, which `transport_break::take` answers with; the auto-merge had taken 9ebf080's deletion. The `reset_break` and `return_silent` hooks stay deleted. - `src/metal.rs`: `FLASHABLE`'s `usb-transport-break` row comes back (b5c59cb took it), since `usb_stick_left`'s T14 arm flashes it. - `issues/kernel/a-held-disk-waits-for-a-pass-no-cpu-takes-when-every-cpu-is-in-a-call-on-it.md`: records `4f2bea143`, this merge's second parent, as the tree holding #588's version of `usb_transport_break`, in place of the instruction to record it. - `issues/boot-media/logd-ends-the-boots-log-on-one-refused-create-and-nothing-durable-says-so.md`: drops its citation of `power::transport_break_chain`, deleted in 90ecefe. The `rust` gitlink is main's. On this tree: `cargo run -- --build-only` exit 0; the kernel's `cargo check` for x86-64 and AArch64, bare, with `boot-actuators` and with `boot-actuators,test-actuators`, exit 0 each; `cargo test --test toyos-build --no-run` exit 0, no warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
#639 deletes the redlist and every test it disabled, and every flaky or red test filed against it, each with its issue recording the commit that restores it. Where #639 and this branch delete the same test, issue, actuator or helper, the deletion stands; where #639 deleted what this branch kept or edited, it is kept only where a test this branch keeps needs it. The redlist: `src/redlist.rs` goes with every touch of it here (the `kept` filter, `check_redlist`, the disabled banner, the selection check's enabled filter). The fourteen issues this branch moved from `expected-red` to `open` take #639's texts; `process-stats-exits-101` keeps this branch's two sightings and exit beside #639's deletion paragraph. The guest keeps: #639 deleted `screen_diag_boot`, `screen_console_shell` and `usb_boot_stick_pulled`, three of this branch's 22, as red tests, and those deletions stand. `iommu_virtio_platform` stays as #639 restores it, and `nested_nmi_is_loud`, #639's own new test, stays: the nested-NMI report is a raw write to the 16550, which the T14 does not have. The guest suite is 21 tests. What `iommu_virtio_platform` needs comes back from main, and only that: `tests/common/iommu.rs` holds the test, its `declining_is_not_free` control and the claim judge it reads (`refused_claim` and its helpers, which only it uses now); `Profile::HeadlessNoIommu` and `Profile::iommu`; `Serial::boot`; the `virtio-no-access-platform` actuator and `virtio::platform_addressing`; and `tests/netcase` with the rows its boot reads (logd, blockd, fsd, netd, test-runner). The rows only cut tests read go: test-runner's second claim on netd's function, which `src/build.rs`'s collision exception named for `pci_function_is_exclusive`, and toybox, shell and host. The test boots with no test binaries: none of its arms runs one. `nested_nmi_is_loud` brings back `nmi-nested`, its idle send in `sched::driver` and `stage_nested_if_armed`. The phases go: with `usb_boot_stick_pulled` gone every row is parallel, so `Sched`, the serial tail and its phase run go, and the suite is one run at the width. The kernel: `idt/nmi.rs` is main's, the NMI entry no longer loading the frame's `cs`, so `note`'s unread `_cs` goes. `msc.rs` is main's file with this branch's deletions applied to it (`MscDevice::online`, `mid_write`, `bind_spends_the_scan`, `reset_moves` and their hooks, `flush_sense`); main's own deletion of the staged-fault machinery and `Asks` stands. The watch-window and handler-post instruments both go, in the kernel and in `toyos-sched`. `close_ends_polls` answers `SysCap` on its own arm, which `sourcegate`'s gate requires. What the union of deletions leaves with no user goes: test-runner's builtins (`log-close` here, `log-storm` and `kbd-close` on main) and the builtin path itself; `tests/logrotatecase` and logd's `--rotate-fast`; `tests/common/swap.rs`; `metaldevices::exit_of`; the console font decoder, the console stream, the PS/2 typing helpers, `QmpDevices` and the render-aware screendump wait; `devices::on_metal`; `C_METAL_SKIP`, empty once `90_stdio_buffering` went. The metal rows #639 deleted go with their judges: `metal_device_probe`, `lan_swap`, `blocking_read_window`, `log_poll_outlives_a_close`, `short_sleep_livelock`. The nightly keeps this branch's layout: `cargo run -- --ci guest` on both lanes, no shards; main's change there is #652's Ninja. The track drops the names #639 deleted, each now held by its own issue, and `sys-debug-actions…` drops `SCREEN_GRAFFITI`, which #639 retired. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L
n2 becomes the only Ninja the project runs, and nothing tells a developer or a runner to install Ninja any more. The owner ruled to keep n2. Before this branch, a scout built LLVM, clang and LLD with n2 linked as the only
ninjaon PATH: exit 0, with no change to LLVM, Rust or CMake.What changed, per decision
src/n2.rsholds A C++ runtime for ToyOS: libc++, libc++abi and libunwind in every C sysroot #637's pin and install directory, unchanged, and its test.n2::bin(root)installs n2 unless it is there, and returns itsbindirectory. That directory holdsn2and aninjalink to it, and nothing else.n2::ninja(root)is the link in that directory.src/libcxx.rskeeps only the runtime. The sysroot build callsn2::ninja.CMAKE_MAKE_PROGRAMand runs it by path, so it never looks upninjaon PATH. That is why it needed no PATH change.llvm::build_in_fork(root, fork)runs bootstrap with PATH set ton2::bin(root)followed by the caller's PATH. If PATH is unset, it panics and says so rather than treating it as empty.resolveandheldpassrootin.ninjaorninja-build(src/bootstrap/src/lib.rs,Build::ninja).Help/release/3.17.rst:307-310, read in Homebrew's CMake 4.4.3), andCMakeNinjaFindMake.cmakethere does it withfind_program(… NAMES ninja-build ninja samu NAMES_PER_DIR). LLVM849da7d62requires CMake 3.20.0 (llvm/CMakeLists.txt:2). The nightly pins Ubuntu's 3.28.3.src/n2.rs. It already hashed the pin while the pin lived insrc/libcxx.rs. Moving the pin therefore still rebuilds the published toolchain under the new n2. The tag test mutates the pin.buildapt step, renamed "disk, QEMU and CMake";portability-linuxandportability-macos;src/main.rs'sALSO_USED, whose only entry was Ninja, and the loop that printed its note;CLAUDE.md's list of admissible C and C++ tools in Dependencies. That list's own condition, "where no Rust tool does the job", now rules Ninja out.buildstep follows the rename.issues/build/the-fork-checkout-runs-git-submodule-in-a-linked-worktree.mdnow has a third arm. In a linked worktree whose LLVM key is in no store, bootstrap'supdate_submodule(config.rs:2585at forkaca5f527) runsgit submodule update --initforsrc/llvm-projectin that worktree's fork checkout. That finding was read from the code and not run. The issue's existing exit covers it.Gates
cargo run -- --build-only: exit 0, on the tree committed asad827a640. It wrotetarget/bootable.img. The compiler, LLVM and sysroot for this tree were already in the stores, so this run built none of them.cargo run -- --ci host: exit 0, "Host: 56 step(s), all green", atad827a640. These three tests ran ok in it:llvm::tests::the_caller_s_environment_reaches_neither_the_build_nor_the_key,n2::tests::an_installed_n2_is_not_installed_againandrelease::tests::the_tag_moves_with_the_c_toolchain.ad827a640. Each was applied as a checked patch and built withcargo test --lib --no-run(exit 0). Each turned its test red, and the tree was restored withgit status --porcelainempty.command.env("PATH", path)frombuild_in_forkmakesthe_caller_s_environment_reaches_neither_the_build_nor_the_keyfail with exit 101: "the build's PATH is not PATH=/target/n2/172fb458445ac68d/bin:…".n2::binreturn the install directory instead of itsbinmakesan_installed_n2_is_not_installed_againfail with exit 101 atassert_eq!(bin(&root), stand_in).b2b171363, before this round. Since then,build_in_forkhas changed only in how it gets n2's directory and the caller's PATH. The first mutation above shows that a test pins the exact PATH that results./opt/homebrew/binreplaced by a directory of links to everything in it exceptninja.which -a ninja ninja-build samufinds nothing on it.llvm::tests::keyed_and_built, run with the fork at main's pinaca5f527and LLVM849da7d62. Bootstrap reported "Build completed successfully in 0:30:50". The proof that n2 ran it:Ninja version: 1.10.2, which is n2's answer.CMakeCache.txt,CMAKE_MAKE_PROGRAMis n2'sninjalink..n2_db, and neither holds a.ninja_log.n2: ran 4331 tasksandn2: ran 133 tasks.git diff origin/main HEAD -- src/was applied as a checked patch and built (exit 0), then run with the same command and PATH. Bootstrap refused with "Couldn't find required command: ninja (or ninja-build)". The tree was restored.crate::n2::SOURCEfrom the releasetrees()turnsthe_tag_moves_with_the_c_toolchainred, exit 101.ninjalater on PATH givesCMAKE_MAKE_PROGRAM= the n2 link;/opt/homebrew/bin/ninja.CMakeCache.txt, n2's own database and task counts, and CMake's release notes and Ninja lookup module.buildandportability-linuxjobs. The same nightly'sportability-macosis the first run on a macOS runner with no Ninja installed.Unsure
ninja-runs-every-command-through-a-bin-sh-toyos-does-not-have,there-is-no-dev-null, and the child-process track. n2 atb1fead5does the same two things (src/process_posix.rs:178spawns/bin/sh, and:169opens/dev/null), so what those issues claim still holds.ninja -k 0records a past command.🤖 Generated with Claude Code
https://claude.ai/code/session_016t9wjdQkB8SH7bmfUoiy6L