diff options
author | Brad King <brad.king@kitware.com> | 2017-03-02 14:26:13 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2017-03-02 14:26:13 (GMT) |
commit | c1fb7213edaf512774eb74adb0a89b4984f88904 (patch) | |
tree | 98b0418a4773c045e257d20eac411db6be200c01 /Source | |
parent | 6c332bd84ce320e4163130a052af7b9950b38318 (diff) | |
parent | 3bf28f5ed057b2fe4d90c601065188055bb052a1 (diff) | |
download | CMake-c1fb7213edaf512774eb74adb0a89b4984f88904.zip CMake-c1fb7213edaf512774eb74adb0a89b4984f88904.tar.gz CMake-c1fb7213edaf512774eb74adb0a89b4984f88904.tar.bz2 |
Merge topic 'autogen_uic_paths'
3bf28f5e Autogen: New short InfoGet functions
154d8339 Autogen: Parse enabled feature configuration only
ac77fa35 Autogen: Add missing return on error
662ad240 Autogen: Rename and merge moc related methods
5adf22bb Autogen: Add AUTOUIC_SEARCH_PATHS release notes
36fa535d Autogen: Add AUTOUIC_SEARCH_PATHS documentation
6d7c02db Autogen: Add AUTOUIC_SEARCH_PATHS test
1cdf7c1b Autogen: Add AUTOUIC_SEARCH_PATHS support
110c1bf4 Autogen: Add subDirPrefix function
db431ecf Autogen: Merge FindInIncludeDirectories into FindIncludeFile
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 15 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 516 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 18 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 |
4 files changed, 292 insertions, 258 deletions
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index de18265..a45b3d5 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -306,6 +306,19 @@ static void UicSetupAutoTarget( AddDefinitionEscaped(makefile, "_uic_skip", uicSkipList); + // Uic search paths + { + std::vector<std::string> uicSearchPaths; + cmSystemTools::ExpandListArgument( + GetSafeProperty(target, "AUTOUIC_SEARCH_PATHS"), uicSearchPaths); + const std::string srcDir = makefile->GetCurrentSourceDirectory(); + for (std::vector<std::string>::iterator it = uicSearchPaths.begin(); + it != uicSearchPaths.end(); ++it) { + *it = cmSystemTools::CollapseFullPath(*it, srcDir); + } + AddDefinitionEscaped(makefile, "_uic_search_paths", uicSearchPaths); + } + // Uic target options { std::string _uic_opts; @@ -959,7 +972,7 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( it = configMocDefines.begin(), end = configMocDefines.end(); it != end; ++it) { - infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first << " " + infoFile << "set(AM_MOC_DEFINITIONS_" << it->first << " " << it->second << ")\n"; } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e7e456a..c83f9a9 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -55,20 +55,38 @@ static std::string Quoted(const std::string& text) return res; } -static std::string GetConfigDefinition(cmMakefile* makefile, - const std::string& key, - const std::string& config) +static void InfoGet(cmMakefile* makefile, const char* key, std::string& value) { - std::string keyConf = key; - if (!config.empty()) { - keyConf += "_"; - keyConf += config; + value = makefile->GetSafeDefinition(key); +} + +static void InfoGet(cmMakefile* makefile, const char* key, bool& value) +{ + value = makefile->IsOn(key); +} + +static void InfoGet(cmMakefile* makefile, const char* key, + std::vector<std::string>& list) +{ + cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); +} + +static void InfoGet(cmMakefile* makefile, const char* key, + const std::string& config, std::vector<std::string>& list) +{ + const char* valueConf = CM_NULLPTR; + { + std::string keyConf = key; + if (!config.empty()) { + keyConf += "_"; + keyConf += config; + } + valueConf = makefile->GetDefinition(keyConf); } - const char* valueConf = makefile->GetDefinition(keyConf); - if (valueConf != CM_NULLPTR) { - return valueConf; + if (valueConf == CM_NULLPTR) { + valueConf = makefile->GetSafeDefinition(key); } - return makefile->GetSafeDefinition(key); + cmSystemTools::ExpandListArgument(valueConf, list); } static std::string SettingsFile(const std::string& targetDirectory) @@ -94,6 +112,15 @@ static void SettingWrite(std::ostream& ostr, const char* key, } } +std::string subDirPrefix(const std::string& fileName) +{ + std::string res(cmsys::SystemTools::GetFilenamePath(fileName)); + if (!res.empty()) { + res += '/'; + } + return res; +} + static bool FileNameIsUnique(const std::string& filePath, const std::map<std::string, std::string>& fileMap) { @@ -319,24 +346,27 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } // - Target names - this->OriginTargetName = - makefile->GetSafeDefinition("AM_ORIGIN_TARGET_NAME"); - this->AutogenTargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); - - // - Directories - this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); - this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); - this->CurrentSourceDir = - makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR"); - this->CurrentBinaryDir = - makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR"); + InfoGet(makefile, "AM_TARGET_NAME", this->AutogenTargetName); + InfoGet(makefile, "AM_ORIGIN_TARGET_NAME", this->OriginTargetName); + + // - Files and directories + InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir); + InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir); + InfoGet(makefile, "AM_CMAKE_CURRENT_SOURCE_DIR", this->CurrentSourceDir); + InfoGet(makefile, "AM_CMAKE_CURRENT_BINARY_DIR", this->CurrentBinaryDir); + InfoGet(makefile, "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", + this->IncludeProjectDirsBefore); + InfoGet(makefile, "AM_SOURCES", this->Sources); + InfoGet(makefile, "AM_HEADERS", this->Headers); // - Qt environment - this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); - if (this->QtMajorVersion == "") { - this->QtMajorVersion = - makefile->GetSafeDefinition("AM_Qt5Core_VERSION_MAJOR"); + InfoGet(makefile, "AM_QT_VERSION_MAJOR", this->QtMajorVersion); + if (this->QtMajorVersion.empty()) { + InfoGet(makefile, "AM_Qt5Core_VERSION_MAJOR", this->QtMajorVersion); } + InfoGet(makefile, "AM_QT_MOC_EXECUTABLE", this->MocExecutable); + InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable); + InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable); // Check Qt version if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { this->LogError("AutoGen: Error: Unsupported Qt version: " + @@ -344,132 +374,115 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( return false; } - this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); - this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE"); - this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE"); - - // - File Lists - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_SOURCES"), - this->Sources); - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_HEADERS"), - this->Headers); - // - Moc - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_MOC_SKIP"), - this->MocSkipList); - cmSystemTools::ExpandListArgument( - GetConfigDefinition(makefile, "AM_MOC_COMPILE_DEFINITIONS", config), - this->MocDefinitions); - cmSystemTools::ExpandListArgument( - GetConfigDefinition(makefile, "AM_MOC_INCLUDES", config), - this->MocIncludePaths); - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_MOC_OPTIONS"), this->MocOptions); - { - std::vector<std::string> mocDependFilters; - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_MOC_DEPEND_FILTERS"), mocDependFilters); - // Insert Q_PLUGIN_METADATA dependency filter - if (this->QtMajorVersion != "4") { - this->MocDependFilterPush("Q_PLUGIN_METADATA", - "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\(" - "[^\\)]*FILE[ \t]*\"([^\"]+)\""); - } - // Insert user defined dependency filters - if ((mocDependFilters.size() % 2) == 0) { - for (std::vector<std::string>::const_iterator dit = - mocDependFilters.begin(); - dit != mocDependFilters.end(); dit += 2) { - if (!this->MocDependFilterPush(*dit, *(dit + 1))) { - return false; + if (this->MocEnabled()) { + InfoGet(makefile, "AM_MOC_SKIP", this->MocSkipList); + InfoGet(makefile, "AM_MOC_DEFINITIONS", config, this->MocDefinitions); + InfoGet(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths); + InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions); + InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode); + { + std::vector<std::string> mocDependFilters; + InfoGet(makefile, "AM_MOC_DEPEND_FILTERS", mocDependFilters); + // Insert Q_PLUGIN_METADATA dependency filter + if (this->QtMajorVersion != "4") { + this->MocDependFilterPush("Q_PLUGIN_METADATA", + "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\(" + "[^\\)]*FILE[ \t]*\"([^\"]+)\""); + } + // Insert user defined dependency filters + if ((mocDependFilters.size() % 2) == 0) { + for (std::vector<std::string>::const_iterator dit = + mocDependFilters.begin(); + dit != mocDependFilters.end(); dit += 2) { + if (!this->MocDependFilterPush(*dit, *(dit + 1))) { + return false; + } } + } else { + this->LogError( + "AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not " + "a multiple of 2"); + return false; } - } else { - this->LogError("AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not " - "a multiple of 2"); } } // - Uic - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_UIC_SKIP"), - this->UicSkipList); - cmSystemTools::ExpandListArgument( - GetConfigDefinition(makefile, "AM_UIC_TARGET_OPTIONS", config), - this->UicTargetOptions); - { - std::vector<std::string> uicFilesVec; - std::vector<std::string> uicOptionsVec; - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES"), uicFilesVec); - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"), uicOptionsVec); - if (uicFilesVec.size() != uicOptionsVec.size()) { - this->LogError( - "AutoGen: Error: Uic files/options lists size missmatch in: " + - filename); - return false; - } - for (std::vector<std::string>::iterator fileIt = uicFilesVec.begin(), - optionIt = uicOptionsVec.begin(); - fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); - this->UicOptions[*fileIt] = *optionIt; + if (this->UicEnabled()) { + InfoGet(makefile, "AM_UIC_SKIP", this->UicSkipList); + InfoGet(makefile, "AM_UIC_SEARCH_PATHS", this->UicSearchPaths); + InfoGet(makefile, "AM_UIC_TARGET_OPTIONS", config, this->UicTargetOptions); + { + std::vector<std::string> uicFilesVec; + std::vector<std::string> uicOptionsVec; + InfoGet(makefile, "AM_UIC_OPTIONS_FILES", uicFilesVec); + InfoGet(makefile, "AM_UIC_OPTIONS_OPTIONS", uicOptionsVec); + // Compare list sizes + if (uicFilesVec.size() == uicOptionsVec.size()) { + for (std::vector<std::string>::iterator + fileIt = uicFilesVec.begin(), + optionIt = uicOptionsVec.begin(); + fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) { + cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + this->UicOptions[*fileIt] = *optionIt; + } + } else { + this->LogError( + "AutoGen: Error: Uic files/options lists size missmatch in: " + + filename); + return false; + } } } // - Rcc - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_RCC_SOURCES"), this->RccSources); - { - std::vector<std::string> rccFilesVec; - std::vector<std::string> rccOptionsVec; - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES"), rccFilesVec); - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS"), rccOptionsVec); - if (rccFilesVec.size() != rccOptionsVec.size()) { - this->LogError( - "AutoGen: Error: RCC files/options lists size missmatch in: " + - filename); - return false; - } - for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(), - optionIt = rccOptionsVec.begin(); - fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); - this->RccOptions[*fileIt] = *optionIt; - } - } - { - std::vector<std::string> rccInputLists; - cmSystemTools::ExpandListArgument( - makefile->GetSafeDefinition("AM_RCC_INPUTS"), rccInputLists); - - // qrc files in the end of the list may have been empty - if (rccInputLists.size() < this->RccSources.size()) { - rccInputLists.resize(this->RccSources.size()); - } - if (this->RccSources.size() != rccInputLists.size()) { - this->LogError( - "AutoGen: Error: RCC sources/inputs lists size missmatch in: " + - filename); - return false; + if (this->RccEnabled()) { + InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources); + { + std::vector<std::string> rccFilesVec; + std::vector<std::string> rccOptionsVec; + InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec); + InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec); + if (rccFilesVec.size() != rccOptionsVec.size()) { + this->LogError( + "AutoGen: Error: RCC files/options lists size missmatch in: " + + filename); + return false; + } + for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(), + optionIt = rccOptionsVec.begin(); + fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { + cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + this->RccOptions[*fileIt] = *optionIt; + } } - for (std::vector<std::string>::iterator fileIt = this->RccSources.begin(), - inputIt = rccInputLists.begin(); - fileIt != this->RccSources.end(); ++fileIt, ++inputIt) { - cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";"); - std::vector<std::string> rccInputFiles; - cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); - this->RccInputs[*fileIt] = rccInputFiles; + { + std::vector<std::string> rccInputLists; + InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists); + + // qrc files in the end of the list may have been empty + if (rccInputLists.size() < this->RccSources.size()) { + rccInputLists.resize(this->RccSources.size()); + } + if (this->RccSources.size() != rccInputLists.size()) { + this->LogError( + "AutoGen: Error: RCC sources/inputs lists size missmatch in: " + + filename); + return false; + } + for (std::vector<std::string>::iterator + fileIt = this->RccSources.begin(), + inputIt = rccInputLists.begin(); + fileIt != this->RccSources.end(); ++fileIt, ++inputIt) { + cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";"); + std::vector<std::string> rccInputFiles; + cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); + this->RccInputs[*fileIt] = rccInputFiles; + } } } - // - Flags - this->IncludeProjectDirsBefore = - makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); - this->MocRelaxedMode = makefile->IsOn("AM_MOC_RELAXED_MODE"); - return true; } @@ -727,15 +740,15 @@ void cmQtAutoGenerators::MocFindDepends( // regular expression check if (contentText.find(filter.key) != std::string::npos) { // Run regular expression check loop + const std::string sourcePath = subDirPrefix(absFilename); const char* contentChars = contentText.c_str(); while (filter.regExp.find(contentChars)) { // Evaluate match const std::string match = filter.regExp.match(1); if (!match.empty()) { // Find the dependency file - const std::string incFile = - this->FindIncludedFile(absFilename, match); - if (!incFile.empty()) { + std::string incFile; + if (this->MocFindIncludedFile(incFile, sourcePath, match)) { mocDepends[absFilename].insert(incFile); if (this->Verbose) { this->LogInfo("AutoMoc: Found dependency:\n " + @@ -823,12 +836,7 @@ void cmQtAutoGenerators::UicParseContent( const char* contentChars = contentText.c_str(); if (strstr(contentChars, "ui_") != CM_NULLPTR) { while (this->RegExpUicInclude.find(contentChars)) { - const std::string currentUi = this->RegExpUicInclude.match(1); - const std::string basename = - cmsys::SystemTools::GetFilenameWithoutLastExtension(currentUi); - // basename should be the part of the ui filename used for - // finding the correct header, so we need to remove the ui_ part - uisIncluded[absFilename].push_back(basename.substr(3)); + uisIncluded[absFilename].push_back(this->RegExpUicInclude.match(1)); contentChars += this->RegExpUicInclude.end(); } } @@ -846,8 +854,7 @@ bool cmQtAutoGenerators::MocParseSourceContent( this->LogInfo("AutoMoc: Checking " + absFilename); } - const std::string scannedFileAbsPath = - cmsys::SystemTools::GetFilenamePath(absFilename) + '/'; + const std::string scannedFileAbsPath = subDirPrefix(absFilename); const std::string scannedFileBasename = cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); @@ -866,13 +873,9 @@ bool cmQtAutoGenerators::MocParseSourceContent( while (this->RegExpMocInclude.find(contentChars)) { const std::string incString = this->RegExpMocInclude.match(1); // Basename of the moc include + const std::string incSubDir(subDirPrefix(incString)); const std::string incBasename = cmsys::SystemTools::GetFilenameWithoutLastExtension(incString); - std::string incSubDir; - if (incString.find_first_of('/') != std::string::npos) { - incSubDir = cmsys::SystemTools::GetFilenamePath(incString); - incSubDir += '/'; - } // If the moc include is of the moc_foo.cpp style we expect // the Q_OBJECT class declaration in a header file. @@ -884,7 +887,7 @@ bool cmQtAutoGenerators::MocParseSourceContent( // Remove the moc_ part const std::string incRealBasename = incBasename.substr(4); const std::string headerToMoc = - this->FindMocHeader(scannedFileAbsPath, incRealBasename, incSubDir); + this->MocFindHeader(scannedFileAbsPath, incSubDir + incRealBasename); if (!headerToMoc.empty()) { // Register moc job mocsIncluded[headerToMoc] = incString; @@ -917,7 +920,7 @@ bool cmQtAutoGenerators::MocParseSourceContent( } else { // In relaxed mode try to find a header instead but issue a warning const std::string headerToMoc = - this->FindMocHeader(scannedFileAbsPath, incBasename, incSubDir); + this->MocFindHeader(scannedFileAbsPath, incSubDir + incBasename); if (!headerToMoc.empty()) { // This is for KDE4 compatibility: fileToMoc = headerToMoc; @@ -1056,8 +1059,7 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile( { std::string basepaths[2]; { - std::string bpath = cmsys::SystemTools::GetFilenamePath(absFilename); - bpath += '/'; + std::string bpath = subDirPrefix(absFilename); bpath += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); // search for default header files and private header files basepaths[0] = bpath; @@ -1235,14 +1237,14 @@ bool cmQtAutoGenerators::MocGenerateAll( */ bool cmQtAutoGenerators::MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDirPrefix, + const std::string& subDir, const std::map<std::string, std::set<std::string> >& mocDepends) { bool mocGenerated = false; bool generateMoc = this->GenerateAllMoc; const std::string mocFileRel = - this->AutogenBuildSubDir + subDirPrefix + mocFileName; + this->AutogenBuildSubDir + subDir + mocFileName; const std::string mocFileAbs = this->CurrentBinaryDir + mocFileRel; if (!generateMoc) { @@ -1323,6 +1325,36 @@ bool cmQtAutoGenerators::MocGenerateFile( return mocGenerated; } +bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, + const std::string& sourceFile, + const std::string& includeString) +{ + bool success = false; + // Search in vicinity of the source + { + std::string testPath = subDirPrefix(sourceFile); + testPath += includeString; + if (cmsys::SystemTools::FileExists(testPath.c_str())) { + absFile = cmsys::SystemTools::GetRealPath(testPath); + success = true; + } + } + // Search in include directories + if (!success) { + for (std::vector<std::string>::const_iterator iit = + this->UicSearchPaths.begin(); + iit != this->UicSearchPaths.end(); ++iit) { + const std::string fullPath = ((*iit) + '/' + includeString); + if (cmsys::SystemTools::FileExists(fullPath.c_str())) { + absFile = cmsys::SystemTools::GetRealPath(fullPath); + success = true; + break; + } + } + } + return success; +} + bool cmQtAutoGenerators::UicGenerateAll( const std::map<std::string, std::vector<std::string> >& uisIncluded) { @@ -1331,46 +1363,57 @@ bool cmQtAutoGenerators::UicGenerateAll( } // single map with input / output names - std::map<std::string, std::map<std::string, std::string> > uiGenMap; - std::map<std::string, std::string> testMap; - for (std::map<std::string, std::vector<std::string> >::const_iterator it = - uisIncluded.begin(); - it != uisIncluded.end(); ++it) { - // source file path - std::string sourcePath = cmsys::SystemTools::GetFilenamePath(it->first); - sourcePath += '/'; - // insert new map for source file an use new reference - uiGenMap[it->first] = std::map<std::string, std::string>(); - std::map<std::string, std::string>& sourceMap = uiGenMap[it->first]; - for (std::vector<std::string>::const_iterator sit = it->second.begin(); - sit != it->second.end(); ++sit) { - const std::string& uiFileName = *sit; - const std::string uiInputFile = sourcePath + uiFileName + ".ui"; - const std::string uiOutputFile = "ui_" + uiFileName + ".h"; - sourceMap[uiInputFile] = uiOutputFile; - testMap[uiInputFile] = uiOutputFile; - } - } - - // look for name collisions + std::map<std::string, std::map<std::string, std::string> > sourceGenMap; { - std::multimap<std::string, std::string> collisions; - if (this->NameCollisionTest(testMap, collisions)) { - std::ostringstream ost; - ost << "AutoUic: Error: The same ui_NAME.h file will be generated " - "from different sources.\n" - "To avoid this error rename the source files.\n"; - this->LogErrorNameCollision(ost.str(), collisions); - return false; + // Collision lookup map + std::map<std::string, std::string> testMap; + // Compile maps + for (std::map<std::string, std::vector<std::string> >::const_iterator sit = + uisIncluded.begin(); + sit != uisIncluded.end(); ++sit) { + const std::string& source(sit->first); + const std::vector<std::string>& sourceIncs(sit->second); + // insert new source/destination map + std::map<std::string, std::string>& uiGenMap = sourceGenMap[source]; + for (std::vector<std::string>::const_iterator uit = sourceIncs.begin(); + uit != sourceIncs.end(); ++uit) { + // Remove ui_ from the begin filename by substr() + const std::string uiBasePath = subDirPrefix(*uit); + const std::string uiBaseName = + cmsys::SystemTools::GetFilenameWithoutLastExtension(*uit).substr(3); + const std::string searchFileName = uiBasePath + uiBaseName + ".ui"; + std::string uiInputFile; + if (UicFindIncludedFile(uiInputFile, source, searchFileName)) { + std::string uiOutputFile = uiBasePath + "ui_" + uiBaseName + ".h"; + cmSystemTools::ReplaceString(uiOutputFile, "..", "__"); + uiGenMap[uiInputFile] = uiOutputFile; + testMap[uiInputFile] = uiOutputFile; + } else { + this->LogError("AutoUic: Error: " + Quoted(sit->first) + + "\nCould not find " + Quoted(searchFileName)); + return false; + } + } + } + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + if (this->NameCollisionTest(testMap, collisions)) { + std::ostringstream ost; + ost << "AutoUic: Error: The same ui_NAME.h file will be generated " + "from different sources.\n" + "To avoid this error rename the source files.\n"; + this->LogErrorNameCollision(ost.str(), collisions); + return false; + } } } - testMap.clear(); // generate ui files for (std::map<std::string, std::map<std::string, std::string> >::const_iterator it = - uiGenMap.begin(); - it != uiGenMap.end(); ++it) { + sourceGenMap.begin(); + it != sourceGenMap.end(); ++it) { for (std::map<std::string, std::string>::const_iterator sit = it->second.begin(); sit != it->second.end(); ++sit) { @@ -1413,15 +1456,15 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, std::vector<std::string> cmd; cmd.push_back(this->UicExecutable); { - std::vector<std::string> opts = this->UicTargetOptions; + std::vector<std::string> allOpts = this->UicTargetOptions; std::map<std::string, std::string>::const_iterator optionIt = this->UicOptions.find(uiInputFile); if (optionIt != this->UicOptions.end()) { std::vector<std::string> fileOpts; cmSystemTools::ExpandListArgument(optionIt->second, fileOpts); - UicMergeOptions(opts, fileOpts, (this->QtMajorVersion == "5")); + UicMergeOptions(allOpts, fileOpts, (this->QtMajorVersion == "5")); } - cmd.insert(cmd.end(), opts.begin(), opts.end()); + cmd.insert(cmd.end(), allOpts.begin(), allOpts.end()); } cmd.push_back("-o"); cmd.push_back(uicFileAbs); @@ -1740,39 +1783,22 @@ bool cmQtAutoGenerators::FindHeader(std::string& header, return false; } -bool cmQtAutoGenerators::FindHeaderGlobal( - std::string& header, const std::string& testBasePath) const -{ - for (std::vector<std::string>::const_iterator iit = - this->MocIncludePaths.begin(); - iit != this->MocIncludePaths.end(); ++iit) { - const std::string fullPath = ((*iit) + '/' + testBasePath); - if (FindHeader(header, fullPath)) { - return true; - } - } - return false; -} - -std::string cmQtAutoGenerators::FindMocHeader(const std::string& basePath, - const std::string& baseName, - const std::string& subDir) const +std::string cmQtAutoGenerators::MocFindHeader( + const std::string& sourcePath, const std::string& includeBase) const { std::string header; - do { - if (!subDir.empty()) { - if (this->FindHeader(header, basePath + subDir + baseName)) { + // Search in vicinity of the source + if (!this->FindHeader(header, sourcePath + includeBase)) { + // Search in include directories + for (std::vector<std::string>::const_iterator iit = + this->MocIncludePaths.begin(); + iit != this->MocIncludePaths.end(); ++iit) { + const std::string fullPath = ((*iit) + '/' + includeBase); + if (FindHeader(header, fullPath)) { break; } } - if (this->FindHeader(header, basePath + baseName)) { - break; - } - // Try include directories - if (this->FindHeaderGlobal(header, subDir + baseName)) { - break; - } - } while (false); + } // Sanitize if (!header.empty()) { header = cmsys::SystemTools::GetRealPath(header); @@ -1780,40 +1806,34 @@ std::string cmQtAutoGenerators::FindMocHeader(const std::string& basePath, return header; } -std::string cmQtAutoGenerators::FindIncludedFile( - const std::string& sourceFile, const std::string& includeString) const +bool cmQtAutoGenerators::MocFindIncludedFile( + std::string& absFile, const std::string& sourcePath, + const std::string& includeString) const { + bool success = false; // Search in vicinity of the source { - std::string testPath = cmSystemTools::GetFilenamePath(sourceFile); - testPath += '/'; + std::string testPath = sourcePath; testPath += includeString; if (cmsys::SystemTools::FileExists(testPath.c_str())) { - return cmsys::SystemTools::GetRealPath(testPath); + absFile = cmsys::SystemTools::GetRealPath(testPath); + success = true; } } - // Search globally - return FindInIncludeDirectories(includeString); -} - -/** - * @brief Tries to find a file in the include directories - * @return True on success - */ -std::string cmQtAutoGenerators::FindInIncludeDirectories( - const std::string& includeString) const -{ - std::string res; - for (std::vector<std::string>::const_iterator iit = - this->MocIncludePaths.begin(); - iit != this->MocIncludePaths.end(); ++iit) { - const std::string fullPath = ((*iit) + '/' + includeString); - if (cmsys::SystemTools::FileExists(fullPath.c_str())) { - res = cmsys::SystemTools::GetRealPath(fullPath); - break; + // Search in include directories + if (!success) { + for (std::vector<std::string>::const_iterator iit = + this->MocIncludePaths.begin(); + iit != this->MocIncludePaths.end(); ++iit) { + const std::string fullPath = ((*iit) + '/' + includeString); + if (cmsys::SystemTools::FileExists(fullPath.c_str())) { + absFile = cmsys::SystemTools::GetRealPath(fullPath); + success = true; + break; + } } } - return res; + return success; } /** diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index e4b7f60..3bff2b2 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -107,10 +107,12 @@ private: const std::map<std::string, std::set<std::string> >& mocDepends); bool MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDirPrefix, + const std::string& subDir, const std::map<std::string, std::set<std::string> >& mocDepends); // - Uic file generation + bool UicFindIncludedFile(std::string& absFile, const std::string& sourceFile, + const std::string& includeString); bool UicGenerateAll( const std::map<std::string, std::vector<std::string> >& includedUis); bool UicGenerateFile(const std::string& realName, @@ -142,14 +144,11 @@ private: bool MakeParentDirectory(const std::string& filename) const; bool FindHeader(std::string& header, const std::string& testBasePath) const; - bool FindHeaderGlobal(std::string& header, - const std::string& testBasePath) const; - std::string FindMocHeader(const std::string& basePath, - const std::string& baseName, - const std::string& subDir) const; - std::string FindIncludedFile(const std::string& sourceFile, - const std::string& includeString) const; - std::string FindInIncludeDirectories(const std::string& includeString) const; + + std::string MocFindHeader(const std::string& sourcePath, + const std::string& includeBase) const; + bool MocFindIncludedFile(std::string& absFile, const std::string& sourceFile, + const std::string& includeString) const; // - Target names std::string OriginTargetName; @@ -185,6 +184,7 @@ private: std::vector<std::string> UicSkipList; std::vector<std::string> UicTargetOptions; std::map<std::string, std::string> UicOptions; + std::vector<std::string> UicSearchPaths; // - Rcc std::vector<std::string> RccSources; std::map<std::string, std::string> RccOptions; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0f3d91b..c360c19 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -248,6 +248,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", CM_NULLPTR); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("AUTOUIC_OPTIONS", CM_NULLPTR); + this->SetPropertyDefault("AUTOUIC_SEARCH_PATHS", CM_NULLPTR); this->SetPropertyDefault("AUTORCC_OPTIONS", CM_NULLPTR); this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", CM_NULLPTR); this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", CM_NULLPTR); |