diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 21a853d0b2..9ea77d4b5e 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -518,6 +518,14 @@ _qt4_find_qmake("${_QT4_QMAKE_NAMES}" QT_QMAKE_EXECUTABLE QTVERSION) if (QT_QMAKE_EXECUTABLE AND QTVERSION) + if (Qt5Core_FOUND) + # Qt5CoreConfig sets QT_MOC_EXECUTABLE as a non-cache variable to the Qt 5 + # path to moc. Unset that variable when Qt 4 and 5 are used together, so + # that when find_program looks for moc, it is not set to the Qt 5 version. + # If FindQt4 has already put the Qt 4 path in the cache, the unset() + # command 'unhides' the (correct) cache variable. + unset(QT_MOC_EXECUTABLE) + endif() if (QT_QMAKE_EXECUTABLE_LAST) string(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED) endif() diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index cab59fe830..7e44c267e8 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1279,8 +1279,8 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) const std::vector& headerExtensions = makefile->GetHeaderExtensions(); - std::vector includedUis; - std::vector skippedUis; + std::map includedUis; + std::map skippedUis; std::vector uicSkipped; cmSystemTools::ExpandListArgument(this->SkipUic, uicSkipped); @@ -1290,7 +1290,8 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) { const bool skipUic = std::find(uicSkipped.begin(), uicSkipped.end(), *it) != uicSkipped.end(); - std::vector& uiFiles = skipUic ? skippedUis : includedUis; + std::map& uiFiles + = skipUic ? skippedUis : includedUis; const std::string &absFilename = *it; if (this->Verbose) { @@ -1350,11 +1351,12 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) { this->GenerateMoc(it->first, it->second); } - for(std::vector::const_iterator it = includedUis.begin(); + for(std::map::const_iterator + it = includedUis.begin(); it != includedUis.end(); ++it) { - this->GenerateUi(*it); + this->GenerateUi(it->first, it->second); } if(!this->RccExecutable.empty()) @@ -1431,7 +1433,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, const std::vector& headerExtensions, std::map& includedMocs, - std::vector &includedUis) + std::map &includedUis) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" @@ -1619,7 +1621,7 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, const std::vector& headerExtensions, std::map& includedMocs, - std::vector& includedUis) + std::map& includedUis) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" @@ -1737,7 +1739,7 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, void cmQtAutoGenerators::ParseForUic(const std::string& absFilename, - std::vector& includedUis) + std::map& includedUis) { if (this->UicExecutable.empty()) { @@ -1754,9 +1756,9 @@ void cmQtAutoGenerators::ParseForUic(const std::string& absFilename, } -void cmQtAutoGenerators::ParseForUic(const std::string&, +void cmQtAutoGenerators::ParseForUic(const std::string& absFilename, const std::string& contentsString, - std::vector& includedUis) + std::map& includedUis) { if (this->UicExecutable.empty()) { @@ -1768,6 +1770,9 @@ void cmQtAutoGenerators::ParseForUic(const std::string&, std::string::size_type matchOffset = 0; + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + matchOffset = 0; if ((strstr(contentsString.c_str(), "ui_") != NULL) && (uiIncludeRegExp.find(contentsString))) @@ -1783,7 +1788,7 @@ void cmQtAutoGenerators::ParseForUic(const std::string&, // finding the correct header, so we need to remove the ui_ part basename = basename.substr(3); - includedUis.push_back(basename); + includedUis[absPath] = basename; matchOffset += uiIncludeRegExp.end(); } while(uiIncludeRegExp.find(contentsString.c_str() + matchOffset)); @@ -1831,7 +1836,7 @@ cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename, void cmQtAutoGenerators::ParseHeaders(const std::set& absHeaders, const std::map& includedMocs, std::map& notIncludedMocs, - std::vector& includedUis) + std::map& includedUis) { for(std::set::const_iterator hIt=absHeaders.begin(); hIt!=absHeaders.end(); @@ -1939,7 +1944,8 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, return false; } -bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName) +bool cmQtAutoGenerators::GenerateUi(const std::string& path, + const std::string& uiFileName) { if (!cmsys::SystemTools::FileExists(this->Builddir.c_str(), false)) { @@ -1947,7 +1953,7 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName) } std::string ui_output_file = "ui_" + uiFileName + ".h"; - std::string ui_input_file = this->Srcdir + uiFileName + ".ui"; + std::string ui_input_file = path + uiFileName + ".ui"; int sourceNewerThanUi = 0; bool success = cmsys::SystemTools::FileTimeCompare(ui_input_file.c_str(), diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index f66d02ba01..2840fbf4b7 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -48,16 +48,16 @@ private: bool RunAutogen(cmMakefile* makefile); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); - bool GenerateUi(const std::string& uiFileName); + bool GenerateUi(const std::string& path, const std::string& uiFileName); bool GenerateQrc(); void ParseCppFile(const std::string& absFilename, const std::vector& headerExtensions, std::map& includedMocs, - std::vector& includedUis); + std::map& includedUis); void StrictParseCppFile(const std::string& absFilename, const std::vector& headerExtensions, std::map& includedMocs, - std::vector& includedUis); + std::map& includedUis); void SearchHeadersForCppFile(const std::string& absFilename, const std::vector& headerExtensions, std::set& absHeaders); @@ -65,14 +65,14 @@ private: void ParseHeaders(const std::set& absHeaders, const std::map& includedMocs, std::map& notIncludedMocs, - std::vector& includedUis); + std::map& includedUis); void ParseForUic(const std::string& fileName, const std::string& contentsString, - std::vector& includedUis); + std::map& includedUis); void ParseForUic(const std::string& fileName, - std::vector& includedUis); + std::map& includedUis); void Init(); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2807f973c8..1e04f2f972 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1191,6 +1191,18 @@ ${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/Qt4And5Automoc") + add_test(Qt4And5AutomocReverse ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Qt4And5Automoc" + "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse" + ${build_generator_args} + --build-project Qt4And5Automoc + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse" + --force-new-ctest-process + --build-options ${build_options} -DQT_REVERSE_FIND_ORDER=1 + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse") endif() endif() diff --git a/Tests/Qt4And5Automoc/CMakeLists.txt b/Tests/Qt4And5Automoc/CMakeLists.txt index 61d5743662..ad74961d9f 100644 --- a/Tests/Qt4And5Automoc/CMakeLists.txt +++ b/Tests/Qt4And5Automoc/CMakeLists.txt @@ -2,8 +2,13 @@ cmake_minimum_required(VERSION 2.8.12) project(Qt4And5Automoc) -find_package(Qt4 REQUIRED) -find_package(Qt5Core REQUIRED) +if (QT_REVERSE_FIND_ORDER) + find_package(Qt5Core REQUIRED) + find_package(Qt4 REQUIRED) +else() + find_package(Qt4 REQUIRED) + find_package(Qt5Core REQUIRED) +endif() set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 515bf5b09f..546ed02b6b 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -88,6 +88,6 @@ target_link_libraries(empty no_link_language) add_library(no_link_language STATIC empty.h) set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE) -qtx_wrap_cpp(uicOnlyMoc uiconly.h) -add_executable(uiconly uiconly.cpp ${uicOnlyMoc}) +qtx_wrap_cpp(uicOnlyMoc sub/uiconly.h) +add_executable(uiconly sub/uiconly.cpp ${uicOnlyMoc}) target_link_libraries(uiconly ${QT_LIBRARIES}) diff --git a/Tests/QtAutogen/uiconly.cpp b/Tests/QtAutogen/sub/uiconly.cpp similarity index 100% rename from Tests/QtAutogen/uiconly.cpp rename to Tests/QtAutogen/sub/uiconly.cpp diff --git a/Tests/QtAutogen/uiconly.h b/Tests/QtAutogen/sub/uiconly.h similarity index 100% rename from Tests/QtAutogen/uiconly.h rename to Tests/QtAutogen/sub/uiconly.h diff --git a/Tests/QtAutogen/uiconly.ui b/Tests/QtAutogen/sub/uiconly.ui similarity index 100% rename from Tests/QtAutogen/uiconly.ui rename to Tests/QtAutogen/sub/uiconly.ui