|
| 1 | +// ⭐⭐ libc++ 的平台后端按 OS 宏选,而 openkal 的答案按「配置的是哪个 C 库」。 |
| 2 | +// |
| 3 | +// THE OVERLAY, NOT AN EDIT. openkal-musl's `port/` carries every difference |
| 4 | +// from vendored musl in one directory that shadows it on the include path, and |
| 5 | +// this is that arrangement for libc++ — the vendored tree stays byte-identical |
| 6 | +// to upstream, and the whole of the difference is this file. |
| 7 | +// |
| 8 | +// WHAT UPSTREAM DOES, AND WHY IT IS RIGHT EVERYWHERE ELSE |
| 9 | +// |
| 10 | +// `__locale_dir/locale_base_api.h` selects a backend by asking which operating |
| 11 | +// system this is, and on each answer it assumes that system's C library: |
| 12 | +// |
| 13 | +// #if defined(__APPLE__) → support/apple.h |
| 14 | +// #elif defined(__linux__) → support/linux.h |
| 15 | +// … |
| 16 | +// |
| 17 | +// That holds wherever libc++ is normally built, because the OS and its C |
| 18 | +// library travel together. |
| 19 | +// |
| 20 | +// WHY THEY DO NOT TRAVEL TOGETHER HERE |
| 21 | +// |
| 22 | +// openkal's arrangement is that the C library is a PACKAGE — openkal-musl — and |
| 23 | +// the platform beneath it is an implementation of a 48-function interface. A |
| 24 | +// program for Apple's object format built this way has `__APPLE__` defined, |
| 25 | +// because that is a statement about the FORMAT and the ABI, and has musl |
| 26 | +// underneath it. Upstream's first question then gets the right answer to the |
| 27 | +// wrong question: |
| 28 | +// |
| 29 | +// bsd_like.h:203: no member named 'asprintf_l' in the global namespace |
| 30 | +// |
| 31 | +// — Apple's locale extensions, which musl does not have and never claimed to. |
| 32 | +// |
| 33 | +// ⚠️ WHY THIS IS NOT EXPRESSIBLE AS A `__config_site` SWITCH, WHICH WAS TRIED |
| 34 | +// FIRST. `__config_site` is where this package states every other decision |
| 35 | +// (which C library, whether there is a filesystem, whether there is a random |
| 36 | +// device), and it is the right place for anything libc++ offers a knob for. |
| 37 | +// libc++ offers none here: the chain is a fixed `#if defined(__APPLE__)` with |
| 38 | +// no override, and the only related knob — `_LIBCPP_HAS_LOCALIZATION 0` — |
| 39 | +// removes `<locale>` entirely rather than choosing a different backend. |
| 40 | +// Removing a working facility to route around a question of taste is a worse |
| 41 | +// trade than shadowing one header. |
| 42 | +// |
| 43 | +// ⇒ `_LIBCPP_HAS_MUSL_LIBC` comes from this package's own `__config_site`, so |
| 44 | +// it is a CONFIGURED FACT rather than a guess, and it is asked first. The |
| 45 | +// backend it selects is the one a musl build already uses on the other object |
| 46 | +// format — nothing new is written, the existing answer is merely reachable. |
| 47 | +// |
| 48 | +// Measured 2026-08-23: with this in place, libc++'s `std` module precompiles |
| 49 | +// for `arm64-apple-macos14.0` on a Linux host. |
| 50 | +#ifndef OPENKAL_LIBCXX_LOCALE_BASE_API_OVERLAY |
| 51 | +#define OPENKAL_LIBCXX_LOCALE_BASE_API_OVERLAY |
| 52 | + |
| 53 | +#include <__config> |
| 54 | + |
| 55 | +#if _LIBCPP_HAS_LOCALIZATION && _LIBCPP_HAS_MUSL_LIBC && defined(__APPLE__) |
| 56 | +// The one case upstream's chain answers wrongly for this configuration. Every |
| 57 | +// other target — including musl on ELF, where `__linux__` is defined and the |
| 58 | +// chain already reaches the same header — falls through to upstream below. |
| 59 | +# include <__locale_dir/support/linux.h> |
| 60 | +#else |
| 61 | +# include_next <__locale_dir/locale_base_api.h> |
| 62 | +#endif |
| 63 | + |
| 64 | +#endif // OPENKAL_LIBCXX_LOCALE_BASE_API_OVERLAY |
0 commit comments