fix: rebuild and relink on what changed, submodules at their revisions, and mingw found where it is
Some checks failed
Flatpak / flatpak (push) Failing after 1m12s
Some checks failed
Flatpak / flatpak (push) Failing after 1m12s
- Shaders record the files glslang opened (a depfile) and their settings
(source path, stage, entry point, defines, include directories) in the
build directory, and rebuild when an included file or a setting changes,
not only the shader's own source.
- An executable relinks when its link command changed, not only when an
object is newer: a link flag in project.cpp, or a dependency's library
that moved (an ExternalDependency built into a new cache directory). The
command is recorded beside the objects; its flags come from ordered sets,
so the order the dependency threads finish in can't change it.
- An external's newest artifact counts its libDirs and versioned .so names.
- Submodules are checked out at the revisions the fetched commit records,
from the URLs its .gitmodules gives, after every clone, switch, checkout
and pull, so a pinned commit builds against its own submodules, and one
moved by hand is put back; with no .gitmodules, git isn't asked.
- Each external clone's fetch and build hold a file lock: parallel builds
pulled into one clone at once ("cannot lock ref").
- mingw:
- -stdlib=libstdc++ always;
- the std module's source is found through libstdc++.modules.json in the
mingw toolchain's own library directories (the generic lib/ holds the
host's Linux one), asking the compiler once a run;
- a toolchain that isn't there is a build error saying where it looked,
not std::terminate;
- CRAFTER_MINGW_DIR names the prefix, the directory holding
x86_64-w64-mingw32/ and lib/gcc/;
- inside the Flatpak the host's /usr mingw is used.
- RunScript's exit-status check reads as the one range it is.
- Tests: ConcurrentExternalFetch, ExternalArtifactTime, GitSubmodules,
LinkFlagsChange, MingwMissing, ShaderIncludeChange; ShaderCompile and
ToolchainResolve extended.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
959c65dbb2
commit
653dd0bb9b
26 changed files with 1075 additions and 109 deletions
|
|
@ -27,7 +27,7 @@ int main() {
|
|||
Shader shader(fs::path(src), "main", ShaderType::Fragment);
|
||||
|
||||
std::array<fs::path, 0> includeDirs = {};
|
||||
std::string err = shader.Compile(outDir, includeDirs);
|
||||
std::string err = shader.Compile(outDir, outDir, includeDirs);
|
||||
if (!err.empty()) {
|
||||
std::println(std::cerr, "shader compile failed: {}", err);
|
||||
return 1;
|
||||
|
|
@ -51,10 +51,27 @@ int main() {
|
|||
}
|
||||
|
||||
// Compiling again should be a no-op since the source isn't newer.
|
||||
if (!shader.Check(outDir)) {
|
||||
if (!shader.Check(outDir, outDir, includeDirs)) {
|
||||
std::println(std::cerr, "Shader::Check returned false on an up-to-date spv");
|
||||
return 1;
|
||||
}
|
||||
// Searched elsewhere, an #include could find another file: stale.
|
||||
const std::array<fs::path, 1> elsewhere = { outDir / "elsewhere" };
|
||||
if (shader.Check(outDir, outDir, elsewhere)) {
|
||||
std::println(std::cerr, "Shader::Check called an spv up to date for other include directories");
|
||||
return 1;
|
||||
}
|
||||
// So could a source of the same name moved to another directory, which
|
||||
// its #includes are searched from first.
|
||||
const fs::path movedDir = outDir / "moved";
|
||||
fs::create_directories(movedDir);
|
||||
fs::copy_file(src, movedDir / src.filename());
|
||||
fs::last_write_time(movedDir / src.filename(), fs::last_write_time(src));
|
||||
Shader moved(movedDir / src.filename(), "main", ShaderType::Fragment);
|
||||
if (moved.Check(outDir, outDir, includeDirs)) {
|
||||
std::println(std::cerr, "Shader::Check called an spv up to date for a source of the same name elsewhere");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// One source registered twice: the second entry carries defines and a
|
||||
// variant name. It must land in its own file instead of overwriting the
|
||||
|
|
@ -77,16 +94,16 @@ int main() {
|
|||
// exists, the variant is still due. A Check() that ignored the
|
||||
// variant would call it up to date here, and Build() would then
|
||||
// never compile a variant added to an already built project.
|
||||
if (each == &red && red.Check(outDir)) {
|
||||
if (each == &red && red.Check(outDir, outDir, includeDirs)) {
|
||||
std::println(std::cerr, "Shader::Check called the variant up to date before it was ever compiled");
|
||||
return 1;
|
||||
}
|
||||
std::string variantErr = each->Compile(outDir, includeDirs);
|
||||
std::string variantErr = each->Compile(outDir, outDir, includeDirs);
|
||||
if (!variantErr.empty()) {
|
||||
std::println(std::cerr, "variant shader compile failed: {}", variantErr);
|
||||
return 1;
|
||||
}
|
||||
if (!each->Check(outDir)) {
|
||||
if (!each->Check(outDir, outDir, includeDirs)) {
|
||||
std::println(std::cerr, "Shader::Check returned false for {}", each->OutputName().string());
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -99,14 +116,14 @@ int main() {
|
|||
Shader malformed(fs::path(variantSrc), "main", ShaderType::Fragment);
|
||||
malformed.defines = {bad};
|
||||
malformed.variant = "malformed";
|
||||
if (!malformed.Compile(outDir, includeDirs).contains("invalid shader define")) {
|
||||
if (!malformed.Compile(outDir, outDir, includeDirs).contains("invalid shader define")) {
|
||||
std::println(std::cerr, "a malformed define was not rejected by name");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Shader nested(fs::path(variantSrc), "main", ShaderType::Fragment);
|
||||
nested.variant = "sub/red";
|
||||
if (!nested.Compile(outDir, includeDirs).contains("path separator")) {
|
||||
if (!nested.Compile(outDir, outDir, includeDirs).contains("path separator")) {
|
||||
std::println(std::cerr, "a variant with a path separator was not rejected by name");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue