fix(mingw): view only a prefix that holds a Linux system
The first fix showed clang every mingw prefix through a view of its mingw-w64 parts. That broke a prefix that holds mingw-w64 alone, where Windows libraries installed with --prefix land in include/ and lib/: with CRAFTER_MINGW_DIR=/opt/mingw, <SDL2/SDL.h> and -lSDL2 were no longer found. Such a prefix is clang's sysroot whole again. Only a prefix that also holds a Linux system gets the view (Toolchain::mingwPrefixIsSystem): the host's /usr inside the Flatpak, whatever its include/ holds, and a prefix whose include/ has a C library's features.h, which every glibc and musl header includes and mingw-w64 has no use for, as CRAFTER_MINGW_DIR=/usr has. MakeMingwSysroot makes the view in the cache, or in $XDG_RUNTIME_DIR/crafter.build when the cache's filesystem takes no symbolic links (vfat, exFAT, CIFS without unix extensions): the XDG spec promises them there, and nothing else in the cache needs them. Its path is absolute, because CMake runs the compiler from directories of its own and a relative cache did not resolve from there. The prefix is resolved once, absolute and lexically normal, so /opt/mingw/ and /opt/mingw are one prefix and not two builds. clang names a header by the path it found it at, so every diagnostic from a viewed mingw-w64 header named a hashed cache directory. RunBuildCommand now writes paths into the view as paths into the prefix, as BuildStdPcm did for its manifest messages already. Also from the review of PR #44: SysrootCompileFlags builds a mingw command, which can make a view, so it redirects the cache like the other tests; the manifest filter's comment names what it still keeps out; the C path asks MingwSysroot() once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5fdbf2baee
commit
06b61e84f9
8 changed files with 262 additions and 78 deletions
|
|
@ -281,6 +281,9 @@ bool Crafter::MatchAny(std::span<const std::string> globs, std::string_view name
|
|||
std::string Crafter::RunBuildCommand(std::string_view cmd) {
|
||||
Progress::EchoCommand(cmd);
|
||||
CommandResult r = RunCommandChecked(cmd);
|
||||
// A mingw build against a system prefix sees mingw-w64 through a view in
|
||||
// the cache, and clang names every header by the path it found it at.
|
||||
r.output = MingwViewToPrefix(std::move(r.output));
|
||||
|
||||
if (r.exitCode == 0) {
|
||||
// Warnings from a step that succeeded. Show them — until now they were
|
||||
|
|
@ -737,10 +740,13 @@ std::string Crafter::BuildStdPcm(const Configuration& config, fs::path stdPcm) {
|
|||
// library, naming the std module's source relative to itself. It is
|
||||
// looked for in the library directories the compiler searches for
|
||||
// this target, as it would look for libstdc++ itself, but only in
|
||||
// those that belong to the mingw toolchain: the list also has the
|
||||
// generic <prefix>/lib, where the host's own (Linux) libstdc++ keeps
|
||||
// its manifest. A toolchain that isn't there is a build error, not
|
||||
// an exception: Build() runs this with its worker threads started.
|
||||
// those that belong to the mingw toolchain. The list also holds
|
||||
// clang's resource directory, the sysroot's generic lib/, where a
|
||||
// prefix given whole can keep a libstdc++ built for another target,
|
||||
// and, when clang finds no gcc directory, an empty entry that would
|
||||
// name a manifest in the working directory. A toolchain that isn't
|
||||
// there is a build error, not an exception: Build() runs this with
|
||||
// its worker threads started.
|
||||
const Toolchain& tc = GetToolchain();
|
||||
const std::string where = tc.mingwPrefix.empty()
|
||||
? std::string("where clang finds it by the x86_64-w64-mingw32 gcc on PATH")
|
||||
|
|
@ -775,13 +781,10 @@ std::string Crafter::BuildStdPcm(const Configuration& config, fs::path stdPcm) {
|
|||
}
|
||||
}
|
||||
if (manifestPath.empty()) return missing;
|
||||
// Found through the view MingwSysroot() makes of the prefix, and
|
||||
// named from here on by its place in the prefix, which is the
|
||||
// directory the user knows and can go and look at.
|
||||
if (!tc.mingwPrefix.empty()) {
|
||||
const fs::path inPrefix = manifestPath.lexically_relative(MingwSysroot());
|
||||
if (!inPrefix.empty() && *inPrefix.begin() != "..") manifestPath = tc.mingwPrefix / inPrefix;
|
||||
}
|
||||
// Found through the view MingwSysroot() may have made of the prefix,
|
||||
// and named from here on by its place in the prefix, the directory
|
||||
// the user knows and can go and look at.
|
||||
manifestPath = fs::path(MingwViewToPrefix(manifestPath.string()));
|
||||
const std::optional<std::string> source = StdModuleSourcePath(FileBytes(manifestPath));
|
||||
if (!source) return std::format("{} names no std module", manifestPath.string());
|
||||
const fs::path stdCc = (manifestPath.parent_path() / *source).lexically_normal();
|
||||
|
|
|
|||
Loading…
Reference in a new issue