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.
This commit is contained in:
Stephen Kelly 2013-05-27 17:58:57 +02:00
parent f776316721
commit fa55751f83
7 changed files with 80 additions and 5 deletions

View File

@ -9,7 +9,6 @@ set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@") set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@")
set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) set(AM_QT_VERSION_MAJOR "@_target_qt_version@")
set(AM_Qt5Core_VERSION_MAJOR "@Qt5Core_VERSION_MAJOR@" )
set(AM_TARGET_NAME @_moc_target_name@) set(AM_TARGET_NAME @_moc_target_name@)
set(AM_RELAXED_MODE "@_moc_relaxed_mode@") set(AM_RELAXED_MODE "@_moc_relaxed_mode@")

View File

@ -309,7 +309,27 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str()); cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str());
makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); 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"); cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc");
if (!qt5Moc) if (!qt5Moc)
@ -322,8 +342,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
} }
else else
{ {
const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE"); if (strcmp(qtVersion, "4") != 0)
makefile->AddDefinition("_qt_moc_executable", qtMoc); {
cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
"Qt 5 ", automocTargetName.c_str());
}
} }
const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");

View File

@ -1044,6 +1044,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--test-command ${CMAKE_CTEST_COMMAND} -V --test-command ${CMAKE_CTEST_COMMAND} -V
) )
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets") 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() endif()
add_test(ExternalProject ${CMAKE_CTEST_COMMAND} add_test(ExternalProject ${CMAKE_CTEST_COMMAND}

View File

@ -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)

View File

@ -0,0 +1,18 @@
#include <QObject>
class SomeObject : public QObject
{
Q_OBJECT
public:
explicit SomeObject(QObject *parent = 0)
: QObject(parent)
{
}
};
int main(int argc, char **argv)
{
return 0;
}

View File

@ -0,0 +1,4 @@
#include "main.cpp"
#include "main_qt4.moc"

View File

@ -0,0 +1,4 @@
#include "main.cpp"
#include "main_qt5.moc"