mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-03 06:10:28 +00:00
Ninja: Swift: Add dependency edge to swiftmodule file
Swiftmodules act like headers for Swift, but are generated by the compiler while building the module. Unlike headerfiles in a pure C/C++ world, where the compiler generates the appropriate depfile. We don't have We're already adding the swiftmodule as an output from swift-linked targets, but aren't using that on inputs. This dependency edge is most important for static libraries in incremental builds. Suppose we have two static libraries, A, and B, and an executable E. B "links" against A, and E links against B. In a C/C++ environment, the library link dependency edge will run from E to both A and B, but there won't be an edge from B to A. If A is changed, the only way this should affect B is if the public interface changes, in which case, the headers will also change. The dep file contains the header link, so Ninja will rebuild B when appropriate. With Swift in an incremental build, B sees the order-dependency on A, but A already exists. If A is changed in a way that changes the public interface, the swiftmodule will change, but since we don't track it, we don't rebuild B, resulting in the final executable to fail to link.
This commit is contained in:
@@ -1396,6 +1396,23 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
||||
}
|
||||
}
|
||||
|
||||
// Add dependencies on swiftmodule files when using the swift linker
|
||||
if (this->TargetLinkLanguage(config) == "Swift") {
|
||||
if (cmComputeLinkInformation* cli =
|
||||
this->GeneratorTarget->GetLinkInformation(config)) {
|
||||
for (auto const& dependency : cli->GetItems()) {
|
||||
// Both the current target and the linked target must be swift targets
|
||||
// in order for there to be a swiftmodule to depend on
|
||||
if (dependency.Target &&
|
||||
dependency.Target->GetLinkerLanguage(config) == "Swift") {
|
||||
std::string swiftmodule =
|
||||
this->ConvertToNinjaPath(GetSwiftModulePath(dependency.Target));
|
||||
linkBuild.ImplicitDeps.emplace_back(swiftmodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ninja should restat after linking if and only if there are byproducts.
|
||||
vars["RESTAT"] = byproducts.ExplicitOuts.empty() ? "" : "1";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user