From d2536579d51e77827b8e55f39123316324314781 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Mon, 19 Nov 2012 21:47:20 +0100 Subject: [PATCH] Automoc: fix regression #13667, broken build in phonon On some systems, ${QT_INCLUDE_DIR} is reported by gcc as a builtin include search dir. Some projects use this information to extend CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES. In cmake 2.8.10 now the targets are queried for the include directories they use. When they return the result, the include dirs contained in CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES have been removed. In cmake 2.8.9 and below the INCLUDE_DIRECTORIES directory property was queried, where this had not been stripped. So, in those projects which modify the implicit include dirs variable, on systems where ${QT_INCLUDE_DIR} is reported by gcc, this directory, e.g. /usr/lib/include/qt/, was not given anymore to moc. This made moc not find required headers, so the build broke. Simply giving the full CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES to moc is no solution either, since moc can't handle some of the headers it finds then (https://bugreports.qt-project.org/browse/QTBUG-28045). So now cmake checks CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES, and if this contains ${QT_INCLUDE_DIR}, and the target reports that it uses ${QT_QTCORE_INCLUDE_DIR} but not ${QT_INCLUDE_DIR}, ${QT_INCLUDE_DIR} is added to the include dirs given to moc. Alex --- Source/cmQtAutomoc.cxx | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 942c7aba2..25614b862 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -195,6 +195,34 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } } + + const char* qtIncDir = 0; + const char* qtCoreIncDir = 0; + + // check whether ${QT_INCLUDE_DIR} is part of the implicit include dirs, + // see http://public.kitware.com/Bug/view.php?id=13667 + bool qtIncludeDirMayHaveBeenRemoved = false; + if (makefile->IsSet("QT_INCLUDE_DIR")) + { + qtIncDir = makefile->GetDefinition("QT_INCLUDE_DIR"); + std::string s = + makefile->GetSafeDefinition("CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES"); + std::vector implIncDirs; + cmSystemTools::ExpandListArgument(s, implIncDirs); + if (std::find(implIncDirs.begin(), implIncDirs.end(),std::string(qtIncDir)) + != implIncDirs.end()) + { + qtIncludeDirMayHaveBeenRemoved = true; + if (makefile->IsSet("QT_QTCORE_INCLUDE_DIR")) + { + qtCoreIncDir = makefile->GetDefinition("QT_QTCORE_INCLUDE_DIR"); + } + } + } + + bool haveQtCoreIncDir = false; + bool haveQtIncDir = false; + std::vector includeDirs; cmGeneratorTarget gtgt(target); localGen->GetIncludeDirectories(includeDirs, >gt, "CXX"); @@ -207,6 +235,37 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) _moc_incs += sep; sep = ";"; _moc_incs += *incDirIt; + + if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir) // #13667 + { + if (*incDirIt == qtIncDir) + { + haveQtIncDir = true; + qtIncludeDirMayHaveBeenRemoved = false; // it's here, i.e. not removed + } + if (*incDirIt == qtCoreIncDir) + { + haveQtCoreIncDir = true; + } + } + } + + // Some projects (kdelibs, phonon) query the compiler for its default + // include search dirs, and add those to + // CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES. + // These may include e.g./usr/lib/qt/include . This is typically also part + // of ${QT_INCLUDES}. If this directory is then contained in the implicit + // include dirs, it is removed from the include dirs returned from the + // target above. So we add ${QT_INCLUDE_DIR} manually for moc if we detected + // that ${QT_QTCORE_INCLUDE_DIR} is among the include dirs (there shouldn't + // be a way to use Qt4 without using ${QT_QTCORE_INCLUDE_DIR} I think. + // See #13646 and #13667. + if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir + && (haveQtCoreIncDir == true) && (haveQtIncDir == false)) + { + _moc_incs += sep; + sep = ";"; + _moc_incs += qtIncDir; } const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");