Browse Source

Qt4: Fix moc command dependencies for incremental build.

Since commit v2.8.12~327^2 (Qt4Macros: Allow specifying a TARGET
in invokations of macros., 2013-02-26), a parameters file is
populated with moc arguments at generate-time.

When the compile definitions or include directories change, the
parameters file is updated but moc is not re-run in response.

Fix that by making the moc invocation depend on the parameters file.

Reported-At: https://bugreports.qt-project.org/browse/QTBUG-36970
Stephen Kelly 11 years ago
parent
commit
734df96f5a

+ 1 - 1
Modules/Qt4Macros.cmake

@@ -141,7 +141,7 @@ macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target)
   set(_moc_extra_parameters_file @${_moc_parameters_file})
   add_custom_command(OUTPUT ${outfile}
                       COMMAND Qt4::moc ${_moc_extra_parameters_file}
-                      DEPENDS ${infile}
+                      DEPENDS ${infile} ${_moc_parameters_file}
                       ${_moc_working_dir}
                       VERBATIM)
 endmacro ()

+ 27 - 0
Tests/Qt4Targets/CMakeLists.txt

@@ -36,3 +36,30 @@ add_executable(Qt4WrapMacroTest WIN32 main_wrap_test.cpp ${moc_file})
 set_property(TARGET Qt4WrapMacroTest PROPERTY AUTOMOC OFF)
 target_include_directories(Qt4WrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface")
 target_link_libraries(Qt4WrapMacroTest Qt4::QtGui)
+
+set(timeformat "%Y%j%H%M%S")
+try_compile(RESULT
+  "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild"
+  "${CMAKE_CURRENT_SOURCE_DIR}/IncrementalMoc"
+  IncrementalMoc
+  CMAKE_FLAGS -DADD_DEF=0 "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
+file(TIMESTAMP "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild/moc_foo.cpp" tsvar_before "${timeformat}")
+if (NOT tsvar_before)
+  message(SEND_ERROR "Unable to read timestamp from moc file from first build!")
+endif()
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 2) # Ensure that the timestamp will change.
+
+try_compile(RESULT
+  "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild"
+  "${CMAKE_CURRENT_SOURCE_DIR}/IncrementalMoc"
+  IncrementalMoc
+  CMAKE_FLAGS -DADD_DEF=1 "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
+file(TIMESTAMP "${CMAKE_CURRENT_BINARY_DIR}/IncrementalMocBuild/moc_foo.cpp" tsvar_after "${timeformat}")
+if (NOT tsvar_after)
+  message(SEND_ERROR "Unable to read timestamp from moc file from second build!")
+endif()
+
+if (NOT tsvar_after GREATER tsvar_before)
+  message(SEND_ERROR "Rebuild did not re-create moc file. Before: ${tsvar_before}. After: ${tsvar_after}")
+endif()

+ 13 - 0
Tests/Qt4Targets/IncrementalMoc/CMakeLists.txt

@@ -0,0 +1,13 @@
+
+cmake_minimum_required(VERSION 2.8.12)
+project(IncrementalMoc)
+
+find_package(Qt4 REQUIRED)
+
+qt4_generate_moc(foo.h moc_foo.cpp)
+
+add_library(testlib foo.cpp moc_foo.cpp)
+target_link_libraries(testlib Qt4::QtCore)
+if (ADD_DEF)
+  target_compile_definitions(testlib PRIVATE NEW_DEF)
+endif()

+ 8 - 0
Tests/Qt4Targets/IncrementalMoc/foo.cpp

@@ -0,0 +1,8 @@
+
+#include "foo.h"
+
+Foo::Foo()
+  : QObject(0)
+{
+
+}

+ 9 - 0
Tests/Qt4Targets/IncrementalMoc/foo.h

@@ -0,0 +1,9 @@
+
+#include <QObject>
+
+class Foo : QObject
+{
+  Q_OBJECT
+public:
+  Foo();
+};