From 56b44f616aaf96b384ca08419c36b87dd1ba3a23 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sat, 31 Oct 2026 22:59:22 +0100 Subject: [PATCH] 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 /external/-/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 --- implementations/Crafter.Build-External.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/implementations/Crafter.Build-External.cpp b/implementations/Crafter.Build-External.cpp index 4a9fbe2..d209a00 100644 --- a/implementations/Crafter.Build-External.cpp +++ b/implementations/Crafter.Build-External.cpp @@ -179,6 +179,19 @@ std::string ConfigureCMake(const fs::path& cloneDir, const fs::path& cmakeBuildD 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); std::string cmd = std::format("cmake -S {} -B {}{}", ShellQuote(fs::absolute(cloneDir).string()), ShellQuote(fs::absolute(cmakeBuildDir).string()), injected);