Skip to content

Commit ae7114e

Browse files
committed
fix: skip --sysroot entirely for macOS std module precompile
CI step 9 proves that clang++ WITHOUT explicit --sysroot precompiles std.cppm correctly on macOS — the clang++.cfg's built-in --sysroot and -isystem flags handle SDK header resolution properly. When mcpp passes an explicit --sysroot (even the identical value), it changes Clang's internal header search order, breaking the transitive inclusion of _ctype.h before ___wctype.h. The macOS SDK's ___wctype.h references _CTYPE_A which is only defined via the default cfg-driven include chain. Fix: detect apple/darwin target and skip --sysroot for std module precompile, letting clang++.cfg handle it. Non-macOS platforms (Linux, Windows) continue to use the probed sysroot as before.
1 parent 078873d commit ae7114e

1 file changed

Lines changed: 14 additions & 15 deletions

File tree

src/toolchain/stdmod.cppm

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,20 @@ std::expected<StdModule, StdModError> ensure_built(
9393
sm.objectPath = sm.cacheDir / "std.o";
9494

9595
std::string sysroot_flag;
96-
bool is_macos_target = tc.targetTriple.find("apple") != std::string::npos
97-
|| tc.targetTriple.find("darwin") != std::string::npos;
98-
if (is_macos_target) {
99-
// macOS: always pass the *active* SDK path (from xcrun) to override
100-
// any stale --sysroot baked into clang++.cfg by xlings at install
101-
// time. The cfg path may point to CommandLineTools SDK while the
102-
// runner has Xcode active, or vice versa. A mismatched SDK causes
103-
// ___wctype.h → _CTYPE_A undeclared errors during std module
104-
// precompilation because the SDK's internal C headers reference
105-
// macros defined in a sibling header that the wrong SDK doesn't
106-
// include transitively.
107-
if (auto sdk = mcpp::platform::macos::sdk_path())
108-
sysroot_flag = std::format(" --sysroot='{}'", sdk->string());
109-
} else if (!tc.sysroot.empty()) {
110-
sysroot_flag = std::format(" --sysroot='{}'", tc.sysroot.string());
96+
if (!tc.sysroot.empty()) {
97+
// macOS (apple/darwin target): do NOT pass --sysroot for std module
98+
// precompilation. xlings LLVM's clang++.cfg already contains a
99+
// --sysroot for the macOS SDK plus -isystem for libc++ headers.
100+
// Passing an explicit --sysroot on the command line (even the same
101+
// value) changes Clang's internal header search order, causing the
102+
// macOS SDK's ___wctype.h to not find _CTYPE_A (defined in a
103+
// sibling C runtime header that's only included transitively via
104+
// the cfg's default search path). The CI "import std" test proves
105+
// that running clang++ WITHOUT an explicit --sysroot works correctly.
106+
bool is_macos = tc.targetTriple.find("apple") != std::string::npos
107+
|| tc.targetTriple.find("darwin") != std::string::npos;
108+
if (!is_macos)
109+
sysroot_flag = std::format(" --sysroot='{}'", tc.sysroot.string());
111110
}
112111

113112
bool std_cached = std::filesystem::exists(sm.bmiPath) && std::filesystem::exists(sm.objectPath);

0 commit comments

Comments
 (0)