瀏覽代碼

AutoMoc: Re-run after adding Q_OBJECT macro

Consider a Qt project with a header file that does not contain the
Q_OBJECT macro. Adding the Q_OBJECT macro is supposed to trigger a run
of moc.

When using Qt >= 5.15 and the Ninja generator, re-running AutoMoc is
controlled by the contents of a Ninja depfile.  In the situation above,
AutoMoc would not re-run, because the header/source files without
Q_OBJECT macro are not contained in the depfile.

Add the relevant source files of the project to the merged depfile to
re-run AutoMoc whenever a source file changes.

Fixes: #21620
Joerg Bornemann 4 年之前
父節點
當前提交
8cb8dd6da5
共有 1 個文件被更改,包括 25 次插入1 次删除
  1. 25 1
      Source/cmQtAutoMocUic.cxx

+ 25 - 1
Source/cmQtAutoMocUic.cxx

@@ -522,6 +522,7 @@ public:
   class JobDepFilesMergeT : public JobFenceT
   {
   private:
+    std::vector<std::string> initialDependencies() const;
     void Process() override;
   };
 
@@ -2198,6 +2199,29 @@ std::string escapeDependencyPath(cm::string_view path)
   return escapedPath;
 }
 
+/*
+ * Return the initial dependencies of the merged depfile.
+ * Those are dependencies from the project files, not from moc runs.
+ */
+std::vector<std::string>
+cmQtAutoMocUicT::JobDepFilesMergeT::initialDependencies() const
+{
+  std::vector<std::string> dependencies;
+  dependencies.reserve(this->BaseConst().ListFiles.size() +
+                       this->BaseEval().Headers.size() +
+                       this->BaseEval().Sources.size());
+  cm::append(dependencies, this->BaseConst().ListFiles);
+  auto append_file_path =
+    [&dependencies](const SourceFileMapT::value_type& p) {
+      dependencies.push_back(p.first);
+    };
+  std::for_each(this->BaseEval().Headers.begin(),
+                this->BaseEval().Headers.end(), append_file_path);
+  std::for_each(this->BaseEval().Sources.begin(),
+                this->BaseEval().Sources.end(), append_file_path);
+  return dependencies;
+}
+
 void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
 {
   if (this->Log().Verbose()) {
@@ -2215,7 +2239,7 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
     return dependenciesFromDepFile(f.c_str());
   };
 
-  std::vector<std::string> dependencies = this->BaseConst().ListFiles;
+  std::vector<std::string> dependencies = this->initialDependencies();
   ParseCacheT& parseCache = this->BaseEval().ParseCache;
   auto processMappingEntry = [&](const MappingMapT::value_type& m) {
     auto cacheEntry = parseCache.GetOrInsert(m.first);