Jelajahi Sumber

Merge topic 'fix-21620'

8cb8dd6da5 AutoMoc: Re-run after adding Q_OBJECT macro
fefba42e37 Add a failing test case for #21620
2999c40dd9 Extend QtAutogen/RerunMoc
f623664e87 Do not use try_compile in RerunMocBasic test

Acked-by: Kitware Robot <[email protected]>
Merge-request: !5642
Brad King 5 tahun lalu
induk
melakukan
520df2880b

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

+ 69 - 10
Tests/QtAutogen/RerunMocBasic/CMakeLists.txt

@@ -47,19 +47,38 @@ macro(require_change_not)
 endmacro()
 
 
-# Initial build
+# Configure the test project
 configure_file("${mocBasicSrcDir}/test1a.h.in" "${mocBasicBinDir}/test1.h" COPYONLY)
-try_compile(MOC_RERUN
-  "${mocBasicBinDir}"
-  "${mocBasicSrcDir}"
-  MocBasic
-  CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
-              "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
-              "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+configure_file("${mocBasicSrcDir}/myobject3a.h.in" "${mocBasicBinDir}/myobject3.h" @ONLY)
+if(CMAKE_GENERATOR_INSTANCE)
+    set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}")
+else()
+    set(_D_CMAKE_GENERATOR_INSTANCE "")
+endif()
+execute_process(
+  COMMAND "${CMAKE_COMMAND}" -B "${mocBasicBinDir}" -S "${mocBasicSrcDir}"
+          -G "${CMAKE_GENERATOR}"
+          -A "${CMAKE_GENERATOR_PLATFORM}"
+          -T "${CMAKE_GENERATOR_TOOLSET}"
+          ${_D_CMAKE_GENERATOR_INSTANCE}
+          "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
+          "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
+          "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
+  RESULT_VARIABLE exit_code
   OUTPUT_VARIABLE output
 )
-if (NOT MOC_RERUN)
-  message(FATAL_ERROR "Initial build of mocBasic failed. Output: ${output}")
+if(NOT exit_code EQUAL 0)
+  message(FATAL_ERROR "Initial configuration of mocBasic failed. Output: ${output}")
+endif()
+
+# Initial build
+execute_process(
+    COMMAND "${CMAKE_COMMAND}" --build "${mocBasicBinDir}"
+    RESULT_VARIABLE exit_code
+    OUTPUT_VARIABLE output
+)
+if(NOT exit_code EQUAL 0)
+    message(FATAL_ERROR "Initial build of mocBasic failed. Output: ${output}")
 endif()
 
 # Get name of the output binary
@@ -100,3 +119,43 @@ message(STATUS "Changing nothing for no MOC re-run")
 rebuild(3)
 acquire_timestamp(After)
 require_change_not()
+
+
+# - Ensure that the timestamp will change
+# - Remove Q_OBJECT from header
+# - Rebuild
+acquire_timestamp(Before)
+sleep()
+message(STATUS "Remove Q_OBJECT from header file for a MOC re-run")
+configure_file("${mocBasicSrcDir}/test1c.h.in" "${mocBasicBinDir}/test1.h" COPYONLY)
+sleep()
+rebuild(4)
+acquire_timestamp(After)
+require_change()
+
+
+# - Ensure that the timestamp will change
+# - Add Q_OBJECT to header again
+# - Rebuild
+acquire_timestamp(Before)
+sleep()
+message(STATUS "Add Q_OBJECT to test1.h for a MOC re-run")
+configure_file("${mocBasicSrcDir}/test1a.h.in" "${mocBasicBinDir}/test1.h" COPYONLY)
+sleep()
+rebuild(5)
+acquire_timestamp(After)
+require_change()
+
+
+# - Ensure that the timestamp will change
+# - Add Q_OBJECT to MyObject3
+# - Rebuild
+acquire_timestamp(Before)
+sleep()
+message(STATUS "Add Q_OBJECT to myobject3.h file for a MOC re-run")
+set(CLASS_CONTENT "Q_OBJECT")
+configure_file("${mocBasicSrcDir}/myobject3a.h.in" "${mocBasicBinDir}/myobject3.h" @ONLY)
+sleep()
+rebuild(6)
+acquire_timestamp(After)
+require_change()

+ 6 - 1
Tests/QtAutogen/RerunMocBasic/MocBasic/CMakeLists.txt

@@ -13,10 +13,15 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
 
 add_executable(mocBasic
   ${CMAKE_CURRENT_BINARY_DIR}/test1.h
+  ${CMAKE_CURRENT_BINARY_DIR}/myobject3.h
   ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+  plainobject.cpp
   res1.qrc
 )
-target_include_directories(mocBasic PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_include_directories(mocBasic PRIVATE
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
 target_link_libraries(mocBasic ${QT_QTCORE_TARGET})
 # Write target name to text file
 add_custom_command(TARGET mocBasic POST_BUILD COMMAND

+ 2 - 0
Tests/QtAutogen/RerunMocBasic/MocBasic/main.cpp.in

@@ -1,4 +1,5 @@
 #include "test1.h"
+#include "plainobject.h"
 
 extern int qInitResources_res1();
 
@@ -16,6 +17,7 @@ int main()
 
   Test1 test1;
   Test2 test2;
+  PlainObject plainObject;
 
   return 0;
 }

+ 13 - 0
Tests/QtAutogen/RerunMocBasic/MocBasic/myobject3a.h.in

@@ -0,0 +1,13 @@
+#ifndef MYOBJECT3_H
+#define MYOBJECT3_H
+
+#include <qobject.h>
+
+class MyObject3 : public QObject
+{
+    @CLASS_CONTENT@
+public:
+    MyObject3() {}
+};
+
+#endif

+ 12 - 0
Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.cpp

@@ -0,0 +1,12 @@
+#include "plainobject.h"
+
+#include "myobject3.h"
+
+PlainObject::PlainObject()
+{
+}
+
+void PlainObject::doSomething()
+{
+  MyObject3 obj3;
+}

+ 12 - 0
Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.h

@@ -0,0 +1,12 @@
+#ifndef PLAINOBJECT_H
+#define PLAINOBJECT_H
+
+// Class that is plain C++, no Qt involved.
+class PlainObject
+{
+public:
+  PlainObject();
+  void doSomething();
+};
+
+#endif

+ 6 - 0
Tests/QtAutogen/RerunMocBasic/MocBasic/test1c.h.in

@@ -0,0 +1,6 @@
+#include <QObject>
+class Test1
+{
+public:
+  void onTst1() {}
+};