From 24f77d92a5c577186aa3b986acd71ddb42c9c3ae Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 06:48:47 +0800 Subject: [PATCH 01/10] Reapply "recipes ask whether a header is there instead of inferring it from the platform" This reverts commit 75f5313a6c550c6f10164abba160715eb2765a37. --- pkgs/c/compat.c-ares.lua | 60 +++++++++++++++++++++++++++++++++------- pkgs/c/compat.curl.lua | 50 ++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/pkgs/c/compat.c-ares.lua b/pkgs/c/compat.c-ares.lua index 4a9559c8..50f65bb0 100644 --- a/pkgs/c/compat.c-ares.lua +++ b/pkgs/c/compat.c-ares.lua @@ -1030,7 +1030,9 @@ package = { #define HAVE_BOOL_T /* Define to 1 if you have the clock_gettime function and monotonic timer. */ -/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ +#if __has_include() && !defined(_WIN32) +#define HAVE_CLOCK_GETTIME_MONOTONIC 1 +#endif /* Define to 1 if you have the closesocket function. */ #define HAVE_CLOSESOCKET @@ -1087,7 +1089,12 @@ package = { /* #undef HAVE_GETSERVBYPORT_R */ /* Define to 1 if you have the `gettimeofday' function. */ -/* #undef HAVE_GETTIMEOFDAY */ +/* SUB-SECOND TIME. `ares_timeval.c:93` refuses a configuration that names no + * source of it, and the Win32 one (`GetTickCount64`) needs `windows.h`. A + * POSIX-presenting target has `clock_gettime`, which `time.h` declares. */ +#if __has_include() && !defined(_WIN32) +#define HAVE_GETTIMEOFDAY 1 +#endif /* Define to 1 if you have the `if_indextoname' function. */ /* #undef HAVE_IF_INDEXTONAME */ @@ -1205,10 +1212,22 @@ package = { #define HAVE_STDLIB_H /* Define to 1 if you have the strcasecmp function. */ -/* #undef HAVE_STRCASECMP */ +/* WIN32 CRT NAMES vs POSIX NAMES, decided by what the C environment + * presents rather than by the platform. This block is the Windows branch of a + * recipe that branches on the PLATFORM; over openkal the target is PE and the + * C environment is POSIX, so the CRT spellings are the ones that are absent. + * `__has_builtin` cannot answer for library functions, so these ask the same + * question the headers do: `strings.h` carries the POSIX pair. */ +#if __has_include() +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#endif +/* #undef HAVE_STRCASECMP_ORIGINAL */ /* Define to 1 if you have the strcmpi function. */ +#if !__has_include() #define HAVE_STRCMPI +#endif /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP @@ -1229,7 +1248,9 @@ package = { /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ +#if !__has_include() #define HAVE_STRNICMP +#endif /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ @@ -1276,23 +1297,42 @@ package = { /* Define to 1 if you have the header file. */ #define HAVE_TIME_H -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define to 1 if you have the windows.h header file. */ +/* THESE ASK WHETHER A HEADER IS THERE, SO THEY ASK THE COMPILER. + * + * This block is the Windows branch of a recipe that branches on the PLATFORM, + * and it used to define all four unconditionally. That was true of every + * Windows target this index had until a C library began presenting POSIX on + * one: over openkal the target is still PE, still Win64, and there is no + * `windows.h` --- `ares_setup.h:81` then reached for it and this repository's + * own compatibility measurement recorded + * + * ares_setup.h:81:12: fatal error: 'windows.h' file not found + * + * `__has_include` is standard C and asks the question actually being asked. + * `HAVE_UNISTD_H` gets the same treatment for the same reason, from the other + * side: a POSIX-presenting Windows target HAS it. */ +#if __has_include() +#define HAVE_UNISTD_H 1 +#endif + +#if __has_include() #define HAVE_WINDOWS_H +#endif -/* Define to 1 if you have the winsock2.h header file. */ +#if __has_include() #define HAVE_WINSOCK2_H +#endif -/* Define to 1 if you have the winsock.h header file. */ +#if __has_include() #define HAVE_WINSOCK_H +#endif /* Define to 1 if you have the writev function. */ /* #undef HAVE_WRITEV */ -/* Define to 1 if you have the ws2tcpip.h header file. */ +#if __has_include() #define HAVE_WS2TCPIP_H +#endif /* Define if __system_property_get exists. */ /* #undef HAVE___SYSTEM_PROPERTY_GET */ diff --git a/pkgs/c/compat.curl.lua b/pkgs/c/compat.curl.lua index 1b818cfa..3c2a63e0 100644 --- a/pkgs/c/compat.curl.lua +++ b/pkgs/c/compat.curl.lua @@ -248,20 +248,56 @@ package = { #if defined(__linux__) #define CURL_OS "Linux" -/* glibc's strerror_r returns char*, not int — curl needs to know which */ + +/* `__linux__` ANSWERS "WHICH KERNEL", NOT "WHICH USERSPACE IS INSTALLED", and + * this block used to read it as the second. Every entry below that names a + * HEADER now asks whether that header is reachable, which is the question + * being asked and is standard C; every entry that names a GLIBC extension + * asks for glibc. + * + * Measured: over openkal-musl on x86_64-linux-gnu the kernel is Linux, so + * `__linux__` is correct, and `#define HAVE_LINUX_TCP_H 1` then sent + * `lib/setopt.c:31` to a uapi header that C library does not carry --- + * `fatal error: 'linux/tcp.h' file not found`, one of the failures in this + * repository's own compatibility measurement. */ +#if __has_include() +#define HAVE_LINUX_TCP_H 1 +#endif +/* `__has_include` ANSWERS ABOUT THE HEADER, NOT ABOUT THE FUNCTION, and those + * two come apart here. openkal-musl CARRIES `sys/eventfd.h` and declares + * `eventfd` absent in its `[c-abi-absent]` table, so defining `HAVE_EVENTFD` + * from the header's presence produced a link that mcpp explained by name: + * + * the C library in this graph (musl) declares that it does not supply + * the following, and the link has just asked for it: + * eventfd as timerfd_create + * + * Neither is declared: curl has a poll-based path and takes it. A header + * test cannot stand in for a symbol test. */ +#if __has_include() +#define HAVE_TERMIO_H 1 +#endif +#if __has_include() +#define HAVE_FSETXATTR 1 +#define HAVE_FSETXATTR_5 1 +#endif + +/* WHICH `strerror_r`, AND EXACTLY ONE OF THEM. glibc's returns `char*`, + * POSIX's returns `int`, and `strerr.c:30` refuses a configuration that names + * neither or both. Asking `__linux__` answered "glibc" for musl, which is the + * wrong one; leaving it out answered "neither", which is also refused. */ +#if defined(__GLIBC__) #define HAVE_GLIBC_STRERROR_R 1 +#else +#define HAVE_POSIX_STRERROR_R 1 +#endif + #define HAVE_GETHOSTBYNAME_R 1 #define HAVE_GETHOSTBYNAME_R_6 1 #define HAVE_ACCEPT4 1 #define HAVE_PIPE2 1 -#define HAVE_EVENTFD 1 -#define HAVE_SYS_EVENTFD_H 1 #define HAVE_SENDMMSG 1 #define HAVE_MEMRCHR 1 -#define HAVE_FSETXATTR 1 -#define HAVE_FSETXATTR_5 1 -#define HAVE_LINUX_TCP_H 1 -#define HAVE_TERMIO_H 1 #define HAVE_CLOCK_GETTIME_MONOTONIC_RAW 1 /* Debian/Fedora layout; overridable at runtime with CURLOPT_CAINFO or the * SSL_CERT_FILE environment variable. */ From 2064c4da11c799075c63364d3b10b125474d1bca Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:25:49 +0800 Subject: [PATCH 02/10] `builds` was a statement about the dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every member of this suite keeps its sources under `tests/`, and for a target with no runner the harness measured the cell with `mcpp build`, which builds the PACKAGE. For these members that compiles nothing of the member at all: it compiled their dependencies, exited 0, and this file recorded `builds`. Measured on `archive` for `aarch64-macos`, 1990 objects, none of them from `tests/compression.cpp` or `tests/versions.cpp`. The reading was never wrong in CI, because both pinned targets are runnable there — linux natively and windows through Wine, which the workflow installs and checks. It was wrong the moment a third target was considered, which is what this change was written for. `mcpp test --no-run` compiles and links the member's own tests for the target and does not execute them. The command choice moves into `command_for` so it has a criterion that needs no toolchain, network or member: three selftest legs, one per branch, and the one that matters names `--no-run` rather than `build`. Also drops a tracked `__pycache__/*.pyc` — a compiled artefact of one interpreter version, which produced a diff for anyone running the harness on 3.13 and an untracked second copy for anyone on 3.12 — and widens .gitignore so the next one is not committed either. --- .gitignore | 2 + docs/openkal-compat.md | 11 +++- .../__pycache__/compat.cpython-313.pyc | Bin 21007 -> 0 bytes tests/openkal/compat.py | 56 +++++++++++++++--- 4 files changed, 59 insertions(+), 10 deletions(-) delete mode 100644 tests/openkal/__pycache__/compat.cpython-313.pyc diff --git a/.gitignore b/.gitignore index 126226e1..772af0bf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ tests/examples/*/imgui.ini # plugin bytecode .xpkgindex/plugins/__pycache__/ +__pycache__/ +*.pyc tests/openkal-work/ diff --git a/docs/openkal-compat.md b/docs/openkal-compat.md index 691a179d..92a5158a 100644 --- a/docs/openkal-compat.md +++ b/docs/openkal-compat.md @@ -33,10 +33,19 @@ recorded per target: | Result | Meaning | | --- | --- | | `runs` | the member's tests passed; on a target other than the host they ran through the pinned runner (Wine for Windows) | -| `builds` | the member built, and its tests were not run or did not pass; the first diagnostic is kept | +| `builds` | the member's own tests compiled and linked for the target, and were not run or did not pass; the first diagnostic is kept | | `fails` | the member did not build; the first diagnostic is kept | | `refused` | the member asked this graph for a capability it does not supply, and was told so before anything was compiled | +**A target with no runner is measured with `mcpp test --no-run`, and until it +was, `builds` was a statement about the dependencies.** Every member here keeps +its sources under `tests/`, and `mcpp build` builds the PACKAGE: for a target +this host cannot execute it compiled the member's dependencies, exited 0, and +that exit code was recorded as `builds`. Measured on `archive` for +`aarch64-macos`: 1990 objects, none of them from `tests/compression.cpp` or +`tests/versions.cpp`. `mcpp test --no-run` compiles and links the member's own +tests for the target and does not execute them, which is what this row claims. + **A refusal is not a failure, and the difference is not a matter of degree.** A member that declares `[kernel-abi] requires-interfaces` naming something the resolved implementation does not provide has been answered correctly. Counting diff --git a/tests/openkal/__pycache__/compat.cpython-313.pyc b/tests/openkal/__pycache__/compat.cpython-313.pyc deleted file mode 100644 index 132e623950ab3c9a519af71f8f1f0729b968f938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21007 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 pJ&Z9{!}I0c*pd6jF`| str: return output.strip().splitlines()[-1][:300] if output.strip() else "" +def command_for(target: str, toolchain: str, native: bool, can_run: bool) -> list: + """The command that measures one cell. + + Separated from `measure` so the choice has a criterion that runs without a + toolchain, a network or a member (`compat.py selftest`). It decides what a + published `builds` means, and the reading it produced before was about the + member's dependencies rather than the member. + """ + cmd = ["mcpp", "test", "--toolchain", toolchain] + if not native: + cmd += ["--target", target] + if not can_run: + # `mcpp test --no-run`, NOT `mcpp build`, AND THE DIFFERENCE IS THE + # WHOLE CELL. + # + # `mcpp build` builds the PACKAGE. Every member here keeps its sources + # under `tests/`, so for a target with no runner it compiled the + # member's dependencies, exited 0, and this file recorded `builds` --- a + # statement about musl and zlib with the member's name on it. Measured + # on `archive` for aarch64-macos: 1990 objects, of which none came from + # `tests/compression.cpp` or `tests/versions.cpp`. + # + # `--no-run` compiles and links the member's own tests for the target + # and does not execute them, which is exactly what this cell claims. + cmd.append("--no-run") + return cmd + + def measure(member: str, target: str, pins: dict) -> dict: work = prepare(member, pins) toolchain = pins["toolchain"] native = target == host_triple() runner = (pins.get("runners") or {}).get(target) - can_run = native or (runner and shutil.which(runner[0])) - if can_run: - cmd = ["mcpp", "test", "--toolchain", toolchain] - if not native: - cmd += ["--target", target] - else: - cmd = ["mcpp", "build", "--toolchain", toolchain, "--target", target] + can_run = bool(native or (runner and shutil.which(runner[0]))) + cmd = command_for(target, toolchain, native, can_run) proc = subprocess.run(cmd, cwd=work, capture_output=True, text=True, timeout=pins.get("timeout", 3600)) out = proc.stdout + proc.stderr @@ -434,6 +458,20 @@ def cmd_selftest(_args: argparse.Namespace) -> int: declared_not_portable({"m": {"t1": "why"}}, "m", "t2"), None), ("nor for another member", declared_not_portable({"m": {"t1": "why"}}, "n", "t1"), None), + # The command is what decides whether `builds` is about the member or + # about its dependencies. `mcpp build` was the old answer and compiled + # none of the member; these three pin the new one. + ("a target with no runner builds the member's own tests", + command_for("aarch64-macos", "llvm@22.1.8", False, False), + ["mcpp", "test", "--toolchain", "llvm@22.1.8", + "--target", "aarch64-macos", "--no-run"]), + ("a target with a runner runs them", + command_for("x86_64-windows-gnu", "llvm@22.1.8", False, True), + ["mcpp", "test", "--toolchain", "llvm@22.1.8", + "--target", "x86_64-windows-gnu"]), + ("the host names no target and runs them", + command_for("x86_64-linux-gnu", "llvm@22.1.8", True, True), + ["mcpp", "test", "--toolchain", "llvm@22.1.8"]), ] bad = 0 for name, got, want in cases: From b2682986835fed9344f42155d2f19a5755e14018 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:36:03 +0800 Subject: [PATCH 03/10] a configure snapshot describes a C environment, not an operating system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c-ares cannot run its own configure here, so this package ships gRPC 1.83.0's three frozen `ares_config.h` snapshots and selected between them by the operating system. That was the same question as "which C environment is this" until a C library began presenting POSIX on Windows. Over openkal the target is still PE and still Win64, and `config_windows` then describes nothing that is there: of the sixteen headers it declares absent, fifteen are present in that graph. The diagnostics arrive one macro at a time, which is what made this look like a list of small fixes rather than one wrong answer: ares_setup.h:81 fatal error: 'windows.h' file not found ares_timeval.c:70 call to undeclared function 'gettimeofday' ares_parse_ns_reply.c:71 invalid application of 'sizeof' to an incomplete type 'struct hostent' with thirteen more behind them. Measured directly: give that target `config_linux` and the member goes from `fails` to `runs`. `_WIN32` and `__APPLE__` are the engine's answer to exactly this question — mcpp defines `_WIN32` for a Win32 environment and suppresses it for a POSIX-presenting one — so the three snapshots move into one top-level `generated_files` entry with three arms and the preprocessor selects. This needs no new key in the descriptor and no new axis in the engine. Each arm is its snapshot verbatim, checked byte for byte against the file it came from; none is edited to suit another. Linux and macOS select what they selected before, so neither reading moves. `cflags`/`ldflags` stay per-OS: a real Windows target still needs ws2_32, and a POSIX-presenting one asks for nothing in it. Measured after the change: `runs` on x86_64-windows-gnu and on x86_64-linux-gnu. --- pkgs/c/compat.c-ares.lua | 434 +++++++++++++++++++++------------------ 1 file changed, 238 insertions(+), 196 deletions(-) diff --git a/pkgs/c/compat.c-ares.lua b/pkgs/c/compat.c-ares.lua index 50f65bb0..1505603f 100644 --- a/pkgs/c/compat.c-ares.lua +++ b/pkgs/c/compat.c-ares.lua @@ -76,14 +76,40 @@ package = { -- fail with implicit-declaration errors. cflags = { "-DCARES_STATICLIB", "-DHAVE_CONFIG_H", "-D_GNU_SOURCE", "-D_HAS_EXCEPTIONS=0" }, - linux = { - -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's - -- third_party/cares/config_linux/ares_config.h. gRPC pins c-ares at this - -- exact release (submodule d3a507e == tag v1.34.5) and ships these files - -- precisely so the library can be built without running c-ares' - -- configure/CMake, which is the same thing this package needs. - generated_files = { - ["mcpp_generated/ares_config.h"] = [==[ + -- ONE SNAPSHOT PER C ENVIRONMENT, AND THE PREPROCESSOR PICKS. + -- + -- These are gRPC 1.83.0's three frozen `ares_config.h` files, verbatim, + -- from third_party/cares/config_{windows,darwin,linux}. gRPC pins c-ares + -- at this exact release (submodule d3a507e == tag v1.34.5) and ships + -- them precisely so the library can be built without running configure + -- or CMake, which is what this package needs too. + -- + -- THEY USED TO BE SELECTED BY THE OPERATING SYSTEM, and a configure + -- snapshot describes a C ENVIRONMENT. Those were the same question + -- until a C library began presenting POSIX on Windows: over openkal the + -- target is still PE and still Win64, and `config_windows` then + -- describes nothing that is there. Of the sixteen headers it declares + -- absent, fifteen are present in that graph, and the first three + -- diagnostics a build produced -- `windows.h` not found, then + -- `gettimeofday` undeclared, then `struct hostent` incomplete -- were + -- each one macro of the sixteen, with thirteen more behind them. + -- + -- `_WIN32` AND `__APPLE__` ARE THE ENGINE'S ANSWER TO EXACTLY THIS + -- QUESTION, so the selection needs no new key in this descriptor and no + -- new axis in the engine. mcpp defines `_WIN32` for a Win32 environment + -- and suppresses it for a POSIX-presenting one; the file asks the + -- preprocessor which environment it is being compiled in, which is the + -- question it was always answering. + -- + -- Measured: x86_64-windows-gnu over openkal goes from `fails` to `runs`. + -- Linux and macOS select the same snapshot they selected before, byte + -- for byte, so neither reading moves. + -- + -- `cflags`/`ldflags` stay per-OS below: a real Windows target still + -- needs ws2_32, and a POSIX-presenting one asks for nothing in it. + generated_files = { + ["mcpp_generated/ares_config.h"] = [==[ +#if defined(_WIN32) /* Generated from ares_config.h.cmake*/ /* Define if building universal (internal helper macro) */ @@ -111,7 +137,7 @@ package = { #undef ETC_INET /* Define to the type of arg 2 for gethostname. */ -#define GETHOSTNAME_TYPE_ARG2 size_t +#define GETHOSTNAME_TYPE_ARG2 int /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 @@ -129,19 +155,19 @@ package = { #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ -#define GETSERVBYPORT_R_ARGS 6 +#define GETSERVBYPORT_R_ARGS /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 /* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H +/* #undef HAVE_ARPA_INET_H */ /* Define to 1 if you have the header file. */ -#define HAVE_ARPA_NAMESER_COMPAT_H +/* #undef HAVE_ARPA_NAMESER_COMPAT_H */ /* Define to 1 if you have the header file. */ -#define HAVE_ARPA_NAMESER_H +/* #undef HAVE_ARPA_NAMESER_H */ /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H @@ -153,10 +179,12 @@ package = { #define HAVE_BOOL_T /* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#if __has_include() && !defined(_WIN32) #define HAVE_CLOCK_GETTIME_MONOTONIC 1 +#endif /* Define to 1 if you have the closesocket function. */ -/* #undef HAVE_CLOSESOCKET */ +#define HAVE_CLOSESOCKET /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ @@ -168,19 +196,19 @@ package = { /* #undef HAVE_CXX11 */ /* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H +/* #undef HAVE_DLFCN_H */ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H /* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL +/* #undef HAVE_FCNTL */ /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK +/* #undef HAVE_FCNTL_O_NONBLOCK */ /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO @@ -189,7 +217,7 @@ package = { #define HAVE_GETADDRINFO /* Define to 1 if the getaddrinfo function is threadsafe. */ -/* #undef HAVE_GETADDRINFO_THREADSAFE */ +#define HAVE_GETADDRINFO_THREADSAFE /* Define to 1 if you have the getenv function. */ #define HAVE_GETENV @@ -207,31 +235,36 @@ package = { #define HAVE_GETNAMEINFO /* Define to 1 if you have the getservbyport_r function. */ -#define HAVE_GETSERVBYPORT_R +/* #undef HAVE_GETSERVBYPORT_R */ /* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY +/* SUB-SECOND TIME. `ares_timeval.c:93` refuses a configuration that names no + * source of it, and the Win32 one (`GetTickCount64`) needs `windows.h`. A + * POSIX-presenting target has `clock_gettime`, which `time.h` declares. */ +#if __has_include() && !defined(_WIN32) +#define HAVE_GETTIMEOFDAY 1 +#endif /* Define to 1 if you have the `if_indextoname' function. */ -#define HAVE_IF_INDEXTONAME +/* #undef HAVE_IF_INDEXTONAME */ /* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -#define HAVE_INET_NTOP +/* #undef HAVE_INET_NTOP */ /* Define to 1 if you have a IPv6 capable working inet_pton function. */ -#define HAVE_INET_PTON +/* #undef HAVE_INET_PTON */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H /* Define to 1 if you have the ioctl function. */ -#define HAVE_IOCTL +/* #undef HAVE_IOCTL */ /* Define to 1 if you have the ioctlsocket function. */ -/* #undef HAVE_IOCTLSOCKET */ +#define HAVE_IOCTLSOCKET /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ @@ -241,13 +274,13 @@ package = { /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -/* #undef HAVE_IOCTLSOCKET_FIONBIO */ +#define HAVE_IOCTLSOCKET_FIONBIO /* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO +/* #undef HAVE_IOCTL_FIONBIO */ /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#define HAVE_IOCTL_SIOCGIFADDR +/* #undef HAVE_IOCTL_SIOCGIFADDR */ /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLV */ @@ -268,19 +301,19 @@ package = { #define HAVE_MEMORY_H /* Define to 1 if you have the MSG_NOSIGNAL flag. */ -#define HAVE_MSG_NOSIGNAL +/* #undef HAVE_MSG_NOSIGNAL */ /* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H +/* #undef HAVE_NETDB_H */ /* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H +/* #undef HAVE_NETINET_IN_H */ /* Define to 1 if you have the header file. */ -#define HAVE_NETINET_TCP_H +/* #undef HAVE_NETINET_TCP_H */ /* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H +/* #undef HAVE_NET_IF_H */ /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 @@ -328,34 +361,48 @@ package = { #define HAVE_STDLIB_H /* Define to 1 if you have the strcasecmp function. */ -#define HAVE_STRCASECMP +/* WIN32 CRT NAMES vs POSIX NAMES, decided by what the C environment + * presents rather than by the platform. This block is the Windows branch of a + * recipe that branches on the PLATFORM; over openkal the target is PE and the + * C environment is POSIX, so the CRT spellings are the ones that are absent. + * `__has_builtin` cannot answer for library functions, so these ask the same + * question the headers do: `strings.h` carries the POSIX pair. */ +#if __has_include() +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#endif +/* #undef HAVE_STRCASECMP_ORIGINAL */ /* Define to 1 if you have the strcmpi function. */ -/* #undef HAVE_STRCMPI */ +#if !__has_include() +#define HAVE_STRCMPI +#endif /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP /* Define to 1 if you have the stricmp function. */ -/* #undef HAVE_STRICMP */ +#define HAVE_STRICMP /* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H +/* #undef HAVE_STRINGS_H */ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H /* Define to 1 if you have the strncasecmp function. */ -#define HAVE_STRNCASECMP +/* #undef HAVE_STRNCASECMP */ /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ -/* #undef HAVE_STRNICMP */ +#if !__has_include() +#define HAVE_STRNICMP +#endif /* Define to 1 if you have the header file. */ -#define HAVE_STROPTS_H +/* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO @@ -373,49 +420,82 @@ package = { #define HAVE_STRUCT_TIMEVAL /* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H +/* #undef HAVE_SYS_IOCTL_H */ /* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H +/* #undef HAVE_SYS_PARAM_H */ /* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H +/* #undef HAVE_SYS_SELECT_H */ /* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H +/* #undef HAVE_SYS_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H -/* Define to 1 if you have the header file. */ +/* THE HEADER THAT DECLARES THE FALLBACK THIS BRANCH ALREADY TAKES. + * + * `HAVE_GETTIMEOFDAY` and `HAVE_CLOCK_GETTIME_MONOTONIC` are defined above + * for a target whose C library supplies them, and `ares_timeval.c` then + * compiles the `clock_gettime` branch --- whose failure path calls + * `gettimeofday` with no guard of its own, because upstream takes one to + * imply the other. Leaving this `#undef` while those two are defined states + * that the function exists and its header does not: + * + * ares_timeval.c:70:11: error: call to undeclared function + * 'gettimeofday' + * + * Asked rather than assumed, for the same reason as the four below. */ +#if __has_include() #define HAVE_SYS_TIME_H +#endif /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ -#define HAVE_SYS_UIO_H +/* #undef HAVE_SYS_UIO_H */ /* Define to 1 if you have the header file. */ #define HAVE_TIME_H -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H +/* THESE ASK WHETHER A HEADER IS THERE, SO THEY ASK THE COMPILER. + * + * This block is the Windows branch of a recipe that branches on the PLATFORM, + * and it used to define all four unconditionally. That was true of every + * Windows target this index had until a C library began presenting POSIX on + * one: over openkal the target is still PE, still Win64, and there is no + * `windows.h` --- `ares_setup.h:81` then reached for it and this repository's + * own compatibility measurement recorded + * + * ares_setup.h:81:12: fatal error: 'windows.h' file not found + * + * `__has_include` is standard C and asks the question actually being asked. + * `HAVE_UNISTD_H` gets the same treatment for the same reason, from the other + * side: a POSIX-presenting Windows target HAS it. */ +#if __has_include() +#define HAVE_UNISTD_H 1 +#endif -/* Define to 1 if you have the windows.h header file. */ -/* #undef HAVE_WINDOWS_H */ +#if __has_include() +#define HAVE_WINDOWS_H +#endif -/* Define to 1 if you have the winsock2.h header file. */ -/* #undef HAVE_WINSOCK2_H */ +#if __has_include() +#define HAVE_WINSOCK2_H +#endif -/* Define to 1 if you have the winsock.h header file. */ -/* #undef HAVE_WINSOCK_H */ +#if __has_include() +#define HAVE_WINSOCK_H +#endif /* Define to 1 if you have the writev function. */ -#define HAVE_WRITEV +/* #undef HAVE_WRITEV */ -/* Define to 1 if you have the ws2tcpip.h header file. */ -/* #undef HAVE_WS2TCPIP_H */ +#if __has_include() +#define HAVE_WS2TCPIP_H +#endif /* Define if __system_property_get exists. */ /* #undef HAVE___SYSTEM_PROPERTY_GET */ @@ -433,7 +513,7 @@ package = { #define RECVFROM_QUAL_ARG5 /* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int +#define RECVFROM_TYPE_ARG1 SOCKET /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void * @@ -442,7 +522,7 @@ package = { #define RECVFROM_TYPE_ARG2_IS_VOID 0 /* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 size_t +#define RECVFROM_TYPE_ARG3 int /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int @@ -460,22 +540,22 @@ package = { #define RECVFROM_TYPE_ARG6_IS_VOID 0 /* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV ssize_t +#define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int +#define RECV_TYPE_ARG1 SOCKET /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 size_t +#define RECV_TYPE_ARG3 int /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ -#define RECV_TYPE_RETV ssize_t +#define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE @@ -484,22 +564,22 @@ package = { #define SEND_QUAL_ARG2 /* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int +#define SEND_TYPE_ARG1 SOCKET /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 size_t +#define SEND_TYPE_ARG3 int /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ -#define SEND_TYPE_RETV ssize_t +#define SEND_TYPE_RETV int /* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME +/* #undef TIME_WITH_SYS_TIME */ /* Define to disable non-blocking sockets. */ #undef USE_BLOCKING_SOCKETS @@ -509,18 +589,11 @@ package = { /* Type to use in place of in_addr_t when system does not provide it. */ #undef in_addr_t -]==], - }, - ldflags = { "-lpthread" }, - }, - macosx = { - -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's - -- third_party/cares/config_darwin/ares_config.h. gRPC pins c-ares at this - -- exact release (submodule d3a507e == tag v1.34.5) and ships these files - -- precisely so the library can be built without running c-ares' - -- configure/CMake, which is the same thing this package needs. - generated_files = { - ["mcpp_generated/ares_config.h"] = [==[ + +/* gRPC manual edits here! */ +#define HAVE_IPHLPAPI_H +#define HAVE_NETIOAPI_H +#elif defined(__APPLE__) /* Generated from ares_config.h.cmake*/ /* Define if building universal (internal helper macro) */ @@ -948,19 +1021,7 @@ package = { /* Type to use in place of in_addr_t when system does not provide it. */ #undef in_addr_t -]==], - }, - -- config_darwin defines HAVE_LIBRESOLV, so res_* comes from libresolv. - ldflags = { "-lresolv" }, - }, - windows = { - -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's - -- third_party/cares/config_windows/ares_config.h. gRPC pins c-ares at this - -- exact release (submodule d3a507e == tag v1.34.5) and ships these files - -- precisely so the library can be built without running c-ares' - -- configure/CMake, which is the same thing this package needs. - generated_files = { - ["mcpp_generated/ares_config.h"] = [==[ +#else /* Generated from ares_config.h.cmake*/ /* Define if building universal (internal helper macro) */ @@ -988,7 +1049,7 @@ package = { #undef ETC_INET /* Define to the type of arg 2 for gethostname. */ -#define GETHOSTNAME_TYPE_ARG2 int +#define GETHOSTNAME_TYPE_ARG2 size_t /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 @@ -1006,19 +1067,19 @@ package = { #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ -#define GETSERVBYPORT_R_ARGS +#define GETSERVBYPORT_R_ARGS 6 /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 /* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_INET_H */ +#define HAVE_ARPA_INET_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_NAMESER_COMPAT_H */ +#define HAVE_ARPA_NAMESER_COMPAT_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_NAMESER_H */ +#define HAVE_ARPA_NAMESER_H /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H @@ -1030,12 +1091,10 @@ package = { #define HAVE_BOOL_T /* Define to 1 if you have the clock_gettime function and monotonic timer. */ -#if __has_include() && !defined(_WIN32) #define HAVE_CLOCK_GETTIME_MONOTONIC 1 -#endif /* Define to 1 if you have the closesocket function. */ -#define HAVE_CLOSESOCKET +/* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ @@ -1047,19 +1106,19 @@ package = { /* #undef HAVE_CXX11 */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ +#define HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H /* Define to 1 if you have the fcntl function. */ -/* #undef HAVE_FCNTL */ +#define HAVE_FCNTL /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -/* #undef HAVE_FCNTL_O_NONBLOCK */ +#define HAVE_FCNTL_O_NONBLOCK /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO @@ -1068,7 +1127,7 @@ package = { #define HAVE_GETADDRINFO /* Define to 1 if the getaddrinfo function is threadsafe. */ -#define HAVE_GETADDRINFO_THREADSAFE +/* #undef HAVE_GETADDRINFO_THREADSAFE */ /* Define to 1 if you have the getenv function. */ #define HAVE_GETENV @@ -1086,36 +1145,31 @@ package = { #define HAVE_GETNAMEINFO /* Define to 1 if you have the getservbyport_r function. */ -/* #undef HAVE_GETSERVBYPORT_R */ +#define HAVE_GETSERVBYPORT_R /* Define to 1 if you have the `gettimeofday' function. */ -/* SUB-SECOND TIME. `ares_timeval.c:93` refuses a configuration that names no - * source of it, and the Win32 one (`GetTickCount64`) needs `windows.h`. A - * POSIX-presenting target has `clock_gettime`, which `time.h` declares. */ -#if __has_include() && !defined(_WIN32) -#define HAVE_GETTIMEOFDAY 1 -#endif +#define HAVE_GETTIMEOFDAY /* Define to 1 if you have the `if_indextoname' function. */ -/* #undef HAVE_IF_INDEXTONAME */ +#define HAVE_IF_INDEXTONAME /* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/* #undef HAVE_INET_NTOP */ +#define HAVE_INET_NTOP /* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/* #undef HAVE_INET_PTON */ +#define HAVE_INET_PTON /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H /* Define to 1 if you have the ioctl function. */ -/* #undef HAVE_IOCTL */ +#define HAVE_IOCTL /* Define to 1 if you have the ioctlsocket function. */ -#define HAVE_IOCTLSOCKET +/* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ @@ -1125,13 +1179,13 @@ package = { /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -#define HAVE_IOCTLSOCKET_FIONBIO +/* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ -/* #undef HAVE_IOCTL_FIONBIO */ +#define HAVE_IOCTL_FIONBIO /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -/* #undef HAVE_IOCTL_SIOCGIFADDR */ +#define HAVE_IOCTL_SIOCGIFADDR /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLV */ @@ -1152,19 +1206,19 @@ package = { #define HAVE_MEMORY_H /* Define to 1 if you have the MSG_NOSIGNAL flag. */ -/* #undef HAVE_MSG_NOSIGNAL */ +#define HAVE_MSG_NOSIGNAL /* Define to 1 if you have the header file. */ -/* #undef HAVE_NETDB_H */ +#define HAVE_NETDB_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_IN_H */ +#define HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_TCP_H */ +#define HAVE_NETINET_TCP_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_NET_IF_H */ +#define HAVE_NET_IF_H /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 @@ -1212,48 +1266,34 @@ package = { #define HAVE_STDLIB_H /* Define to 1 if you have the strcasecmp function. */ -/* WIN32 CRT NAMES vs POSIX NAMES, decided by what the C environment - * presents rather than by the platform. This block is the Windows branch of a - * recipe that branches on the PLATFORM; over openkal the target is PE and the - * C environment is POSIX, so the CRT spellings are the ones that are absent. - * `__has_builtin` cannot answer for library functions, so these ask the same - * question the headers do: `strings.h` carries the POSIX pair. */ -#if __has_include() -#define HAVE_STRCASECMP 1 -#define HAVE_STRNCASECMP 1 -#endif -/* #undef HAVE_STRCASECMP_ORIGINAL */ +#define HAVE_STRCASECMP /* Define to 1 if you have the strcmpi function. */ -#if !__has_include() -#define HAVE_STRCMPI -#endif +/* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP /* Define to 1 if you have the stricmp function. */ -#define HAVE_STRICMP +/* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ +#define HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #define HAVE_STRING_H /* Define to 1 if you have the strncasecmp function. */ -/* #undef HAVE_STRNCASECMP */ +#define HAVE_STRNCASECMP /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ -#if !__has_include() -#define HAVE_STRNICMP -#endif +/* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_STROPTS_H */ +#define HAVE_STROPTS_H /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO @@ -1271,68 +1311,49 @@ package = { #define HAVE_STRUCT_TIMEVAL /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_IOCTL_H */ +#define HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_PARAM_H */ +#define HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SELECT_H */ +#define HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKET_H */ +#define HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIME_H */ +#define HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UIO_H */ +#define HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #define HAVE_TIME_H -/* THESE ASK WHETHER A HEADER IS THERE, SO THEY ASK THE COMPILER. - * - * This block is the Windows branch of a recipe that branches on the PLATFORM, - * and it used to define all four unconditionally. That was true of every - * Windows target this index had until a C library began presenting POSIX on - * one: over openkal the target is still PE, still Win64, and there is no - * `windows.h` --- `ares_setup.h:81` then reached for it and this repository's - * own compatibility measurement recorded - * - * ares_setup.h:81:12: fatal error: 'windows.h' file not found - * - * `__has_include` is standard C and asks the question actually being asked. - * `HAVE_UNISTD_H` gets the same treatment for the same reason, from the other - * side: a POSIX-presenting Windows target HAS it. */ -#if __has_include() -#define HAVE_UNISTD_H 1 -#endif +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H -#if __has_include() -#define HAVE_WINDOWS_H -#endif +/* Define to 1 if you have the windows.h header file. */ +/* #undef HAVE_WINDOWS_H */ -#if __has_include() -#define HAVE_WINSOCK2_H -#endif +/* Define to 1 if you have the winsock2.h header file. */ +/* #undef HAVE_WINSOCK2_H */ -#if __has_include() -#define HAVE_WINSOCK_H -#endif +/* Define to 1 if you have the winsock.h header file. */ +/* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ -/* #undef HAVE_WRITEV */ +#define HAVE_WRITEV -#if __has_include() -#define HAVE_WS2TCPIP_H -#endif +/* Define to 1 if you have the ws2tcpip.h header file. */ +/* #undef HAVE_WS2TCPIP_H */ /* Define if __system_property_get exists. */ /* #undef HAVE___SYSTEM_PROPERTY_GET */ @@ -1350,7 +1371,7 @@ package = { #define RECVFROM_QUAL_ARG5 /* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET +#define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void * @@ -1359,7 +1380,7 @@ package = { #define RECVFROM_TYPE_ARG2_IS_VOID 0 /* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int +#define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int @@ -1377,22 +1398,22 @@ package = { #define RECVFROM_TYPE_ARG6_IS_VOID 0 /* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int +#define RECVFROM_TYPE_RETV ssize_t /* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET +#define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int +#define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int +#define RECV_TYPE_RETV ssize_t /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE @@ -1401,22 +1422,22 @@ package = { #define SEND_QUAL_ARG2 /* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET +#define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int +#define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ -#define SEND_TYPE_RETV int +#define SEND_TYPE_RETV ssize_t /* Define to 1 if you can safely include both and . */ -/* #undef TIME_WITH_SYS_TIME */ +#define TIME_WITH_SYS_TIME /* Define to disable non-blocking sockets. */ #undef USE_BLOCKING_SOCKETS @@ -1426,12 +1447,33 @@ package = { /* Type to use in place of in_addr_t when system does not provide it. */ #undef in_addr_t - -/* gRPC manual edits here! */ -#define HAVE_IPHLPAPI_H -#define HAVE_NETIOAPI_H +#endif ]==], - }, + }, + + linux = { + -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's + -- third_party/cares/config_linux/ares_config.h. gRPC pins c-ares at this + -- exact release (submodule d3a507e == tag v1.34.5) and ships these files + -- precisely so the library can be built without running c-ares' + -- configure/CMake, which is the same thing this package needs. + ldflags = { "-lpthread" }, + }, + macosx = { + -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's + -- third_party/cares/config_darwin/ares_config.h. gRPC pins c-ares at this + -- exact release (submodule d3a507e == tag v1.34.5) and ships these files + -- precisely so the library can be built without running c-ares' + -- configure/CMake, which is the same thing this package needs. + -- config_darwin defines HAVE_LIBRESOLV, so res_* comes from libresolv. + ldflags = { "-lresolv" }, + }, + windows = { + -- Frozen configure snapshot, taken verbatim from gRPC 1.83.0's + -- third_party/cares/config_windows/ares_config.h. gRPC pins c-ares at this + -- exact release (submodule d3a507e == tag v1.34.5) and ships these files + -- precisely so the library can be built without running c-ares' + -- configure/CMake, which is the same thing this package needs. cflags = { "-DNOMINMAX", "-D_CRT_SECURE_NO_DEPRECATE", "-D_CRT_NONSTDC_NO_DEPRECATE", "-D_WIN32_WINNT=0x0600" }, ldflags = { "-lws2_32", "-liphlpapi" }, }, From a11fd34fad4b7b30776e09b827238d058769e0f6 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:40:49 +0800 Subject: [PATCH 04/10] a library built outside the graph says so MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `compat.openssl` runs OpenSSL's own Configure and make from `install()`, outside mcpp's compile rules. `cc_override()` hands that build `gcc --sysroot=` on linux and `/usr/bin/cc` on macOS, so the archive is a glibc or libSystem artefact — and the hook cannot be otherwise, because it runs once at install time and knows nothing about the graph a later consumer will resolve. Linked into a graph whose C library is musl, it fails at symbols that library does not have. Measured on x86_64-linux-gnu over openkal: ld.lld: error: undefined symbol: setcontext >>> referenced by async.c >>> libcrypto-lib-async.o in archive .../libcrypto.a musl omits the `*context` family deliberately, and `__isoc23_strtol` is glibc's header redirection for `strtol`. Neither names the cause, and both arrive after a successful configure, compile and archive step. `provides = ["platform-sdk"]` is the engine's existing word for "this package brings the platform's own side into the graph" (docs/06). It does not make the link succeed and is not meant to. Measured, it puts the fact where a reader and a machine can both see it: Target platform-deps openssl@3.5.1 and with `[build] platform-dependencies = "refuse"`: error: [build] platform-dependencies = "refuse", and the dependency graph brings a platform dependency: openssl@3.5.1. Building OpenSSL inside the graph is what would make the link succeed. That is a different change: its source list comes from Configure, so it needs the snapshot treatment compat.c-ares and compat.ffmpeg have. --- pkgs/c/compat.openssl.lua | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pkgs/c/compat.openssl.lua b/pkgs/c/compat.openssl.lua index 0cabfac8..e4b63f02 100644 --- a/pkgs/c/compat.openssl.lua +++ b/pkgs/c/compat.openssl.lua @@ -132,6 +132,41 @@ package = { include_dirs = { "include" }, deps = { }, + -- THIS ARCHIVE IS BOUND TO THE C LIBRARY IT WAS BUILT AGAINST, AND + -- SAYING SO IS THE ONLY THING THAT MAKES THAT VISIBLE. + -- + -- `install()` runs OpenSSL's own Configure and make, outside mcpp's + -- compile rules, once per installed package. `cc_override()` hands + -- that build `gcc --sysroot=` on linux and + -- `/usr/bin/cc` on macOS, so the archive it produces is a glibc (or + -- libSystem) artefact -- and the hook cannot be otherwise, because it + -- runs at install time and knows nothing about the graph any later + -- consumer will resolve. + -- + -- Linked into a graph with a different C library, it fails at symbols + -- that library does not have. Measured on x86_64-linux-gnu over + -- openkal, whose c-abi is musl: + -- + -- ld.lld: error: undefined symbol: setcontext + -- >>> referenced by async.c + -- >>> libcrypto-lib-async.o in archive .../libcrypto.a + -- + -- (musl omits the `*context` family deliberately), and + -- `__isoc23_strtol`, which is glibc's header redirection for + -- `strtol`. + -- + -- `platform-sdk` is the engine's existing word for "this package + -- brings the platform's own side into the graph" (docs/06, "Making it + -- visible to the closure"). Declaring it does not make the link + -- succeed, and is not meant to: it puts the package on every build's + -- `Target` report and lets `[build] platform-dependencies = "refuse"` + -- fail the build with the cause rather than with a missing symbol + -- three layers down. Building OpenSSL inside the graph is what would + -- make the link succeed, and that is a different change: its source + -- list comes from Configure, so it needs the snapshot treatment + -- compat.c-ares and compat.ffmpeg have. + provides = { "platform-sdk" }, + linux = { ldflags = { "-Llib", From c1b4b3e457a9d93cb3b34ca8b7c355aa35eed671 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:42:53 +0800 Subject: [PATCH 05/10] curl's two cells have one cause, and it is not curl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both targets fail because this graph supplies no TLS provider, and the member's own test refuses a curl without one — transfer.cpp:45 fails when CURL_VERSION_SSL is clear, on the stated reasoning that "a curl built with no SSL still links and still runs, it just silently cannot do https". Configuring the member without TLS would turn both cells green and measure a different library. On linux the provider is compat.openssl, which is built by an install() hook through OpenSSL's own Configure and is therefore a glibc artefact; it now declares `provides = ["platform-sdk"]` and fails this link at `setcontext` and `__isoc23_strtol`. On windows the provider is Schannel, selected together with the checked-in lib/config-win32.h by `_WIN32` — the macro a C library presenting POSIX on Windows does not define. With neither HAVE_CONFIG_H nor _WIN32 curl reads no configuration at all and stops at `curl_setup.h:591: "too small curl_off_t"`, which names a consequence 591 lines away from its cause. compat.openssl has no Windows build, so there is no second provider to fall back to. Declared rather than left unexplained, and the declaration is falsifiable: `compat.py check` fails if a declared cell builds, so an in-graph OpenSSL would force these lines to be removed rather than quietly keeping a stale excuse. --- tests/openkal/members.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/openkal/members.toml b/tests/openkal/members.toml index 1d9172d4..e6dc9b1a 100644 --- a/tests/openkal/members.toml +++ b/tests/openkal/members.toml @@ -50,6 +50,14 @@ cmp-module = "coroutines, C++ modules" # `curl`'s `linux/tcp.h` is exactly that, `#define HAVE_LINUX_TCP_H 1` inside # `#if defined(__linux__)` in `pkgs/c/compat.curl.lua`. What qualifies is # upstream source that asks in the preprocessor where no key can answer. +[not-portable.curl] +# Both targets, one cause: this graph supplies no TLS provider, and the member's +# own test refuses a curl without one -- transfer.cpp:45 fails when +# CURL_VERSION_SSL is clear, because "a curl built with no SSL still links and +# still runs, it just silently cannot do https". +x86_64-linux-gnu = "curl's TLS backend here is compat.openssl, which builds through OpenSSL's own Configure from an install() hook and is therefore a glibc artefact: it declares provides = [\"platform-sdk\"] and fails this graph's link at setcontext and __isoc23_strtol, which musl does not have. Building OpenSSL inside the graph would change this cell." +x86_64-windows-gnu = "curl's Windows configuration is Schannel plus the checked-in lib/config-win32.h, and both are selected by _WIN32, which a C library presenting POSIX on Windows does not define. With neither HAVE_CONFIG_H nor _WIN32, curl_setup.h reads no configuration at all and stops at curl_setup.h:591 'too small curl_off_t', which names a consequence and not the cause. compat.openssl has no Windows build, so there is no second TLS provider to fall back to." + [not-portable.cmp-module] x86_64-linux-gnu = "asio's detail/config.hpp:899 includes whenever __linux__ is defined, OUTSIDE every ASIO_DISABLE_* guard, so no configuration macro prevents it. openkal runs on the Linux kernel, so __linux__ is correct; the uapi headers glibc's userspace installs beside it are not part of what openkal presents." From e82b3201913259a9aba742d71a1416402ca03070 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:44:22 +0800 Subject: [PATCH 06/10] two of the three guards that would have excluded this target never arrive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mimalloc's prim-tls.h:176 enables `__builtin_thread_pointer()` for x86_64 with clang >= 14 unless `__APPLE__`, `__CYGWIN__` or `MI_LIBC_MUSL` says otherwise. Two of those three describe this target and neither reaches it: mcpp suppresses `__CYGWIN__` deliberately, because source must not read the realisation triple as a statement about Cygwin, and `MI_LIBC_MUSL` is a build option upstream expects the packager to set ("Enable this when linking with musl libc", CMakeLists.txt:39) rather than something it detects. So the guard passes and LLVM has no lowering for the builtin on this OS: fatal error: error in backend: Target OS doesn't support __builtin_thread_pointer() yet. which arrives as a backend crash with no source location, and reaches the compatibility results as the bare line "error: build failed". prim-tls.h:176 opens with `#if !defined(MI_USE_BUILTIN_THREAD_POINTER) /* allow user override */`, so the fix is to give it one. It goes in the Windows branch, where a Win32 target never reads it — `_WIN32` selects `NtCurrentTeb()` three arms earlier — so it changes only the target that has no `_WIN32`. Measured: `runs` on x86_64-windows-gnu and unchanged `runs` on x86_64-linux-gnu. --- pkgs/c/compat.mimalloc.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkgs/c/compat.mimalloc.lua b/pkgs/c/compat.mimalloc.lua index 41829663..ab0e8913 100644 --- a/pkgs/c/compat.mimalloc.lua +++ b/pkgs/c/compat.mimalloc.lua @@ -112,6 +112,30 @@ package = { runtime = { libraries = { "psapi", "shell32", "user32", "advapi32", "bcrypt" }, }, + + -- `__builtin_thread_pointer()` IS NOT AVAILABLE FOR EVERY OS THE + -- TRIPLE CAN NAME, AND THE FAILURE IS A BACKEND CRASH. + -- + -- prim-tls.h:176 turns the builtin on for x86_64 with clang >= 14 + -- unless `__APPLE__`, `__CYGWIN__` or `MI_LIBC_MUSL` says + -- otherwise. Two of those three would have excluded this target + -- and neither reaches it: mcpp suppresses `__CYGWIN__` on purpose, + -- because source must not read the realisation triple as a + -- statement about Cygwin, and `MI_LIBC_MUSL` is a build option + -- upstream expects the packager to set ("Enable this when linking + -- with musl libc", CMakeLists.txt:39) rather than something it + -- detects. So the guard passes, and LLVM has no lowering for the + -- builtin on this OS: + -- + -- fatal error: error in backend: Target OS doesn't support + -- __builtin_thread_pointer() yet. + -- + -- prim-tls.h:176 opens with `#if !defined(...) /* allow user + -- override */`, so the answer is to give it one. This is the + -- Windows branch, and on a Win32 target the setting is not read at + -- all --- `_WIN32` selects `NtCurrentTeb()` three arms earlier --- + -- so it changes only the target that has no `_WIN32`. + cflags = { "-DMI_USE_BUILTIN_THREAD_POINTER=0" }, }, }, } From 48a7ab54709dc4fb61112ab23840074ecb1148bb Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 07:51:23 +0800 Subject: [PATCH 07/10] a static image cannot answer dladdr, and that is not a failure expat's member asserts that the code which parsed is not the ecosystem payload's libexpat, and asks `dladdr` to attribute it. musl's `dladdr` is `weak_alias(stub_dladdr, dladdr)` returning 0 (src/ldso/dladdr.c); the dynamic loader overrides it, and a static link has no loader to do so. An openkal program is statically linked, so the call returns 0 for every address and the member failed one check on both targets. The risk the check exists for cannot arise there either: nothing was loaded at runtime, so the only expat in the process is the one that was linked in. Skipping it would make "no loader" and "the loader answered wrongly" the same reading, so the fallback asserts what distinguishes them. `main` is in this executable by construction; if `dladdr` cannot locate that either, there is no dynamic symbol information at all. If it locates `main` and not `XML_ParserCreate`, the check fails as it did before. Measured both ways: `runs` on both openkal targets, and on a dynamic host build the positive branch still runs and still prints what it resolved. --- tests/examples/expat/tests/xml.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/examples/expat/tests/xml.cpp b/tests/examples/expat/tests/xml.cpp index ce605881..e371622e 100644 --- a/tests/examples/expat/tests/xml.cpp +++ b/tests/examples/expat/tests/xml.cpp @@ -102,17 +102,39 @@ int main() // the same either way: the code that just parsed must not have come from // the ecosystem's `xim:expat`, which is present whenever Mesa is and would // otherwise answer silently. + // + // A STATICALLY LINKED BINARY CANNOT ANSWER THIS, AND THAT IS NOT A + // FAILURE. musl's `dladdr` is `weak_alias(stub_dladdr, dladdr)` returning + // 0 (src/ldso/dladdr.c); the dynamic loader overrides it, and a static + // link has no loader to do so. An openkal program is statically linked, so + // the call returns 0 for every address, and the risk this check exists for + // cannot arise there either: nothing was loaded at runtime, so the only + // expat in the process is the one that was linked in. + // + // SKIPPING IT SILENTLY WOULD MAKE "no loader" AND "the loader answered + // wrongly" THE SAME READING, so the fallback asserts what distinguishes + // them. `main` is in this executable by construction; if `dladdr` cannot + // locate that either, there is no dynamic symbol information at all and + // the question is moot. If it locates `main` but not `XML_ParserCreate`, + // something is wrong and the check fails as before. { Dl_info info{}; const bool located = ::dladdr(reinterpret_cast(&XML_ParserCreate), &info) != 0 && info.dli_fname != nullptr; - check(located, "dladdr locates the code that parsed"); if (located) { const std::string from = info.dli_fname; std::printf(" resolved from: %s\n", from.c_str()); check(from.find("xim-x-expat") == std::string::npos, "it is not the ecosystem payload's libexpat"); + } else { + Dl_info self{}; + const bool anyAnswer = + ::dladdr(reinterpret_cast(&main), &self) != 0; + std::printf(" dladdr answers nothing in this image%s\n", + anyAnswer ? " EXCEPT main" : " at all (static link)"); + check(!anyAnswer, + "dladdr locates the code that parsed, or locates nothing"); } } From 4eb45a7657bc940000ab844b332184acc8792b4a Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 08:05:30 +0800 Subject: [PATCH 08/10] twenty build and ten do not, and nine of the ten are one cause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS is measurable now that a target with no runner compiles the member's own tests, so it was measured: 20 of 30 members build for aarch64-macos over openkal and 10 do not. Nine of the ten are reached under `#ifdef __APPLE__` — TargetConditionals.h five times, then sys/cdefs.h, sys/event.h, xlocale.h and pthread_threadid_np — and on this target `__APPLE__` is correct. It is an Apple platform. What it does not say is which C library is underneath, and upstream uses it to mean both because on a real macOS the two coincide. This is the Windows problem again with one difference: there the engine has a lever, because presenting POSIX is realised as a cygwin triple and `_WIN32` goes away. On macOS the realisation adds `-D__unix__` and leaves `__APPLE__` standing, because it is true. The whole identity a source file sees there is `__APPLE__ __MACH__ __MCPP_TARGET_MACOS__ __OPENKAL__ __unix__`, measured, and none of it answers the question. So the target is not pinned: it would add ten red cells whose repair is one design question. The number is recorded so the question is asked with one. --- docs/openkal-compat.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/openkal-compat.md b/docs/openkal-compat.md index 92a5158a..7989034b 100644 --- a/docs/openkal-compat.md +++ b/docs/openkal-compat.md @@ -167,6 +167,48 @@ lower. The comparison becomes a required check for pull requests once the repository variable `OPENKAL_RATCHET` is `on`; it is enabled after the weekly measurement has been stable for two consecutive weeks. +### Why `aarch64-macos` is not a pinned target yet + +`pins.toml` names linux and windows. macOS is measurable — `mcpp test --no-run` +compiles and links each member's own tests for a target this host cannot run — +and it was measured once, on 2026-09-21, against mcpp 2026.9.21.3 and +openkal-llvm-runtime 0.15.0: **20 members build and 10 do not.** + +Nine of the ten are one cause, and it is not ten packaging defects: + +| diagnostic | members | +| --- | --- | +| `TargetConditionals.h` not found | catch2, curl, mimalloc, re2, sqlite3 | +| `sys/cdefs.h`, through Apple's `dnsinfo.h` | c-ares | +| `sys/event.h`, the kqueue reactor | cmp-module | +| `xlocale.h` | fmtlib.fmt | +| `pthread_threadid_np` undeclared | spdlog | +| `library not found for -lm` | brotli | + +Every one of those is reached under `#ifdef __APPLE__`, and on this target +`__APPLE__` is **correct**: it is an Apple platform — Mach-O, arm64, macOS. +What it does not say is which C library is underneath, and upstream code uses +it to mean both because on a real macOS the two coincide. + +**This is the macOS mirror of the Windows problem this document's `c-ares` +entry describes, with one difference: there the engine has a lever.** A C +library presenting POSIX on Windows is realised as `--target=…-pc-cygwin`, +which suppresses `_WIN32`, so `#ifdef _WIN32` stops selecting the Win32 +branch. On macOS the realisation adds `-D__unix__` and leaves `__APPLE__` and +`__MACH__` standing, because they are true. Measured, the whole identity a +source file sees there is + +``` +__APPLE__ __MACH__ __MCPP_TARGET_MACOS__ __OPENKAL__ __unix__ +``` + +and nothing in it answers "which C library". musl defines no identifying macro +by design, so there is no portable question to ask either. + +Pinning the target today would add ten red cells whose repair is one design +question, not ten. The measurement is recorded here so the question is asked +with a number attached. + ## 4. Adapting a package A package that fails in an openkal graph has met one of the layers. The rules From d1e6f1745fcc06d91ab4e4d3f03de7daf19d4ef9 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 09:04:11 +0800 Subject: [PATCH 09/10] the pin moves to the engine the harness now needs `mcpp test --no-run` is what measures a target with no runner, and 2026.9.21.3 is the first release to carry it. `pins.toml` and the workflow's `MCPP_VERSION` move together because the workflow checks that they agree. `runtime` does not move with it. 0.15.0 is the graph the engine change was measured against, and moving both at once would make a red cell ambiguous between the two. aarch64-macos is still not pinned, and that is a measurement rather than an omission: 20 of 30 members build there and 10 do not, nine of the ten reaching for the Apple C environment under `#ifdef __APPLE__` on a target where `__APPLE__` is true and libSystem is not present. The number is in docs/openkal-compat.md so the design question behind it is asked with one attached. --- .github/workflows/openkal-compat.yml | 2 +- tests/openkal/pins.toml | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/openkal-compat.yml b/.github/workflows/openkal-compat.yml index f028bd6f..9f091a0a 100644 --- a/.github/workflows/openkal-compat.yml +++ b/.github/workflows/openkal-compat.yml @@ -37,7 +37,7 @@ env: # run if this drifts from pins.toml. See the comment beside `mcpp` in # pins.toml for why this pin, not just validate.yml's, is gated by the # index floor. - MCPP_VERSION: "2026.9.21.2" + MCPP_VERSION: "2026.9.21.3" # CROSS-VALIDATION BEFORE A RELEASE, NOT AFTER IT. # # Empty in an ordinary run, so this measurement keeps using the RELEASED diff --git a/tests/openkal/pins.toml b/tests/openkal/pins.toml index a18bf85a..342a6176 100644 --- a/tests/openkal/pins.toml +++ b/tests/openkal/pins.toml @@ -18,6 +18,27 @@ toolchain = "llvm@22.1.8" # index requires mcpp >= 2026.9.18.1 but this is mcpp 2026.9.17.3 [E0006]" # before a single line of the member's own source is read. # +# 2026-09-21 (second move): `mcpp` -> 2026.9.21.3, AND THIS ONE MOVES ALONE. +# +# THE HARNESS NOW NEEDS AN ENGINE FLAG. A target with no runner is measured +# with `mcpp test --no-run`, which 2026.9.21.3 is the first release to carry. +# Before it, such a target was measured with `mcpp build`, which builds the +# PACKAGE -- and every member here keeps its sources under `tests/`, so that +# compiled the member's dependencies and none of the member. The reading was +# never wrong in CI, because both targets below are runnable there (linux +# natively, windows through the Wine this workflow installs and checks); it +# was wrong the moment a third target was considered. +# +# `runtime` does not move with it: 0.15.0 is the graph this engine change was +# measured against, and moving both at once would make a red cell ambiguous +# between the two. +# +# aarch64-macos IS STILL NOT PINNED, and that is a measurement rather than an +# omission: 20 of 30 members build there and 10 do not, nine of the ten +# reaching for the Apple C environment under `#ifdef __APPLE__` on a target +# where `__APPLE__` is true and libSystem is not present. See +# docs/openkal-compat.md, "Why aarch64-macos is not a pinned target yet". + # 2026-09-21: `runtime` -> 0.15.0 AND `mcpp` -> 2026.9.21.2, AND THE TWO MOVE # TOGETHER BECAUSE THE MEASUREMENT IS ABOUT WHAT THE PAIR DOES. # @@ -74,7 +95,7 @@ toolchain = "llvm@22.1.8" # openkal-musl 0.16.0 and openkal-llvm-runtime 0.12.0), because a pin that # moves onto an unreachable or divergent asset fails every member at once and # reports it as a compatibility result. -mcpp = "2026.9.21.2" +mcpp = "2026.9.21.3" targets = ["x86_64-linux-gnu", "x86_64-windows-gnu"] From 9151a11d1db36df7da3b6188a01356a3390cdfdc Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 21 Sep 2026 09:50:09 +0800 Subject: [PATCH 10/10] the published reading is `builds`, and mine was `runs` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI measured mimalloc's Windows cell as `builds`: the backend crash is gone and the member compiles and links, and its `alloc` test then exits 1 under the Wine that CI installs while passing under the one on this machine. The recipe comment claimed `runs` on the strength of the local run. The build repair stands — the cell was `fails: error: build failed` — but a repaired build is not a passing test, and both the recipe and docs now say which one this is. The sixty-cell table is CI's, not mine: 56 runs, 1 builds, 3 fails, all three declared. --- docs/openkal-compat.md | 19 +++++++++++++++++++ pkgs/c/compat.mimalloc.lua | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/docs/openkal-compat.md b/docs/openkal-compat.md index 7989034b..2fe7f00f 100644 --- a/docs/openkal-compat.md +++ b/docs/openkal-compat.md @@ -167,6 +167,25 @@ lower. The comparison becomes a required check for pull requests once the repository variable `OPENKAL_RATCHET` is `on`; it is enabled after the weekly measurement has been stable for two consecutive weeks. +### The 2026-09-21 measurement, on mcpp 2026.9.21.3 + +Thirty members, two targets, sixty cells, measured by this repository's own CI: + +| | before | after | +| --- | --- | --- | +| `runs` | 50 | **56** | +| `builds` | 0 | 1 | +| `fails` | 10 | **3, all declared** | + +`compat.py check` against the published baseline: no published label +regressed, and no declaration was contradicted. + +The one `builds` is `mimalloc` on `x86_64-windows-gnu`. Its build was repaired +in this round — `MI_USE_BUILTIN_THREAD_POINTER=0`, see the recipe — and its +`alloc` test then exits 1 under the Wine CI installs while passing under +another. A repaired build is not a passing test, and the label says which one +this is. + ### Why `aarch64-macos` is not a pinned target yet `pins.toml` names linux and windows. macOS is measurable — `mcpp test --no-run` diff --git a/pkgs/c/compat.mimalloc.lua b/pkgs/c/compat.mimalloc.lua index ab0e8913..c77bc5d5 100644 --- a/pkgs/c/compat.mimalloc.lua +++ b/pkgs/c/compat.mimalloc.lua @@ -135,6 +135,16 @@ package = { -- Windows branch, and on a Win32 target the setting is not read at -- all --- `_WIN32` selects `NtCurrentTeb()` three arms earlier --- -- so it changes only the target that has no `_WIN32`. + -- + -- WHAT THIS FIXES AND WHAT IT DOES NOT. The cell goes from + -- `fails: error: build failed` to `builds`: the backend crash is + -- gone and the member compiles and links for this target. Its + -- `alloc` test then passes under one Wine and exits 1 under the + -- one this repository's CI installs, so the published reading is + -- `builds` rather than `runs`. That remainder is a separate + -- question about the TLS path the override falls back to, and it + -- is recorded here rather than folded into this one so the next + -- reader does not take a green build for a green test. cflags = { "-DMI_USE_BUILTIN_THREAD_POINTER=0" }, }, },