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
|
|
@ -39,14 +39,20 @@ export namespace Crafter {
|
|||
fs::path wasiSysroot;
|
||||
// The mingw-w64 install prefix, the directory that holds
|
||||
// x86_64-w64-mingw32/ and lib/gcc/x86_64-w64-mingw32/ (/usr for a
|
||||
// distro package), as an absolute path. Empty means clang's own
|
||||
// discovery, which follows the mingw gcc on PATH. Set by
|
||||
// distro package), absolute and lexically normal. Empty means clang's
|
||||
// own discovery, which follows the mingw gcc on PATH. Set by
|
||||
// CRAFTER_MINGW_DIR, else the host's /usr when running sandboxed and
|
||||
// it has mingw-w64 (the sandbox's own /usr never does). clang never
|
||||
// gets the prefix itself: the mingw target's --sysroot is
|
||||
// MingwSysroot(), a view of it. Keyed into the mingw target's
|
||||
// VariantId and std PCM directory.
|
||||
// it has mingw-w64 (the sandbox's own /usr never does). What the
|
||||
// mingw target passes as --sysroot is MingwSysroot(), not this:
|
||||
// see mingwPrefixIsSystem.
|
||||
fs::path mingwPrefix;
|
||||
// The prefix holds a Linux system as well as mingw-w64: the host's
|
||||
// /usr in the sandbox, or a prefix whose include/ has a C library's
|
||||
// features.h, as /usr has. clang searches a mingw sysroot's include/
|
||||
// and lib/, so such a prefix is shown to it only through a view of
|
||||
// its mingw-w64 parts; any other prefix is the sysroot itself, and
|
||||
// Windows libraries installed into its include/ and lib/ are found.
|
||||
bool mingwPrefixIsSystem = false;
|
||||
// `clang++ -print-target-triple` and the first line of
|
||||
// `clang++ --version`; both empty when clang++ could not be run.
|
||||
std::string hostTriple;
|
||||
|
|
@ -89,18 +95,32 @@ export namespace Crafter {
|
|||
const Toolchain& GetToolchain();
|
||||
// GetToolchain(), or a std::runtime_error carrying its error.
|
||||
const Toolchain& RequireToolchain();
|
||||
// Makes, in the first of `parents` that can hold one, a directory that
|
||||
// shows clang only the mingw-w64 parts of `prefix`: links named
|
||||
// x86_64-w64-mingw32, lib/gcc and lib64/gcc to the same paths under
|
||||
// `prefix`, at <parent>/mingw-sysroot/<hash of prefix>, and returns it.
|
||||
// A view already there is reused; one another process makes at the same
|
||||
// moment is as good as one made here. Throws when no parent can hold
|
||||
// one, with the reason for each.
|
||||
fs::path MakeMingwSysroot(const fs::path& prefix, std::span<const fs::path> parents);
|
||||
// The --sysroot of every compile, link and CMake configure for the mingw
|
||||
// target: a directory in crafter-build's cache holding only links to the
|
||||
// x86_64-w64-mingw32/, lib/gcc/ and lib64/gcc/ of GetToolchain()'s
|
||||
// mingwPrefix, made on the first call of a process. Empty without a
|
||||
// prefix. The prefix cannot be the sysroot: clang takes a mingw sysroot
|
||||
// for a tree that holds mingw-w64 alone and searches its include/ and
|
||||
// lib/ as well, which for /usr (the host's, in the Flatpak) are the
|
||||
// Linux system's own. A Windows build then saw glibc's headers, and
|
||||
// target, settled on the first call of a process: empty without a
|
||||
// mingwPrefix, the prefix itself for one that holds mingw-w64 alone, and
|
||||
// for a system prefix the view MakeMingwSysroot makes in crafter-build's
|
||||
// cache, or in $XDG_RUNTIME_DIR/crafter.build when the cache's
|
||||
// filesystem takes no symbolic links. A system prefix cannot be the
|
||||
// sysroot: clang takes a mingw sysroot for a tree that holds mingw-w64
|
||||
// alone and searches its include/ and lib/ as well, which for /usr are
|
||||
// the Linux system's own. A Windows build then saw glibc's headers, and
|
||||
// libstdc++, finding <sys/single_threaded.h>, had shared_ptr read
|
||||
// __libc_single_threaded, which nothing on Windows defines (issue #43).
|
||||
// Throws when the view cannot be made.
|
||||
const fs::path& MingwSysroot();
|
||||
// `text` with every path into the view MingwSysroot() made written as
|
||||
// the same path into the prefix it shows, so that compiler messages name
|
||||
// a header where the user installed it rather than in a hashed cache
|
||||
// directory; `text` unchanged when no view was made.
|
||||
std::string MingwViewToPrefix(std::string text);
|
||||
// _LIBCPP_VERSION as the <__config> in `includeDir` (an include/c++/v1)
|
||||
// defines it, XXYYZZ; 0 when the file is missing or has no such line.
|
||||
std::int32_t LibcxxVersion(const fs::path& includeDir);
|
||||
|
|
|
|||
Loading…
Reference in a new issue