fix: re-resolve module imports before checking staleness
Adding a data member to a class in a module interface did not rebuild every object compiled against the old layout. The build succeeded with no error or warning and the resulting binary mixed both layouts, surfacing later as a SIGSEGV in a destructor. GetInterfacesAndImplementations scans a TU's `import X;` statements when the source is declared. An import that matches neither a module in the Configuration nor one reachable through `dependencies` was dropped on the floor, leaving that TU with no staleness edge to the interface it consumes. `dependencies` is frequently assigned *after* the scan — AddTest does exactly that, resolving tests/<name>/main.cpp and only then returning a builder whose .Dependencies() supplies the library — so consumers of a dependency's modules routinely carried no edge at all. A layout change then rebuilt the library, relinked the consumer, and kept the consumer's object as it was. Unresolved names are now remembered on the partition/implementation as pendingImports, and Configuration::ResolvePendingImports retries them against the dependency DAG as it stands. Build() calls it immediately before comparing mtimes, which closes the window for every caller rather than only the ones that declare in the right order; TestBuilder::Dependencies also calls it so the Configuration is coherent for anyone inspecting it before the build. Resolves #27
This commit is contained in:
parent
8892154b28
commit
13697cd026
11 changed files with 341 additions and 7 deletions
|
|
@ -14,6 +14,13 @@ namespace Crafter {
|
|||
std::vector<Module*> moduleDependencies;
|
||||
std::vector<ModulePartition*> partitionDependencies;
|
||||
std::vector<std::pair<Module*, fs::path>> externalModuleDependencies;
|
||||
// Names from `import X;` that matched neither a module in this
|
||||
// Configuration nor one reachable through its dependencies at the time
|
||||
// the source was scanned. Retried by ResolvePendingImports (see
|
||||
// Crafter.Build:Clang) so a dependency wired up after
|
||||
// GetInterfacesAndImplementations still produces a staleness edge.
|
||||
// Names that never resolve (`std`, module-mapped externals) stay here.
|
||||
std::vector<std::string> pendingImports;
|
||||
std::atomic<bool> compiled;
|
||||
bool needsRecompiling;
|
||||
bool checked = false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue