From a8d879cf4507f0460dd8386a10c3b4ffe79c3566 Mon Sep 17 00:00:00 2001 From: Duncan Barber <7744-dunquan@users.noreply.gitlab.kitware.com> Date: Sat, 3 Apr 2021 11:53:53 +0100 Subject: Autogen: Add detection of UI file changes to the pre-build VS case This is achieved by adding a rule file which carries the UI files as dependencies but performs no meaningful command. Its output path points to a timestamp file which is instead touched by the pre-build command that runs autogen. The rule file therefore triggers the build if any of the files have been changed more recently than the last autogen run. Fixes: #17959 Fixes: #18741 --- Source/cmQtAutoGenInitializer.cxx | 40 ++++++++++++++++++++++++++++++++++++++- Source/cmQtAutoGenInitializer.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 816d7e5..3adeb1a 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -936,7 +936,9 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!skipUic) { // Check if the .ui file has uic options std::string const uicOpts = sf->GetSafeProperty(kw.AUTOUIC_OPTIONS); - if (!uicOpts.empty()) { + if (uicOpts.empty()) { + this->Uic.UiFilesNoOptions.emplace_back(fullPath); + } else { this->Uic.UiFilesWithOptions.emplace_back(fullPath, cmExpandedList(uicOpts)); } @@ -1181,6 +1183,42 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() this->Makefile); } + if (!this->Uic.UiFilesNoOptions.empty() || + !this->Uic.UiFilesWithOptions.empty()) { + // Add a generated timestamp file + ConfigString timestampFile; + std::string timestampFileGenex; + ConfigFileNamesAndGenex(timestampFile, timestampFileGenex, + cmStrCat(this->Dir.Build, "/autouic"_s), + ".stamp"_s); + this->AddGeneratedSource(timestampFile, this->Uic); + + // Add a step in the pre-build command to touch the timestamp file + commandLines.push_back( + cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", "touch", + timestampFileGenex })); + + // UIC needs to be re-run if any of the known UI files change or the + // executable itself has been updated + auto uicDependencies = this->Uic.UiFilesNoOptions; + for (auto const& uiFile : this->Uic.UiFilesWithOptions) { + uicDependencies.push_back(uiFile.first); + } + AddAutogenExecutableToDependencies(this->Uic, uicDependencies); + + // Add a rule file to cause the target to build if a dependency has + // changed, which will trigger the pre-build command to run autogen + std::string no_main_dependency; + cmCustomCommandLines no_command_lines; + this->LocalGen->AddCustomCommandToOutput( + timestampFileGenex, uicDependencies, no_main_dependency, + no_command_lines, /*comment=*/"", this->Dir.Work.c_str(), + /*cmp0116=*/cmPolicies::NEW, /*replace=*/false, + /*escapeOldStyle=*/false, /*uses_terminal=*/false, + /*command_expand_lists=*/false, /*depfile=*/"", /*job_pool=*/"", + stdPipesUTF8); + } + // Add the pre-build command directly to bypass the OBJECT_LIBRARY // rejection in cmMakefile::AddCustomCommandToTarget because we know // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index d096315..8a6d8f9 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -238,6 +238,7 @@ private: : GenVarsT(GenT::UIC){}; std::set SkipUi; + std::vector UiFilesNoOptions; std::vector UiFilesWithOptions; ConfigStrings> Options; std::vector SearchPaths; -- cgit v0.12