QtAutogen: Use Qt 4 IMPORTED targets to find executable locations.

Avoid using the moc from Qt 5 with Qt 4 based targets. Moc generates
a version check to ensure that such generated code does not compile.

The Qt4And5Automoc unit test should have been testing this, but it
was not because the test was broken. In that unit test, moc was run
on trivial files which have no significant content, and in particular
no Q_OBJECT macro.  Therefore moc was generating empty files which
do not even contain the version check.  Fix this by generating files
for input to moc at cmake time.
This commit is contained in:
Stephen Kelly 2014-01-24 13:02:16 +01:00
parent e96683b048
commit 321e348e13
5 changed files with 52 additions and 35 deletions

View File

@ -549,9 +549,6 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
}
}
const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE");
makefile->AddDefinition("_qt_moc_executable", qtMoc);
const char *qtVersion = makefile->GetDefinition("_target_qt_version");
if (strcmp(qtVersion, "5") == 0)
{
@ -564,15 +561,23 @@ void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget const* target,
}
makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(0));
}
else
else if (strcmp(qtVersion, "4") == 0)
{
if (strcmp(qtVersion, "4") != 0)
cmTarget *qt4Moc = makefile->FindTargetToUse("Qt4::moc");
if (!qt4Moc)
{
cmSystemTools::Error("Qt4::moc target not found ",
autogenTargetName.c_str());
return;
}
makefile->AddDefinition("_qt_moc_executable", qt4Moc->GetLocation(0));
}
else
{
cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
"Qt 5 ", autogenTargetName.c_str());
}
}
}
void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts,
const std::vector<std::string> &fileOpts,
@ -641,9 +646,6 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
{
cmMakefile *makefile = target->GetMakefile();
const char *qtUic = makefile->GetSafeDefinition("QT_UIC_EXECUTABLE");
makefile->AddDefinition("_qt_uic_executable", qtUic);
std::vector<cmSourceFile*> srcFiles;
target->GetSourceFiles(srcFiles);
@ -747,22 +749,29 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target,
if (!qt5Uic)
{
// Project does not use Qt5Widgets, but has AUTOUIC ON anyway
makefile->RemoveDefinition("_qt_uic_executable");
}
else
{
makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(0));
}
}
else
else if (strcmp(qtVersion, "4") == 0)
{
if (strcmp(qtVersion, "4") != 0)
cmTarget *qt4Uic = makefile->FindTargetToUse("Qt4::uic");
if (!qt4Uic)
{
cmSystemTools::Error("Qt4::uic target not found ",
targetName);
return;
}
makefile->AddDefinition("_qt_uic_executable", qt4Uic->GetLocation(0));
}
else
{
cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
"Qt 5 ", targetName);
}
}
}
void cmQtAutoGenerators::MergeRccOptions(std::vector<std::string> &opts,
const std::vector<std::string> &fileOpts,
@ -927,9 +936,6 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
makefile->AddDefinition("_qt_rcc_options_options",
cmLocalGenerator::EscapeForCMake(rccFileOptions.c_str()).c_str());
const char *qtRcc = makefile->GetSafeDefinition("QT_RCC_EXECUTABLE");
makefile->AddDefinition("_qt_rcc_executable", qtRcc);
const char* targetName = target->GetName();
if (strcmp(qtVersion, "5") == 0)
{
@ -942,15 +948,23 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
}
makefile->AddDefinition("_qt_rcc_executable", qt5Rcc->GetLocation(0));
}
else
else if (strcmp(qtVersion, "4") == 0)
{
if (strcmp(qtVersion, "4") != 0)
cmTarget *qt4Rcc = makefile->FindTargetToUse("Qt4::rcc");
if (!qt4Rcc)
{
cmSystemTools::Error("Qt4::rcc target not found ",
targetName);
return;
}
makefile->AddDefinition("_qt_rcc_executable", qt4Rcc->GetLocation(0));
}
else
{
cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
"Qt 5 ", targetName);
}
}
}
bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config)
{

View File

@ -1,3 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
project(Qt4And5Automoc)
@ -7,7 +8,17 @@ find_package(Qt5Core REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(qt4_exe main_qt4.cpp)
macro(generate_main_file VERSION)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp" COPYONLY)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/main_qt${VERSION}.cpp"
"#include \"main_qt${VERSION}.moc\"\n"
)
endmacro()
generate_main_file(4)
generate_main_file(5)
add_executable(qt4_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt4.cpp")
target_link_libraries(qt4_exe Qt4::QtCore)
add_executable(qt5_exe main_qt5.cpp)
add_executable(qt5_exe "${CMAKE_CURRENT_BINARY_DIR}/main_qt5.cpp")
target_link_libraries(qt5_exe Qt5::Core)

View File

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

View File

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