From 2720aade0d97ba4dc39e5b2467e7038aaa8800fe Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 02:51:25 +0800 Subject: [PATCH 1/3] the target is named by mcpp, and a sixth patch site was found by enumerating `__libunwind_config.h` sizes `unw_context_t` by whether the target is Windows. It read `__CYGWIN__`, deliberately, because it is INSTALLED --- an application's own compile reads it, and this package's private define never reaches that compile. mcpp 2026.9.21.1 states the fact under its own name, so the header reads `__mcpp_target_windows__` first and still accepts the old one: correct on an engine from either side of that release, no flag day. THE SIXTH SITE WAS NOT ON ANY LIST. `compiler-rt/lib/builtins/int_lib.h` selects how `COMPILER_RT_ALIAS` is spelt: #if defined(__ELF__) || defined(__MINGW32__) || ... || defined(__CYGWIN__) #elif defined(__APPLE__) #elif defined(_WIN32) || defined(__UEFI__) #else #error Unsupported target It works today BY ACCIDENT. `_WIN32` and `__MINGW32__` are suppressed by `[c-abi] presents = "posix"` and `__ELF__` is false, so `__CYGWIN__` is the only operand holding that branch up. Withdraw it and every branch goes false: `#error Unsupported target`, one release from now. This file is NOT installed --- it is compiled only by this package's own build --- so it takes the private define, which is the rule the other five patches in this tree follow and the reason `__libunwind_config.h` does the opposite. Found by enumerating the readers rather than fixing the two that were known. The first shape of this ecosystem change was stopped by cross-verification precisely because a set was compared by sampling; doing it again here would have moved the failure from a `static_assert` to an `#error`, one release later. PATCHES.md records the site and adds `__CYGWIN__` to the grep list that the next person changing this tree is told to run. --- llvm/PATCHES.md | 26 +++++++++++++++++++++ llvm/compiler-rt/lib/builtins/int_lib.h | 23 +++++++++++++++++- llvm/libunwind/include/__libunwind_config.h | 17 ++++++++++---- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/llvm/PATCHES.md b/llvm/PATCHES.md index ca0f2938..a5bdeca8 100644 --- a/llvm/PATCHES.md +++ b/llvm/PATCHES.md @@ -155,6 +155,32 @@ openkal-musl 的 `[c-abi] presents = "posix"` 把它和 `_WIN32`、`__MINGW32__` --- +## 第六处:`compiler-rt/lib/builtins/int_lib.h`(2026-09-21) + +前五处是按「撤掉 `_WIN32` 后会落错分支」找出来的。**第六处是按「撤掉 `__CYGWIN__` 后会 +落错分支」找出来的,而当时没有人去找第二遍。** + +```c +#if defined(__ELF__) || defined(__MINGW32__) || ... || defined(__CYGWIN__) + /* __attribute__((alias)) —— PE 要走的就是这一支 */ +#elif defined(__APPLE__) ... +#elif defined(_WIN32) || defined(__UEFI__) ... +#else +#error Unsupported target +``` + +这个文件今天**靠 `__CYGWIN__` 偶然工作**:`_WIN32`/`__MINGW32__` 被 `[c-abi] presents = +"posix"` 压掉,`__ELF__` 为假,只剩它。mcpp 撤掉 `__CYGWIN__` 之后(2026.9.21.1 的下一版), +三支全部落空,直接 `#error`。 + +它**不是**已安装的头,只由本包自己的构建编译,所以按本文件的规矩用私有 define +`OPENKAL_TARGET_WINDOWS`——而 `__libunwind_config.h` 反过来用 `__mcpp_target_windows__`, +因为它**是**已安装的。两者读不同的宏,回答同一个关于同一个目标的问题,这正是下面那一节 +要求的性质。 + +⚠️ **下一次改这棵树,`grep` 的清单要加上 `__CYGWIN__`**: +`grep -rn "_WIN32\|_WIN64\|__MINGW32__\|__MINGW64__\|__CYGWIN__"`。 + ## ⭐ 一个名字,不是五个 五处补丁全部守卫在 **`OPENKAL`** 上,`cflags` 和 `cxxflags` 各给一次 diff --git a/llvm/compiler-rt/lib/builtins/int_lib.h b/llvm/compiler-rt/lib/builtins/int_lib.h index 943430de..f4fa1465 100644 --- a/llvm/compiler-rt/lib/builtins/int_lib.h +++ b/llvm/compiler-rt/lib/builtins/int_lib.h @@ -48,8 +48,29 @@ #define XSTR(a) STR(a) #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name +// ─── openkal ─── BEGIN +// `OPENKAL_TARGET_WINDOWS` joins this guard, and the alternative was a hard +// `#error Unsupported target` a release from now. +// +// This target is PE, and PE takes the first branch: `__attribute__((alias))` +// is what the GNU/clang toolchain emits for it. Today that branch is reached +// through `__CYGWIN__`, which mcpp defines only because nothing else named +// the target --- BY ACCIDENT, not by this file's intent. `_WIN32` and +// `__MINGW32__` are suppressed here on purpose (`[c-abi] presents = "posix"`) +// and `__ELF__` is false, so when `__CYGWIN__` is withdrawn --- it is, one +// release after mcpp 2026.9.21.1 --- every operand of this `#if` goes false, +// `__APPLE__` and `_WIN32`/`__UEFI__` below are false too, and the `#else` +// is `#error Unsupported target`. +// +// The private define is the right name here, not `__mcpp_target_windows__`: +// this file is NOT installed, it is compiled only by this package's own +// build, and `mcpp.toml` carries `OPENKAL_TARGET_WINDOWS` to it in `cflags`. +// That is the same rule the other five patches in this tree follow, and the +// reason `__libunwind_config.h` does the opposite --- it IS installed. See +// `llvm/PATCHES.md`. #if defined(__ELF__) || defined(__MINGW32__) || defined(__wasm__) || \ - defined(_AIX) || defined(__CYGWIN__) + defined(_AIX) || defined(__CYGWIN__) || defined(OPENKAL_TARGET_WINDOWS) +// ─── openkal ─── END #define COMPILER_RT_ALIAS(name, aliasname) \ COMPILER_RT_ABI __typeof(name) aliasname __attribute__((__alias__(#name))); #elif defined(__APPLE__) diff --git a/llvm/libunwind/include/__libunwind_config.h b/llvm/libunwind/include/__libunwind_config.h index 629ee14f..de862686 100644 --- a/llvm/libunwind/include/__libunwind_config.h +++ b/llvm/libunwind/include/__libunwind_config.h @@ -54,15 +54,24 @@ // through `unwind.h` and `libunwind.h`, both public), so it cannot read // `OPENKAL_TARGET_WINDOWS` --- that is this package's own private build // define (mcpp.toml) and an application calling `unw_getcontext` directly -// against `unw_context_t` does not see it. `__CYGWIN__` is read instead, -// for the same reason `openkal-musl`'s `bits/setjmp.h` reads it: mcpp keeps -// it defined target-wide, an application's compile included. +// against `unw_context_t` does not see it. `__mcpp_target_windows__` is read +// instead (mcpp 2026.9.21.1): mcpp states the target under its OWN name, +// target-wide, an application's compile included. `__CYGWIN__` stays beside +// it so this header is correct on an engine from either side of that release +// --- the new name is absent before it, the old one is withdrawn after a +// later one. The second operand exists so this file has no flag day, not for +// redundancy, and goes once that withdrawal ships. +// +// THE OLD NAME WAS BORROWED AND MEANT SOMETHING ELSE. Upstream reads +// `__CYGWIN__` as "Win32 is available"; a 30-member measurement found four +// packages doing exactly that and reaching `#include `. It +// answered this file's question only by accident. // `UnwindRegistersSave.S` writes exactly the record sized here and reads // `OPENKAL_TARGET_WINDOWS` rather than `__CYGWIN__`, because it is NOT // installed --- compiled only by this package's own build, like // `okm_setjmp.S`. The two answer the same question about the same target // without reading the same macro, which is what has to hold; see that file. -# if defined(_WIN64) || defined(__CYGWIN__) +# if defined(_WIN64) || defined(__mcpp_target_windows__) || defined(__CYGWIN__) // ─── openkal ─── END # define _LIBUNWIND_CONTEXT_SIZE 54 # ifdef __SEH__ From 29c4a5021854c9998e6d268b507877c1ba262cbb Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 03:04:09 +0800 Subject: [PATCH 2/3] 0.14.0 --- follow openkal-musl 0.19.0 Both packages move onto mcpp's own name for the target in the same step, because both reasons are the same reason: an INSTALLED header is read by an application's own compile, and a package-private define never reaches it. THE PIN MOVES WITH IT, AND THE ORDER IS THE ONE THIS ECOSYSTEM LEARNED THE HARD WAY TODAY. openkal-musl 0.19.0 is registered in the index before this pin is merged; a consumer merged ahead of its dependency's registration made mcpp's own `openkal-cross` job fail earlier in this wave, and the consumer's own CI could not see it --- that CI substitutes working trees for the whole graph, so it cannot observe a missing registration by construction. --- README.md | 4 ++-- mcpp.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7192566b..952ca089 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ C library. ```toml [dependencies] -openkal-llvm-runtime = "0.13.0" +openkal-llvm-runtime = "0.14.0" ``` > **Engine floor (mcpp 2026.9.20.1):** this version of this package pins -> `openkal-musl 0.18.0` and inherits its `[c-abi]` declaration. The engine +> `openkal-musl 0.19.0` and inherits its `[c-abi]` declaration. The engine > assembles the verification probe's command line in one place that REFUSES > to run it without a target selection (`cenv_probe::assemble_argv`), and > `cenv::realise` forces `-fno-short-wchar` on freestanding wchar. Older diff --git a/mcpp.toml b/mcpp.toml index ee6b48d2..95ee8cf2 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-llvm-runtime" -version = "0.13.0" +version = "0.14.0" description = "LLVM's C++ runtime libraries — libc++, libc++abi and libunwind — configured for openkal-musl rather than for a host C library." license = "Apache-2.0" authors = ["mcpplibs"] @@ -216,7 +216,7 @@ sources = [ cflags = ["-DDISABLE_AARCH64_FMV=1"] [dependencies] -openkal-musl = "0.18.0" +openkal-musl = "0.19.0" [build] From 060d37233c8ab9ec6292de16d3db2ffc0c668f19 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 03:39:37 +0800 Subject: [PATCH 3/3] the name is upper case, and two operands remove the ordering constraint Project-owned macros are upper case --- `NDEBUG` and every other one are --- while lower case belongs to the compiler's own predefines (`__linux__`), which mcpp supplies but does not own. 2026.9.21.1 spelt it lower; the release that withdraws `__CYGWIN__` renames it in the same change, so these headers are written against the spelling they will keep. The lower-case name is not read here and does not need to be: it existed for one release and nothing consumed it. Two operands cover every engine --- one up to and including 2026.9.21.1 defines `__CYGWIN__`, the one that withdraws it defines `__MCPP_TARGET_WINDOWS__` --- so these headers have no flag day and the releases may land in either order. `int_lib.h` is unaffected by the spelling: it is not installed, so it takes the package-private `OPENKAL_TARGET_WINDOWS`, which is the rule this tree already follows and the reason `__libunwind_config.h` does the opposite. --- llvm/PATCHES.md | 2 +- llvm/libunwind/include/__libunwind_config.h | 25 ++++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/llvm/PATCHES.md b/llvm/PATCHES.md index a5bdeca8..045eef8c 100644 --- a/llvm/PATCHES.md +++ b/llvm/PATCHES.md @@ -174,7 +174,7 @@ openkal-musl 的 `[c-abi] presents = "posix"` 把它和 `_WIN32`、`__MINGW32__` 三支全部落空,直接 `#error`。 它**不是**已安装的头,只由本包自己的构建编译,所以按本文件的规矩用私有 define -`OPENKAL_TARGET_WINDOWS`——而 `__libunwind_config.h` 反过来用 `__mcpp_target_windows__`, +`OPENKAL_TARGET_WINDOWS`——而 `__libunwind_config.h` 反过来用 `__MCPP_TARGET_WINDOWS__`, 因为它**是**已安装的。两者读不同的宏,回答同一个关于同一个目标的问题,这正是下面那一节 要求的性质。 diff --git a/llvm/libunwind/include/__libunwind_config.h b/llvm/libunwind/include/__libunwind_config.h index de862686..16d0283d 100644 --- a/llvm/libunwind/include/__libunwind_config.h +++ b/llvm/libunwind/include/__libunwind_config.h @@ -54,13 +54,22 @@ // through `unwind.h` and `libunwind.h`, both public), so it cannot read // `OPENKAL_TARGET_WINDOWS` --- that is this package's own private build // define (mcpp.toml) and an application calling `unw_getcontext` directly -// against `unw_context_t` does not see it. `__mcpp_target_windows__` is read -// instead (mcpp 2026.9.21.1): mcpp states the target under its OWN name, -// target-wide, an application's compile included. `__CYGWIN__` stays beside -// it so this header is correct on an engine from either side of that release -// --- the new name is absent before it, the old one is withdrawn after a -// later one. The second operand exists so this file has no flag day, not for -// redundancy, and goes once that withdrawal ships. +// against `unw_context_t` does not see it. `__MCPP_TARGET_WINDOWS__` is read +// instead: mcpp states the target under its OWN name, target-wide, an +// application's compile included. +// +// TWO OPERANDS COVER EVERY ENGINE AND REMOVE THE ORDERING CONSTRAINT. One up +// to and including 2026.9.21.1 defines `__CYGWIN__`, which answers; the +// release that withdraws it defines `__MCPP_TARGET_WINDOWS__`, which answers +// instead. No engine defines neither, so this header has no flag day and the +// two releases may land in either order. The second operand goes once the +// withdrawal has shipped. +// +// 2026.9.21.1 spelt the name in lower case and it is not read here: that +// spelling existed for one release, nothing consumed it, and the release that +// withdraws `__CYGWIN__` renames it in the same change. Project-owned macros +// are upper case; lower case belongs to the compiler's own predefines, which +// mcpp supplies but does not own. // // THE OLD NAME WAS BORROWED AND MEANT SOMETHING ELSE. Upstream reads // `__CYGWIN__` as "Win32 is available"; a 30-member measurement found four @@ -71,7 +80,7 @@ // installed --- compiled only by this package's own build, like // `okm_setjmp.S`. The two answer the same question about the same target // without reading the same macro, which is what has to hold; see that file. -# if defined(_WIN64) || defined(__mcpp_target_windows__) || defined(__CYGWIN__) +# if defined(_WIN64) || defined(__MCPP_TARGET_WINDOWS__) || defined(__CYGWIN__) // ─── openkal ─── END # define _LIBUNWIND_CONTEXT_SIZE 54 # ifdef __SEH__