--- name: schunix-layout-migration description: "The bt/ -> ports/ + lib/ + cmd/ restructure done 2026-08-01, and the two build traps it exposed" metadata: node_type: memory type: project originSessionId: d1a1ea76-f919-411c-b0ef-0e1bc5064563 modified: 2026-08-01T17:17:12.984Z --- Restructured Schunix's tree on 2026-08-01. `bt/` became `ports/` (third-party only, Makefile + patches, nothing else), first-party userland split into `lib/` (runtime glue) and `cmd//main.c` (programs), tarballs to `dist/`, and all generated output to `build/`. Documented in `docs/layout.md`. Verified: full build passes and the image boots to `init: ready (pid 1)`. **Two traps that bit during this and will bite again:** 1. `ld -r -b binary` derives symbol names from the input file's **path**. The kernel embeds `initcode` and `entryother` this way, and the root Makefile has `--redefine-sym _binary_build_lib_initcode_start=...` lines. Move either blob's build location and the link breaks. 2. **A stamp file inside the directory it guards is always out of date.** `ports/musl`'s `$(SRCDIR)/.patched` rule depended on `$(SRCDIR)`, but creating the stamp bumps that directory's mtime, so the rule re-ran on every build and failed (a patch does not apply twice). Same class of bug in toybox and mksh. Fixed by making `$(SRCDIR)` an order-only prerequisite (`| $(SRCDIR)`) in all three ports. **A real thing that was silently lost-in-waiting:** musl's patch file claimed two modified files; the build tree actually had five. The three undocumented ones were in mallocng — two are inert debug tracing under `#ifdef SCHUNIX_MALLOC_DEBUG`, but `glue.h` had a **required** build fix (forward declarations for `__mmap`/`__madvise`/`__mremap`) that existed only as a hand-edit in the build tree. Any `make distclean` would have silently lost it. The patch was regenerated from a real diff against pristine musl 1.2.5 and dry-run verified. Backups from that session (delete when confident): the pre-migration tarball `~/schunix-backup-20260801-1856.tar.gz` and `~/toybox-known-good`, both inside WSL. See [[schunix-build-environment]], [[schunix-rewrite-priorities]].