From fa55751f83dc5d5bd5f80d12c3076ec703262edb Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 27 May 2013 17:58:57 +0200 Subject: [PATCH] QtAutomoc: Get the Qt version through the target link interface In Qt 5.1, Qt5::Core has a INTERFACE_QT_MAJOR_VERSION property of '5', and since CMake 2.8.11, Qt4::QtCore has an INTERFACE_QT_MAJOR_VERSION of '4'. This was introduced in commit 4aa10cd6 (FindQt4: Set the INTERFACE_QT_MAJOR_VERSION for Qt4::QtCore, 2013-03-16), to produce an error if Qt 4 and Qt 5 are erroneously used by the same target. This can also be used however to determine the Qt major version, and therefore the particular moc executable to use during automoc steps. This means that targets in a single buildsystem can use a selection of Qt 4 and Qt 5, and still take advantage of the CMAKE_AUTOMOC feature without conflicting. --- Modules/AutomocInfo.cmake.in | 3 +-- Source/cmQtAutomoc.cxx | 29 ++++++++++++++++++++++++++--- Tests/CMakeLists.txt | 14 ++++++++++++++ Tests/Qt4And5Automoc/CMakeLists.txt | 13 +++++++++++++ Tests/Qt4And5Automoc/main.cpp | 18 ++++++++++++++++++ Tests/Qt4And5Automoc/main_qt4.cpp | 4 ++++ Tests/Qt4And5Automoc/main_qt5.cpp | 4 ++++ 7 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 Tests/Qt4And5Automoc/CMakeLists.txt create mode 100644 Tests/Qt4And5Automoc/main.cpp create mode 100644 Tests/Qt4And5Automoc/main_qt4.cpp create mode 100644 Tests/Qt4And5Automoc/main_qt5.cpp diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in index e5bee864a..9cff735fb 100644 --- a/Modules/AutomocInfo.cmake.in +++ b/Modules/AutomocInfo.cmake.in @@ -9,7 +9,6 @@ set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") -set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) -set(AM_Qt5Core_VERSION_MAJOR "@Qt5Core_VERSION_MAJOR@" ) +set(AM_QT_VERSION_MAJOR "@_target_qt_version@") set(AM_TARGET_NAME @_moc_target_name@) set(AM_RELAXED_MODE "@_moc_relaxed_mode@") diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 9d14fc203..350b46291 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -309,7 +309,27 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str()); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); - if (makefile->GetDefinition("Qt5Core_VERSION_MAJOR")) + const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR"); + if (!qtVersion) + { + qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR"); + } + if (const char *targetQtVersion = + target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", 0)) + { + qtVersion = targetQtVersion; + } + if (qtVersion) + { + makefile->AddDefinition("_target_qt_version", qtVersion); + } + + { + const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE"); + makefile->AddDefinition("_qt_moc_executable", qtMoc); + } + + if (strcmp(qtVersion, "5") == 0) { cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc"); if (!qt5Moc) @@ -322,8 +342,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } else { - const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE"); - makefile->AddDefinition("_qt_moc_executable", qtMoc); + if (strcmp(qtVersion, "4") != 0) + { + cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and " + "Qt 5 ", automocTargetName.c_str()); + } } const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 0b221e885..230f77659 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1044,6 +1044,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets") + + if(Qt5Widgets_FOUND AND NOT Qt5Widgets_VERSION VERSION_LESS 5.1.0) + add_test(Qt4And5Automoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Qt4And5Automoc" + "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc" + ${build_generator_args} + --build-project Qt4And5Automoc + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc") + endif() endif() add_test(ExternalProject ${CMAKE_CTEST_COMMAND} diff --git a/Tests/Qt4And5Automoc/CMakeLists.txt b/Tests/Qt4And5Automoc/CMakeLists.txt new file mode 100644 index 000000000..0cc80fe73 --- /dev/null +++ b/Tests/Qt4And5Automoc/CMakeLists.txt @@ -0,0 +1,13 @@ + +project(Qt4And5Automoc) + +find_package(Qt4 REQUIRED) +find_package(Qt5Core REQUIRED) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_executable(qt4_exe main_qt4.cpp) +target_link_libraries(qt4_exe Qt4::QtCore) +add_executable(qt5_exe main_qt5.cpp) +target_link_libraries(qt5_exe Qt5::Core) diff --git a/Tests/Qt4And5Automoc/main.cpp b/Tests/Qt4And5Automoc/main.cpp new file mode 100644 index 000000000..00fd64153 --- /dev/null +++ b/Tests/Qt4And5Automoc/main.cpp @@ -0,0 +1,18 @@ + +#include + +class SomeObject : public QObject +{ + Q_OBJECT +public: + explicit SomeObject(QObject *parent = 0) + : QObject(parent) + { + + } +}; + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/Tests/Qt4And5Automoc/main_qt4.cpp b/Tests/Qt4And5Automoc/main_qt4.cpp new file mode 100644 index 000000000..a84ce897f --- /dev/null +++ b/Tests/Qt4And5Automoc/main_qt4.cpp @@ -0,0 +1,4 @@ + +#include "main.cpp" + +#include "main_qt4.moc" diff --git a/Tests/Qt4And5Automoc/main_qt5.cpp b/Tests/Qt4And5Automoc/main_qt5.cpp new file mode 100644 index 000000000..287b26137 --- /dev/null +++ b/Tests/Qt4And5Automoc/main_qt5.cpp @@ -0,0 +1,4 @@ + +#include "main.cpp" + +#include "main_qt5.moc"