mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 22:37:30 +08:00
AutoGen: Fix over-specified direct dependencies of custom command
The AutoMoc timestamp creating custom command explicitly depended on all dependencies of the origin target (associated to the AutoGen target). When an origin target depended on a shared library 'libfoo.so', if it was re-linked, the AutoMoc custom command would touch its output timestamp file, and thus cause needless rebuilding of sources, despite the shared library not having any influence on the AutoMoc generated files. Introduce a new '<target>_autogen_timestamp_deps' utility target, which will serve as an 'order-only' dependency for the custom command. This will prevent needless rebuilding, because touching 'libfoo.so' will not cause the custom command to be re-executed. The new AutoMoc dependency tree looks like: '_autogen_timestamp_deps (serves as order-only dep)' <- '<target_autogen>/timestamp' file ( + moc deps file) <- '<target>_autogen' target. Fixes: #21020
This commit is contained in:
@@ -1180,11 +1180,54 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
if (useNinjaDepfile) {
|
||||
// Create a custom command that generates a timestamp file and
|
||||
// has a depfile assigned. The depfile is created by JobDepFilesMergeT.
|
||||
//
|
||||
// Also create an additional '_autogen_timestamp_deps' that the custom
|
||||
// command will depend on. It will have no sources or commands to
|
||||
// execute, but it will have dependencies that would originally be
|
||||
// assigned to the pre-Qt 5.15 'autogen' target. These dependencies will
|
||||
// serve as a list of order-only dependencies for the custom command,
|
||||
// without forcing the custom command to re-execute.
|
||||
//
|
||||
// The dependency tree would then look like
|
||||
// '_autogen_timestamp_deps (order-only)' <- '/timestamp' file <-
|
||||
// '_autogen' target.
|
||||
const auto timestampTargetName =
|
||||
cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
|
||||
std::vector<std::string> timestampTargetProvides;
|
||||
cmCustomCommandLines timestampTargetCommandLines;
|
||||
|
||||
// Add additional autogen target dependencies
|
||||
// Add additional autogen target dependencies to
|
||||
// '_autogen_timestamp_deps'.
|
||||
for (const cmTarget* t : this->AutogenTarget.DependTargets) {
|
||||
dependencies.push_back(t->GetName());
|
||||
}
|
||||
|
||||
cmTarget* timestampTarget = this->LocalGen->AddUtilityCommand(
|
||||
timestampTargetName, true, this->Dir.Work.c_str(),
|
||||
/*byproducts=*/timestampTargetProvides,
|
||||
/*depends=*/dependencies, timestampTargetCommandLines, false, nullptr);
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(timestampTarget, this->LocalGen));
|
||||
|
||||
// Set FOLDER property on the timestamp target, so it appears in the
|
||||
// appropriate folder in an IDE or in the file api.
|
||||
if (!this->TargetsFolder.empty()) {
|
||||
timestampTarget->SetProperty("FOLDER", this->TargetsFolder);
|
||||
}
|
||||
|
||||
// Make '/timestamp' file depend on '_autogen_timestamp_deps' and on the
|
||||
// moc and uic executables (whichever are enabled).
|
||||
dependencies.clear();
|
||||
dependencies.push_back(timestampTargetName);
|
||||
|
||||
if (this->Moc.ExecutableTarget != nullptr) {
|
||||
dependencies.push_back(this->Moc.ExecutableTarget->Target->GetName());
|
||||
}
|
||||
if (this->Uic.ExecutableTarget != nullptr) {
|
||||
dependencies.push_back(this->Uic.ExecutableTarget->Target->GetName());
|
||||
}
|
||||
|
||||
// Create the custom command that outputs the timestamp file.
|
||||
const char timestampFileName[] = "timestamp";
|
||||
const std::string outputFile =
|
||||
cmStrCat(this->Dir.Build, "/", timestampFileName);
|
||||
|
@@ -2163,7 +2163,9 @@ std::string escapeDependencyPath(cm::string_view path)
|
||||
void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
|
||||
{
|
||||
if (Log().Verbose()) {
|
||||
Log().Info(GenT::MOC, "Merging MOC dependencies");
|
||||
Log().Info(GenT::MOC,
|
||||
cmStrCat("Merging MOC dependencies into ",
|
||||
MessagePath(BaseConst().DepFile.c_str())));
|
||||
}
|
||||
auto processDepFile =
|
||||
[](const std::string& mocOutputFile) -> std::vector<std::string> {
|
||||
|
Reference in New Issue
Block a user