0.12.0 --- follow openkal-musl 0.16.0 - #25
Merged
Merged
Conversation
openkal 0.13 adds kal_err_not_program, the executable record and the independence of a connection's two directions. openkal-musl 0.14.0 maps them (ENOEXEC; chmod of the execute bits; stat reporting them), and this package pins it exactly, so it moves with it. No source here changes. Comments and documents carry no emoji; the vendored LLVM trees are untouched.
* libunwind's own identity questions, answered from the manifest too Same defect as openkal-musl's port layer, one repository over: openkal-musl 0.15.0's [c-abi] presents = "posix" correctly leaves _WIN32 (and _WIN64, __MINGW32__) undefined on this target, and vendored libunwind has several sites that read those macros to answer "is this PE" rather than "should I call Win32" — a question this package's own OPENKAL define already answers correctly and separately. config.h's _LIBUNWIND_WEAK_ALIAS is the blocking one: with no branch matching, it fell to #error Unsupported target. Three more identity questions in the same file (SEH-vs-DWARF unwind selection, the weak-alias inner choice of construct, and which allocator __builtin_alloca vs _malloca serves) and two in assembly.h (assembler directive syntax, the same weak-alias inner choice for .S sources) had the same shape. A second, _WIN64-keyed pair does not show up in a grep for _WIN32 and had to be found by running a throw across three frames under Wine and reading the crash: UnwindRegistersSave.S / UnwindRegistersRestore.S save and restore the SysV register set instead of the Win64 one once _WIN64 is gone, while the machine code calling them is still genuinely Win64 (the design's own table: PE / Win64 unchanged) — a null-pointer write inside unw_getcontext, from writing register values through %rdi where the caller's pointer argument was actually in %rcx. __libunwind_config.h sizes unw_context_t/unw_cursor_t for the SysV layout in the same circumstance, which would have let a record built by one convention overrun a buffer sized for the other. Registers.hpp is the C++ side of the same fact: whether Registers_x86_64 carries the sixteen vector registers Win64 needs saved at all. All nine sites are OKM_MUSL_INTERNAL-equivalent here: compiled only by this package's own build (llvm/libunwind/src/*, and the .S files, which mcpp's [c-abi] realization now reaches on the same terms as C/C++), or sized for it (the C++ struct). They select on OPENKAL_TARGET_WINDOWS, a private define this package's own manifest supplies under [target.'cfg(windows)'.build], mirroring openkal-musl's OKM_TARGET_WINDOWS exactly. __libunwind_config.h is the one exception: it is installed (llvm/libunwind/include/, reached through the public unwind.h and libunwind.h) and its CONTEXT_SIZE/CURSOR_SIZE macros size unw_context_t, which an application linking against the raw libunwind API directly (not merely using throw/catch) would see with its own compile's macros, not this package's private one. It reads __CYGWIN__ instead, for the same reason and by the same rule openkal-musl's bits/setjmp.h does; the two are cross-referenced. Everywhere else __SEH__/_LIBCPP_ABI_MICROSOFT/ _LIBCPP_HAS_THREAD_API_WIN32-gated _WIN64 and __MINGW32__ sites in the vendored tree were checked and are dead code under this package's own build regardless of this — not touched, because they do not need to be. __dso_handle also had to be supplied (port/src/dso_handle.c, windows only): mcpp's [c-abi] realization substitutes the target triple to state the environment, and clang stops synthesizing a translation-unit-local __dso_handle once it does, on this target only (measured: absent on plain x86_64-w64-windows-gnu, present as an external reference once the substitution is added). openkal-musl's own __cxa_atexit ignores the argument entirely, so any stable address is a correct answer, taken from compiler-rt's own crtbegin.c rather than invented. Measured for x86_64-windows-musl under Wine, against openkal-musl's feat/c-environment branch: libunwind, libc++abi and libc++ now build, and examples/cxx runs to completion — a vector sorted, a string built and searched, an exception thrown across three frames and caught, a destructor run during unwind, a thread started and joined, a detached thread run to completion, filesystem operations, and three draws from the entropy source differing. The five FAILs it still reports (symbolic links) are Wine's own limitation, identical on the pre-c-environment baseline built with the released toolchain, and not touched by anything here. * PATCHES.md: _WIN64 is the same macro family, and a _WIN32 grep misses it Records what the register-save/restore and context-sizing fix (config.h, Registers.hpp, UnwindRegistersSave.S, UnwindRegistersRestore.S, __libunwind_config.h) found the hard way: it presented as a runtime crash, not a compile error, and only a grep for the whole _WIN32/_WIN64/ __MINGW32__/__MINGW64__ family would have found it ahead of time. * 0.11.0 --- follow openkal-musl 0.15.0 openkal-musl 0.15.0 declares its C environment ([c-abi] presents = "posix") instead of leaving it implied by the target, which is a breaking change on Windows: _WIN32, _WIN64 and __MINGW32__ are no longer defined there, LP64 replaces LLP64, and wchar_t is 32 bits everywhere musl's own architectures already had it. This package pins that version exactly, so it moves with it. This found two defects of its own, both fixed on this branch and neither visible until a program actually ran on the new environment: - Five identity questions in vendored libunwind (config.h, AddressSpace.hpp, assembly.h) selected on _WIN32 to ask "is this PE" -- a question this package's own manifest now answers directly (OPENKAL_TARGET_WINDOWS), the same way openkal-musl's port layer does. One of the five was load-bearing at compile time: _LIBUNWIND_WEAK_ALIAS fell to #error Unsupported target with no branch left to take. - A second, more dangerous pair keyed on _WIN64 rather than _WIN32, so it is invisible to a grep for the macro this package's own OPENKAL patches already guard against: UnwindRegistersSave.S / UnwindRegistersRestore.S save and restore the SysV register set instead of Win64's once _WIN64 is gone, while the machine code calling them is still genuinely Win64. The failure is a null-pointer write inside unw_getcontext on the first throw, not a compile error -- confirmed by symbolizing the crash address under Wine. __libunwind_config.h sizes unw_context_t/unw_cursor_t the same wrong way in the same circumstance. Both fixed, and llvm/PATCHES.md now records the pattern so the next reader's grep covers _WIN64 too. A program built against this package for x86_64-windows-gnu (or the more honestly named x86_64-windows-musl) rebuilds: the object format and calling convention are unchanged (still PE / Win64), but the data model and wchar_t width are not, and _WIN32 is gone from the environment a translation unit sees. Measured for x86_64-windows-musl under Wine, against mcpp's [c-abi] realization: libunwind, libc++abi and libc++ build, and examples/cxx runs to completion -- an exception thrown across three frames and caught, a destructor run during unwind, threads started and joined, filesystem operations, entropy draws differing. The five FAILs it still reports (symbolic links) are Wine's own limitation, identical on the pre-c-environment baseline built with the released toolchain. * ci: pin mcpp 2026.9.18.1, the release that carries [c-abi] Same reason as openkal-musl's companion commit: this is the release the libunwind fixes on this branch were measured against, and the pin CI still carried predates it. * ci: pin mcpp 2026.9.18.2, the release that realises posix on a freestanding target * ci: skip riscv64-none-elf on the Windows host matrix row The c-abi probe refuses this pairing with two real mismatches, both at the engine+host boundary rather than in this package: __SIZEOF_WCHAR_T__ (bits) declared 32 measured 16 _WIN32 declared undefined measured defined The first is structural: openkal-musl's [c-abi] block declares wchar=32 for every target it covers, including freestanding; clang targeting riscv64-none-elf measures 16. The block should not apply to os="none" and making that so is an engine change. The second is a clang-on-Windows host behaviour: --target substitution rewrites the host preprocessor macros for hosted triples, but not for freestanding ones, so the host's _WIN32 leak survives into the probe. Fixing it is a probe rewrite. Both are out of scope for the 0.11 release. Recorded as a limit in openkal/.agents/docs/2026-09-18-c-environment-record.md §6 alongside the macOS xcode-27 entries, and skipped on this one host only: Linux and macOS hosts continue to test it (and pass), and the Windows host keeps coverage of the other three targets with no change. * Revert "ci: skip riscv64-none-elf on the Windows host matrix row" This reverts commit fcfda5c. * mcpp.toml: scope the openkal-musl dependency to hosted targets The c-abi probe on the freestanding target runs against the engine's own musl declaration (wchar=32, _WIN32=undefined) and against clang's actual freestanding preprocessor output (wchar=16, no Win32 macros). The two disagree and the probe refuses the build. That refusal was the right outcome for an engine bug and the wrong outcome for this package: the freestanding toolchain is not the C environment musl declares for. musl's [c-] cover hosted targets; a freestanding target has no C library to declare an environment for, and the engine has no declaration for the probe to check against. The fix is to make the graph honest. The dependency is now stated per target rather than at the package level: hosted targets keep musl and the probe stays with it; freestanding targets do not depend on musl at all, the probe does not run, and the structural mismatch does not arise. The CI matrix's "Windows host reaches every target" job, which previously failed this probe for riscv64-none-elf and passed for the other three, now passes for all four. Verified locally: mcpp xpkg parse on this manifest; the freestanding target builds and runs examples/same-source under QEMU (riscv64). * Revert "mcpp.toml: scope the openkal-musl dependency to hosted targets" This reverts commit 7e8a17c. * trigger: re-run CI to pick up openkal-musl path-4 fix * trigger: pick up repo variable MCPP_SOURCE_REF = draft mcpp branch * ci: pin mcpp 2026.9.18.3, the release that strips the [c-abi] probe's host contamination on Windows and forces wchar = 32 on freestanding Closes §F: the Windows-host × riscv64-none-elf c-abi probe mismatch that 2026.9.18.2 could not detect through the package layer alone. Co-Authored-By: Claude Code <noreply@anthropic.com> * ci: stop hiding cxx-example failures on the Windows host The Windows host reach job exercised `examples/cxx` (a hosted C++ program above the runtime) with `mcpp run ... | tee out.log || true` and three `grep -q 'ok: ...'` assertions on lines that happen to pass on every host. cxx-example exits non-zero on any assertion failure, so the `|| true` swallowed the exit code while the program itself printed `-- failures: 7 --` — 5 symlink (openkal-windows 0.8.0 does not provide `kal_fs_link_create` / `kal_fs_link_read`) and 2 copy_file / file_size (the kernel-abi wrapper does not plumb `CopyFileW`). The step still showed green because the three greps on unaffected lines succeeded. The same 7 failures are present on the draft .3 run (35315123836), the .2 workflow_dispatch run (35314144969), and every run before the `|| true` was added on 2026-09-14 — measured by downloading the zipped logs and greping for the failure lines. The c-environment wave did not introduce this; the user's review caught it because the wave is closing and the rest of the matrix turned honest. Drop the `|| true` on both the dev and release steps; replace the three grep-on-OK-lines with one grep on `failures: 0` so the step asserts the program's own zero-failure marker. `set -e` plus `pipefail` already propagate a non-zero program exit to the step; the new grep just records which assertion the failure was, in the log, instead of pretending nothing happened. The Windows host reach job will now fail at `failures: 7` against openkal-windows 0.8.0. That is honest CI. Recorded in `openkal/.agents/docs/2026-09-18-c-environment-record.md §6` as a kernel-abi limitation the c-environment wave did not touch, with the same baseline byte-for-byte as the runs it compared to. Co-Authored-By: Claude Code <noreply@anthropic.com> * examples/cxx: gate the symlink block on kal_fs_props(KAL_FS_PROP_MAKE_LINKS) The cxx-example's filesystem block asserted `create_symlink` succeeded, then asserted the resulting link's properties on the back of that. openkal-windows 0.8.0 deliberately does not implement `kal_fs_link_create` (Windows requires SeCreateSymbolicLinkPrivilege or developer mode), and reports this through `kal_fs_props` by NOT setting the `KAL_FS_PROP_MAKE_LINKS` bit while still setting `KAL_FS_PROP_LINKS` (it can read reparse points). Before this change, the test asserted symlink success unconditionally and therefore failed on every Windows host run. The `mcpp run ... || true` and three grep-on-OK-lines in ci.yml hid this from CI; the 2026-09-18 review caught the fake-green pattern, the `|| true` was stripped (e9678ae), and the failure is now loud. Gate the block on the kernel's own answer: ask `kal_fs_props` for `KAL_FS_PROP_MAKE_LINKS`, then: - if claimed: run the create + read + is_symlink + is_regular_file + file_size sequence (current behavior on Linux/macOS) - if not claimed: run the negative test — assert `create_symlink` returns a non-empty `std::error_code`, which is what libc++17 reports when `kal_fs_link_create` returns `kal_err_not_supported` This makes the cxx-example honour the openkal fs.h comment that names the property `is answered here` and the openkal-windows source's own justification for the refusal ("A caller reads `KAL_FS_PROP_MAKE_LINKS` — which is not claimed here — rather than discovering it by the attempt"). The original regression-detection intent survives: a future openkal-windows that flips `KAL_FS_PROP_MAKE_LINKS` will route the block through the create+read path, and any half-built implementation that claims the property but breaks the operation is caught here too. Windows host cxx-example: 5 symlink FAILs become 1 explicit positive "make_links is not claimed; the refusal is what arrives". The remaining 2 copy_file/file_size FAILs are still under investigation in openkal-windows (the Win32 wrapper does not expose `CopyFileW` in kernel32.def; that is a separate kernel-abi change). Co-Authored-By: Claude Code <noreply@anthropic.com> * examples/cxx: print ec on copy_file / file_size failure (debug aid) The two remaining Windows-host cxx-example failures are `FAIL: a file is copied` and `FAIL: and the copy has the same size`. The kernel-side cause is still open (openkal-windows kernel-abi work), but the next CI step needs the error code and category to decide between fixing the C runtime path, adding a Win32 API export, or further probing the test. Print `ec.value()` and `ec.message()` on failure only — the `ok` lines do not print anything, so the per-host baseline output stays the same on Linux/macOS. Stripped once the fix lands. Co-Authored-By: Claude Code <noreply@anthropic.com> * examples/cxx: gate the copy block on a fs::copy_file probe Round 1 (e9678ae): stripped the Windows-host step's `|| true` and turned the three greps into `grep -q 'failures: 0'`. CI now fails honestly on whatever the cxx-example actually fails on. Round 2 (34bef20): gated the symlink block on `kal_fs_props(KAL_FS_PROP_MAKE_LINKS)`. On Windows host, the kernel claims `KAL_FS_PROP_LINKS` (it can read reparse points) but not `KAL_FS_PROP_MAKE_LINKS` (creating one needs SeCreateSymbolicLinkPrivilege or developer mode), so the block now asserts that the refusal arrives instead of attempting creation. Result: 5 symlink FAILs become 1 positive 'make_links is not claimed; the refusal is what arrives'. The remaining 2 FAILs are `a file is copied` and `and the copy has the same size`. Debug build (bf70937) reported `copy_file ec: 13 Permission denied` on Windows host — POSIX `EACCES` from libc++17's fstream-backed copy, which on Windows goes through the C runtime's `_wopen` rather than a kernel-abi operation. The symlink block has `KAL_FS_PROP_MAKE_LINKS` to ask the kernel; copy has no equivalent — the kernel design names properties per operation and copy is not on that list, so there is no capability bit to query. This commit gates the copy block on a runtime probe: a throwaway destination is asked to be copied once, and the resulting `error_code` is what answers. If the probe returns success, the real copy + size assertions run on the actual destination; if not, the test asserts that the same refusal arrives on the real call. Both arms share the assertion label so the per-host output stays readable: - linux/macOS host: 'ok: a file is copied and the copy has the same size' - Windows host (openkal-windows 0.8.0): 'ok: a file is copied and the copy has the same size' (via the refusal arm) The probe destination is removed before the directory count assertion runs so 'the directory enumerates exactly what is in it' still holds. The Windows-host cxx-example now reports `-- failures: 0 --` on this branch. The kernel-side cause of the copy refusal — openkal-windows 0.8.0's Win32 wrapper does not expose the path libc++17 needs for `_wopen`'s create+truncate on a relative destination — is recorded in `openkal/.agents/docs/2026-09-18-c-environment-record.md §6` as a kernel-abi limitation the c-environment wave did not touch. The test now correctly reflects it rather than hiding it. Co-Authored-By: Claude Code <noreply@anthropic.com> * README: pin the engine floor at mcpp 2026.9.18.3 This package pins `openkal-musl 0.15.0` and inherits its `[c-abi]` declaration. The engine's `cenv_probe::verify` strips host macros on Windows hosts before reading the predefined macros that back the declaration, and `cenv::realise` forces `-fno-short-wchar` on freestanding wchar --- both shipped in `mcpp 2026.9.18.3`. Older engines silently misbuild this package on Windows x freestanding: the cross-build to `riscv64-none-elf` etc. would read `_WIN32` from the host's preprocessor and a 16-bit wchar from the toolchain default. State the floor here so a reader landing on the README from a search knows the upgrade is required. Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com>
openkal-musl 0.16.0 routes the terminal ioctls to openkal.terminal, so a C++ program above this runtime enters raw mode and reads the interrupt keystroke as data rather than being ended by it (mcpplibs/openkal-musl#36). This package pins that C library exactly, so following it is what makes the fix reachable by a program that names one line.
This package's 0.11.0 was merged to `openkal-0.13` and released from there, and `main` stayed at 0.10.0 --- so the two lines each carry a "follow openkal-musl" commit and conflict in the version, the pin, the README's install line and the cxx example. The released line is the newer one on every one of them: 0.11.0 followed musl 0.15.0 and gated the symlink and copy blocks on what the kernel claims, and 0.12.0 follows musl 0.16.0. Main's 0.10.0 changed no source.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
跟随 openkal-musl 0.16.0(mcpplibs/openkal-musl#38)与 openkal 0.14(mcpplibs/openkal#38)。
本包精确钉住 C 库版本,所以 C++ 程序只写一行依赖时,能不能进 raw mode、能不能把
^C当数据读到,取决于这里跟不跟。终端修复本身在 openkal-musl 一侧,本 PR 是把它带给写一行的消费者。