1
0
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:
Alexandru Croitor
2020-07-31 17:50:37 +02:00
parent 103d6faed9
commit a79056bb02
2 changed files with 47 additions and 2 deletions

View File

@@ -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);

View File

@@ -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> {