diff options
Diffstat (limited to 'Source/cmQtAutomoc.cxx')
-rw-r--r-- | Source/cmQtAutomoc.cxx | 216 |
1 files changed, 104 insertions, 112 deletions
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 25614b862..a1fa31f2a 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -17,6 +17,10 @@ #include "cmSourceFile.h" #include "cmSystemTools.h" +#if defined(_WIN32) && !defined(__CYGWIN__) +# include "cmLocalVisualStudioGenerator.h" +#endif + #include <cmsys/Terminal.h> #include <cmsys/ios/sstream> @@ -44,14 +48,14 @@ static bool containsQ_OBJECT(const std::string& text) static std::string findMatchingHeader(const std::string& absPath, const std::string& mocSubDir, const std::string& basename, - const std::list<std::string>& headerExtensions) + const std::vector<std::string>& headerExtensions) { std::string header; - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - std::string sourceFilePath = absPath + basename + (*ext); + std::string sourceFilePath = absPath + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { header = sourceFilePath; @@ -59,7 +63,7 @@ static std::string findMatchingHeader(const std::string& absPath, } if (!mocSubDir.empty()) { - sourceFilePath = mocSubDir + basename + (*ext); + sourceFilePath = mocSubDir + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { header = sourceFilePath; @@ -85,6 +89,18 @@ static std::string extractSubDir(const std::string& absPath, } +static void copyTargetProperty(cmTarget* destinationTarget, + cmTarget* sourceTarget, + const char* propertyName) +{ + const char* propertyValue = sourceTarget->GetProperty(propertyName); + if (propertyValue) + { + destinationTarget->SetProperty(propertyName, propertyValue); + } +} + + cmQtAutomoc::cmQtAutomoc() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,ColorOutput(true) @@ -107,12 +123,9 @@ cmQtAutomoc::cmQtAutomoc() } } - -void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); - cmLocalGenerator* localGen = makefile->GetLocalGenerator(); - const char* targetName = target->GetName(); // don't do anything if there is no Qt4 or Qt5Core (which contains moc): std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); if (qtMajorVersion == "") @@ -121,9 +134,30 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } if (qtMajorVersion != "4" && qtMajorVersion != "5") { - return; + return false; } + std::string automocTargetName = target->GetName(); + automocTargetName += "_automoc"; + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), + true); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); + + target->AddSourceFile(mocCppSource); + return true; +} + +void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +{ + cmMakefile* makefile = target->GetMakefile(); + cmLocalGenerator* localGen = makefile->GetLocalGenerator(); + const char* targetName = target->GetName(); + bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); // create a custom target for running automoc at buildtime: @@ -152,10 +186,44 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) std::string automocComment = "Automoc for target "; automocComment += targetName; - makefile->AddUtilityCommand(automocTargetName.c_str(), true, - workingDirectory.c_str(), depends, - commandLines, false, automocComment.c_str()); - target->AddUtility(automocTargetName.c_str()); +#if defined(_WIN32) && !defined(__CYGWIN__) + bool usePRE_BUILD = false; + cmGlobalGenerator* gg = localGen->GetGlobalGenerator(); + if(strstr(gg->GetName(), "Visual Studio")) + { + cmLocalVisualStudioGenerator* vslg = + static_cast<cmLocalVisualStudioGenerator*>(localGen); + // Under VS >= 7 use a PRE_BUILD event instead of a separate target to + // reduce the number of targets loaded into the IDE. + // This also works around a VS 11 bug that may skip updating the target: + // https://connect.microsoft.com/VisualStudio/feedback/details/769495 + usePRE_BUILD = vslg->GetVersion() >= cmLocalVisualStudioGenerator::VS7; + } + if(usePRE_BUILD) + { + // Add the pre-build command directly to bypass the OBJECT_LIBRARY + // rejection in cmMakefile::AddCustomCommandToTarget because we know + // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. + std::vector<std::string> no_output; + cmCustomCommand cc(makefile, no_output, depends, + commandLines, automocComment.c_str(), + workingDirectory.c_str()); + cc.SetEscapeOldStyle(false); + cc.SetEscapeAllowMakeVars(true); + target->GetPreBuildCommands().push_back(cc); + } + else +#endif + { + cmTarget* automocTarget = makefile->AddUtilityCommand( + automocTargetName.c_str(), true, + workingDirectory.c_str(), depends, + commandLines, false, automocComment.c_str()); + // inherit FOLDER property from target (#13688) + copyTargetProperty(automocTarget, target, "FOLDER"); + + target->AddUtility(automocTargetName.c_str()); + } // configure a file to get all information to automoc at buildtime: std::string _moc_files; @@ -196,36 +264,11 @@ 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<std::string> 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<std::string> includeDirs; cmGeneratorTarget gtgt(target); - localGen->GetIncludeDirectories(includeDirs, >gt, "CXX"); + // Get the include dirs for this target, without stripping the implicit + // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 + localGen->GetIncludeDirectories(includeDirs, >gt, "CXX", 0, false); std::string _moc_incs = ""; const char* sep = ""; for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin(); @@ -235,41 +278,14 @@ 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)) + const char* tmp = target->GetProperty("COMPILE_DEFINITIONS"); + std::string _moc_compile_defs; + if (tmp) { - _moc_incs += sep; - sep = ";"; - _moc_incs += qtIncDir; + _moc_compile_defs = target->GetCompileDefinitions(0); } - - const char* tmp = target->GetProperty("COMPILE_DEFINITIONS"); - std::string _moc_compile_defs = (tmp!=0 ? tmp : ""); tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); if (tmp) { @@ -304,17 +320,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) outputFile += "/AutomocInfo.cmake"; makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); - - std::string mocCppFile = makefile->GetCurrentOutputDirectory(); - mocCppFile += "/"; - mocCppFile += automocTargetName; - mocCppFile += ".cpp"; - cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), - true); - target->AddSourceFile(mocCppSource); - - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - mocCppFile.c_str(), false); } @@ -332,7 +337,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - success = this->RunAutomoc(); + success = this->RunAutomoc(makefile); } this->WriteOldMocDefinitionsFile(targetDirectory); @@ -540,7 +545,7 @@ void cmQtAutomoc::Init() } -bool cmQtAutomoc::RunAutomoc() +bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) { if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) @@ -564,22 +569,8 @@ bool cmQtAutomoc::RunAutomoc() std::vector<std::string> sourceFiles; cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); - std::list<std::string> headerExtensions; - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); -#if defined(_WIN32) - // not case sensitive, don't add ".H" -#elif defined(__APPLE__) - // detect case-sensitive filesystem - long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); - if (caseSensitive == 1) - { - headerExtensions.push_back(".H"); - } -#else - headerExtensions.push_back(".H"); -#endif + const std::vector<std::string>& headerExtensions = + makefile->GetHeaderExtensions(); for (std::vector<std::string>::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); @@ -679,7 +670,7 @@ bool cmQtAutomoc::RunAutomoc() void cmQtAutomoc::ParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( @@ -857,7 +848,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( @@ -968,8 +959,8 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, - std::set<std::string>& absHeaders) + const std::vector<std::string>& headerExtensions, + std::set<std::string>& absHeaders) { // search for header files and private header files we may need to moc: const std::string basename = @@ -977,22 +968,22 @@ void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - const std::string headerName = absPath + basename + (*ext); + const std::string headerName = absPath + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(headerName.c_str())) { absHeaders.insert(headerName); break; } } - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + const std::string privateHeaderName = absPath+basename+"_p."+(*ext); if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())) { absHeaders.insert(privateHeaderName); @@ -1113,7 +1104,8 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, } -std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator) +std::string cmQtAutomoc::Join(const std::vector<std::string>& lst, + char separator) { if (lst.empty()) { @@ -1121,11 +1113,11 @@ std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator) } std::string result; - for (std::list<std::string>::const_iterator it = lst.begin(); + for (std::vector<std::string>::const_iterator it = lst.begin(); it != lst.end(); ++it) { - result += (*it) + separator; + result += "." + (*it) + separator; } result.erase(result.end() - 1); return result; |