fix(sysroot): take the std module source from the sysroot's libc++ release
A cross build against a sysroot whose libc++ differs from the toolchain's failed while precompiling the std module, with a page of "no member named 'runtime_format' in namespace 'std'". The module source is a list of using-declarations for what one libc++ release declares, so it only compiles against that release's headers. BuildStdPcm wants the sysroot's own <sysroot>/usr/share/libc++/v1/std.cppm, but Alpine packages the headers without it, and the fallback was the toolchain's copy whatever its release. That held while the compiler came from the same distro as the sysroot; with the Flatpak's libc++ 22.1.8 and Alpine edge on 23.1.2 it no longer does. The release is now read from _LIBCPP_VERSION in the sysroot's and the toolchain's <__config>, and SysrootStdModule picks in this order: the sysroot's own source, the toolchain's when both are the same major release (a release branch only takes fixes), the copy crafter-build ships for that release under share/crafter-build/libc++-modules/<major>. When none fits the build stops with one line naming both releases and the directory the matching source belongs in, before clang is run. If either release cannot be read the toolchain's source is tried as before, since there is nothing to compare. Matching sources live in crafter-build's own share directory rather than the LLVM prefix: they are data this tool ships for sysroots, not part of any one compiler install, and "sources ship" already describes that directory. `--version` prints the toolchain's libc++ release and the releases sources are shipped for, the first thing to look at when such a build fails. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
adc91ed9e2
commit
e15cd3c14d
4 changed files with 112 additions and 14 deletions
|
|
@ -1537,6 +1537,20 @@ static void PrintVersion() {
|
|||
return;
|
||||
}
|
||||
std::println("compiler {} ({})", tc.clangVersion, tc.clangxx.string());
|
||||
if (tc.libcxxVersion != 0) {
|
||||
// A sysroot on another libc++ release builds only when its std
|
||||
// module source is in the sysroot or among these; printed here
|
||||
// because that is the first question when such a build fails.
|
||||
std::vector<std::string> shipped;
|
||||
std::error_code ec;
|
||||
for (const fs::directory_entry& entry : fs::directory_iterator(tc.stdModulesDir, ec)) {
|
||||
if (fs::exists(entry.path() / "std.cppm")) shipped.push_back(entry.path().filename().string());
|
||||
}
|
||||
std::ranges::sort(shipped);
|
||||
std::string also;
|
||||
for (const std::string& release : shipped) also += std::format(", {}", release);
|
||||
std::println("libc++ {}{}", LibcxxVersionString(tc.libcxxVersion), also.empty() ? std::string() : std::format(" (std module sources for sysroots also for{})", also.substr(1)));
|
||||
}
|
||||
std::println("host {}", tc.hostTriple);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue