fix(external): start a CMake build over when its configure inputs change

ConfigureCMake records the flags it injects (compiler, libc++, and for
the mingw target CMAKE_SYSROOT) and reconfigures when they differ, but
it did so in place. CMake then keeps what the old flags compiled: the
Makefiles generator writes --sysroot into build.make, which make does
not compare, so nothing was recompiled, and the check results the old
configure cached stay too. A mingw external built by a release that gave
clang the host's /usr as the sysroot kept its objects reading
__libc_single_threaded after the fix for #43, and only deleting
<cache>/external/<name>-<hash>/build by hand got rid of them.

A build directory with a CMakeCache.txt whose recorded inputs differ is
now removed before the configure. It keeps its name, since projects
point include directories at headers generated in it. The two
crafter-builds the Flatpak's branches are, sharing one cache, rebuild
such an external from nothing each time they take turns, where they
used to reuse each other's objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-31 22:59:22 +01:00
commit 56b44f616a
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB

View file

@ -179,6 +179,19 @@ std::string ConfigureCMake(const fs::path& cloneDir, const fs::path& cmakeBuildD
if (!needsConfigure) return ""; if (!needsConfigure) return "";
// A build directory configured with other inputs starts over instead of
// being reconfigured. CMake reconfigures in place without recompiling
// what an old compiler or --sysroot compiled (the Makefiles generator
// writes --sysroot into build.make, which make does not compare) and
// keeps the check results the old configure cached. A mingw external
// built against the host's /usr as the sysroot (issue #43) kept its
// objects reading __libc_single_threaded after the fix that way. The
// directory keeps its name, which projects point generated headers at.
if (fs::exists(cmakeBuildDir / "CMakeCache.txt")) {
std::error_code ec;
fs::remove_all(cmakeBuildDir, ec);
if (ec) return std::format("cannot clear {} for a fresh configure: {}", cmakeBuildDir.string(), ec.message());
}
if (!fs::exists(cmakeBuildDir)) fs::create_directories(cmakeBuildDir); if (!fs::exists(cmakeBuildDir)) fs::create_directories(cmakeBuildDir);
std::string cmd = std::format("cmake -S {} -B {}{}", ShellQuote(fs::absolute(cloneDir).string()), ShellQuote(fs::absolute(cmakeBuildDir).string()), injected); std::string cmd = std::format("cmake -S {} -B {}{}", ShellQuote(fs::absolute(cloneDir).string()), ShellQuote(fs::absolute(cmakeBuildDir).string()), injected);