fix: key the std module's directory on everything it is compiled with
StdPcmDir named the directory by target, march and toolchain, then grew a case per target for the rest: the wasm flags, and with the first fix for #43 the mingw prefix. Every other flag BuildStdPcm passes went unkeyed, so configurations that differed only there took turns rebuilding one std PCM in place, under the PCMs built against it: a project with -mtune=generic against project.cpp's -mtune=native on every run, or two sysroots for one target. And the mingw prefix was keyed only when there was one, so a build without a prefix landed in the directory an older release had filled with a CRAFTER_MINGW_DIR=/usr build, and relinked its objects. StdPcmFlags is now the one source of the flags BuildStdPcm compiles with, and StdPcmKey names the directory by target, march and toolchain followed by a hash of those flags and, for the mingw target, of the prefix behind its --sysroot. VariantId hashes StdPcmKey in place of the mingw prefix: units do not notice a std module that moved directories, so a build has to move with it. Every std PCM directory and build directory moves once, as after a compiler update; the old ones stay until `clean` and the cache is cleared by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
06b61e84f9
commit
5d25495621
4 changed files with 114 additions and 65 deletions
|
|
@ -790,12 +790,10 @@ std::string Crafter::BuildStdPcm(const Configuration& config, fs::path stdPcm) {
|
|||
const fs::path stdCc = (manifestPath.parent_path() / *source).lexically_normal();
|
||||
if (!fs::exists(stdCc)) return std::format("{}, which {} names as the std module, is missing", stdCc.string(), manifestPath.string());
|
||||
|
||||
// -femulated-tls keeps PCM TLS access matching libstdc++'s emutls
|
||||
// definitions; mismatch surfaces as undefined std::__once_callable.
|
||||
// The std.cc → std.cppm copy uses a plain filename: held under the
|
||||
// cache lock, no other builder writes this path concurrently.
|
||||
fs::path stdCppm = stdPcm.parent_path() / "std.cppm";
|
||||
std::string command = std::format("{} --target={} -march={} -mtune={} -femulated-tls -O3 -std=c++26 -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile {} -o {}", GetBaseCommand(config), config.target, config.march, config.mtune, stdCppm.string(), stdPcm.string());
|
||||
std::string command = std::format("{}{} --precompile {} -o {}", GetBaseCommand(config), StdPcmFlags(config), stdCppm.string(), stdPcm.string());
|
||||
std::string stamp = HashStamp(command + '\0' + FileBytes(stdCc));
|
||||
if (fs::exists(stdPcm) && ReadStamp(StampPath(stdPcm)) == stamp) return "";
|
||||
std::error_code copyEc;
|
||||
|
|
@ -825,27 +823,11 @@ std::string Crafter::BuildStdPcm(const Configuration& config, fs::path stdPcm) {
|
|||
if (!source.error.empty()) return source.error;
|
||||
stdCppm = source.stdCppm.string();
|
||||
}
|
||||
std::string sysrootFlag = config.sysroot.empty()
|
||||
? std::string()
|
||||
: std::format(" --sysroot={}", config.sysroot);
|
||||
// wasm32 rejects -march, and the std module has to be compiled the way
|
||||
// the units importing it are, a variant pass's flags (e.g.
|
||||
// -mrelaxed-simd) included, or the BMI is not feature-compatible.
|
||||
std::string archFlags = isWasm
|
||||
? WasmCompileFlags(config)
|
||||
: std::format(" -march={} -mtune={}", config.march, config.mtune);
|
||||
// non-wasm cross builds: the driver ranks the host toolchain's own
|
||||
// libc++ headers (<install>/../include/c++/v1) above --sysroot, so
|
||||
// the PCM would mix host libc++ with the foreign libc — force the
|
||||
// sysroot's copy.
|
||||
if (!isWasm && !config.sysroot.empty()) {
|
||||
archFlags += std::format(" -nostdinc++ -isystem {}/usr/include/c++/v1", config.sysroot);
|
||||
}
|
||||
// Keyed on the command and the module source's bytes, never on
|
||||
// mtimes: an installed std.cppm can be dated at the epoch (OSTree),
|
||||
// and a libc++ update under the same clang changes the bytes but
|
||||
// not the path.
|
||||
std::string command = std::format("{} --target={} -std=c++26{}{} -O3 -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile {} -o {}", GetBaseCommand(config), config.target, sysrootFlag, archFlags, stdCppm, stdPcm.string());
|
||||
std::string command = std::format("{}{} --precompile {} -o {}", GetBaseCommand(config), StdPcmFlags(config), stdCppm, stdPcm.string());
|
||||
std::string stamp = HashStamp(command + '\0' + FileBytes(stdCppm));
|
||||
if (fs::exists(stdPcm) && ReadStamp(StampPath(stdPcm)) == stamp) return "";
|
||||
std::string result = RunBuildCommand(command);
|
||||
|
|
|
|||
Loading…
Reference in a new issue