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
|
|
@ -147,6 +147,31 @@ int main() {
|
|||
Check(tc.mingwPrefix == "/opt/mingw", "CRAFTER_MINGW_DIR names the mingw prefix");
|
||||
in.env["CRAFTER_MINGW_DIR"] = "mingw";
|
||||
Check(ResolveToolchain(in).mingwPrefix == fs::absolute("mingw"), "a relative CRAFTER_MINGW_DIR is resolved against the working directory once, when the toolchain is");
|
||||
// The prefix names directories, so one directory has one spelling:
|
||||
// otherwise a trailing slash rebuilds every mingw build for nothing.
|
||||
for (const char* spelling : {"/opt/mingw/", "/opt//mingw", "/opt/./mingw", "/opt/x/../mingw"}) {
|
||||
in.env["CRAFTER_MINGW_DIR"] = spelling;
|
||||
Check(ResolveToolchain(in).mingwPrefix == "/opt/mingw", std::format("{} is spelled /opt/mingw (got '{}')", spelling, ResolveToolchain(in).mingwPrefix.string()));
|
||||
}
|
||||
}
|
||||
{
|
||||
// A prefix that holds a Linux system's C library, as /usr does, is
|
||||
// shown to clang through a view; one that holds mingw-w64 alone is
|
||||
// the sysroot itself, Windows libraries in its include/ and lib/
|
||||
// included.
|
||||
const fs::path staged = fs::temp_directory_path() / "crafter-build-toolchain-mingw-prefixes";
|
||||
fs::remove_all(staged);
|
||||
Touch(staged / "system" / "include" / "features.h");
|
||||
Touch(staged / "system" / "x86_64-w64-mingw32" / "include" / "_mingw.h");
|
||||
Touch(staged / "dedicated" / "include" / "SDL2" / "SDL.h");
|
||||
Touch(staged / "dedicated" / "x86_64-w64-mingw32" / "include" / "_mingw.h");
|
||||
ToolchainInputs in;
|
||||
in.env["CRAFTER_MINGW_DIR"] = (staged / "system").string();
|
||||
Check(ResolveToolchain(in).mingwPrefixIsSystem, "a prefix with a C library's features.h holds a Linux system");
|
||||
in.env["CRAFTER_MINGW_DIR"] = (staged / "dedicated").string();
|
||||
Check(!ResolveToolchain(in).mingwPrefixIsSystem, "a prefix of mingw-w64 and Windows libraries does not");
|
||||
Check(!ResolveToolchain({}).mingwPrefixIsSystem, "no prefix, nothing to show");
|
||||
fs::remove_all(staged);
|
||||
}
|
||||
{
|
||||
// Sandboxed, the host's /usr stands in for the missing mingw-w64,
|
||||
|
|
@ -158,6 +183,7 @@ int main() {
|
|||
Check(ResolveToolchain(in).mingwPrefix.empty(), "a host without mingw-w64 gives no mingw prefix");
|
||||
fs::create_directories(host / "usr" / "x86_64-w64-mingw32");
|
||||
Check(ResolveToolchain(in).mingwPrefix == host / "usr", "a host with mingw-w64 gives its /usr as the mingw prefix");
|
||||
Check(ResolveToolchain(in).mingwPrefixIsSystem, "the host's /usr is the host's system, with or without its C library's headers");
|
||||
in.env["CRAFTER_MINGW_DIR"] = "/opt/mingw";
|
||||
Check(ResolveToolchain(in).mingwPrefix == "/opt/mingw", "CRAFTER_MINGW_DIR wins over the host's");
|
||||
fs::remove_all(host);
|
||||
|
|
|
|||
Loading…
Reference in a new issue