diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.cxx | 42 | ||||
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio10Generator.cxx | 6 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio10Generator.h | 6 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio11Generator.cxx | 8 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio71Generator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.cxx | 10 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.h | 6 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio9Generator.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 107 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 21 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 142 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 811 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 32 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 10 |
18 files changed, 838 insertions, 378 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index af88d2c..489dc3c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 5) -set(CMake_VERSION_PATCH 20160418) +set(CMake_VERSION_PATCH 20160428) #set(CMake_VERSION_RC 1) diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 1f17f8f..12e2eee 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -481,9 +481,46 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( } } +std::map<const cmSourceFile *, std::string> +cmGhsMultiTargetGenerator::GetObjectNames( + const std::vector<cmSourceFile *> &objectSources) +{ + bool found_duplicate = false; + std::set<std::string> filenames; + for(std::vector<cmSourceFile *>::const_iterator + sf = objectSources.begin(); sf != objectSources.end(); ++sf) + { + const std::string filename = + cmSystemTools::GetFilenameName((*sf)->GetFullPath()); + const std::string lower_filename = cmSystemTools::LowerCase(filename); + if (filenames.end() != filenames.find(lower_filename)) + { + found_duplicate = true; + } + filenames.insert(lower_filename); + } + + std::map<const cmSourceFile *, std::string> objectNames; + if (found_duplicate) + { + for(std::vector<cmSourceFile *>::const_iterator + sf = objectSources.begin(); sf != objectSources.end(); ++sf) + { + std::string full_filename = (*sf)->GetFullPath(); + cmsys::SystemTools::ReplaceString(full_filename, ":/", "_"); + cmsys::SystemTools::ReplaceString(full_filename, "/", "_"); + objectNames[*sf] = full_filename; + } + } + + return objectNames; +} + void cmGhsMultiTargetGenerator::WriteSources( std::vector<cmSourceFile *> const &objectSources) { + std::map<const cmSourceFile *, std::string> objectNames = + cmGhsMultiTargetGenerator::GetObjectNames(objectSources); for (std::vector<cmSourceFile *>::const_iterator si = objectSources.begin(); si != objectSources.end(); ++si) { @@ -515,6 +552,11 @@ void cmGhsMultiTargetGenerator::WriteSources( "bsp" != (*si)->GetExtension()) { this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si)); + if (objectNames.end() != objectNames.find(*si)) + { + *this->FolderBuildStreams[sgPath] << " -o \"" << + objectNames.find(*si)->second << ".o\"" << std::endl; + } this->WriteObjectDir(this->FolderBuildStreams[sgPath], this->AbsBuildFilePath + sgPath); diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index e85e412..3a13600 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -88,6 +88,8 @@ private: WriteCustomCommandsHelper(std::vector<cmCustomCommand> const &commandsSet, cmTarget::CustomCommandType commandType); void WriteSources(std::vector<cmSourceFile *> const &objectSources); + static std::map<const cmSourceFile *, std::string> + GetObjectNames(const std::vector<cmSourceFile *> &objectSources); static void WriteObjectLangOverride(cmGeneratedFileStream *fileStream, cmSourceFile *sourceFile); static void WriteObjectDir(cmGeneratedFileStream *fileStream, diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index c49008d..c24e7f5 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -609,12 +609,6 @@ void cmGlobalVisualStudio10Generator::PathTooLong( } //---------------------------------------------------------------------------- -bool cmGlobalVisualStudio10Generator::UseFolderProperty() -{ - return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty(); -} - -//---------------------------------------------------------------------------- bool cmGlobalVisualStudio10Generator::IsNsightTegra() const { return !this->NsightTegraVersion.empty(); diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 6bf4740..8723fd1 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -56,9 +56,6 @@ public: cmMakefile *, bool optional); virtual void WriteSLNHeader(std::ostream& fout); - /** Is the installed VS an Express edition? */ - bool IsExpressEdition() const { return this->ExpressEdition; } - /** Generating for Nsight Tegra VS plugin? */ bool IsNsightTegra() const; std::string GetNsightTegraVersion() const; @@ -129,9 +126,6 @@ protected: bool SystemIsWindowsCE; bool SystemIsWindowsPhone; bool SystemIsWindowsStore; - bool ExpressEdition; - - bool UseFolderProperty(); private: class Factory; diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 9522f6e..9b00357 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -239,10 +239,10 @@ void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout) //---------------------------------------------------------------------------- bool cmGlobalVisualStudio11Generator::UseFolderProperty() { - // Intentionally skip over the parent class implementation and call the - // grand-parent class's implementation. Folders are not supported by the - // Express editions in VS10 and earlier, but they are in VS11 Express. - return cmGlobalVisualStudio8Generator::UseFolderProperty(); + // Intentionally skip up to the top-level class implementation. + // Folders are not supported by the Express editions in VS10 and earlier, + // but they are in VS11 Express and above. + return cmGlobalGenerator::UseFolderProperty(); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 5035fda..d20ffbc 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -75,6 +75,9 @@ protected: const std::set<std::string>& depends); virtual void WriteSLNHeader(std::ostream& fout); + // Folders are not supported by VS 7.1. + virtual bool UseFolderProperty() { return false; } + std::string ProjectConfigurationSectionName; }; #endif diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 3abff6c..5c50530 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -103,6 +103,10 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator(cmake* cm, this->Name = name; this->ExtraFlagTable = this->GetExtraFlagTableVS8(); this->Version = VS8; + std::string vc8Express; + this->ExpressEdition = cmSystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\8.0\\Setup\\VC;" + "ProductDir", vc8Express, cmSystemTools::KeyWOW64_32); } //---------------------------------------------------------------------------- @@ -190,6 +194,12 @@ void cmGlobalVisualStudio8Generator::Configure() } //---------------------------------------------------------------------------- +bool cmGlobalVisualStudio8Generator::UseFolderProperty() +{ + return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty(); +} + +//---------------------------------------------------------------------------- std::string cmGlobalVisualStudio8Generator::GetUserMacrosDirectory() { // Some VS8 sp0 versions cannot run macros. diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index b3093cc..6eb8450 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -66,6 +66,9 @@ public: virtual bool TargetsWindowsCE() const { return !this->WindowsCEVersion.empty(); } + /** Is the installed VS an Express edition? */ + bool IsExpressEdition() const { return this->ExpressEdition; } + protected: virtual void AddExtraIDETargets(); virtual const char* GetIDEVersion() { return "8.0"; } @@ -94,8 +97,11 @@ protected: const char* path, const cmGeneratorTarget *t); + bool UseFolderProperty(); + std::string Name; std::string WindowsCEVersion; + bool ExpressEdition; private: class Factory; diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 884f754..da6ffae 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -104,6 +104,10 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(cmake* cm, : cmGlobalVisualStudio8Generator(cm, name, platformName) { this->Version = VS9; + std::string vc9Express; + this->ExpressEdition = cmSystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0\\Setup\\VC;" + "ProductDir", vc9Express, cmSystemTools::KeyWOW64_32); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 04146fb..9817b09 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -92,7 +92,7 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets() // // Organize in the "predefined targets" folder: // - if (this->UseFolderProperty() && this->GetVersion() > VS71) + if (this->UseFolderProperty()) { allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder()); } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7c85281..755c8a6 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -84,7 +84,7 @@ public: bool IsEmpty() const { return this->Empty; } - void Add(const char *newString) + void Add(const std::string& newString) { this->Empty = false; @@ -109,7 +109,7 @@ public: } else { - return this->Generator->CreateString(this->String.c_str()); + return this->Generator->CreateString(this->String); } } }; @@ -804,7 +804,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); - settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags.c_str())); + settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags)); // Is this a resource file in this target? Add it to the resources group... // @@ -1011,8 +1011,8 @@ cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath( std::string name = cmSystemTools::GetFilenameName(path.c_str()); const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())? "<absolute>" : "SOURCE_ROOT"); - fileRef->AddAttribute("name", this->CreateString(name.c_str())); - fileRef->AddAttribute("path", this->CreateString(path.c_str())); + fileRef->AddAttribute("name", this->CreateString(name)); + fileRef->AddAttribute("path", this->CreateString(path)); fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree)); if(this->XcodeVersion == 15) { @@ -1326,7 +1326,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, ostr << "../" << mit->first.c_str(); } copyFilesBuildPhase->AddAttribute("dstPath", - this->CreateString(ostr.str().c_str())); + this->CreateString(ostr.str())); copyFilesBuildPhase->AddAttribute( "runOnlyForDeploymentPostprocessing", this->CreateString("0")); buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); @@ -1752,7 +1752,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, (makefile+"$CONFIGURATION").c_str()); makecmd += " all"; buildphase->AddAttribute("shellScript", - this->CreateString(makecmd.c_str())); + this->CreateString(makecmd)); buildphase->AddAttribute("showEnvVarsInLog", this->CreateString("0")); } @@ -2021,7 +2021,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, if(archs.size() == 1) { buildSettings->AddAttribute("ARCHS", - this->CreateString(archs[0].c_str())); + this->CreateString(archs[0])); } else { @@ -2030,7 +2030,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, for(std::vector<std::string>::iterator i = archs.begin(); i != archs.end(); i++) { - archObjects->AddObject(this->CreateString((*i).c_str())); + archObjects->AddObject(this->CreateString(*i)); } buildSettings->AddAttribute("ARCHS", archObjects); } @@ -2081,13 +2081,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { std::string pncdir = gtgt->GetDirectory(configName); buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR", - this->CreateString(pncdir.c_str())); + this->CreateString(pncdir)); } } else { buildSettings->AddAttribute("OBJROOT", - this->CreateString(pndir.c_str())); + this->CreateString(pndir)); pndir = gtgt->GetDirectory(configName); } @@ -2097,9 +2097,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, } buildSettings->AddAttribute("EXECUTABLE_PREFIX", - this->CreateString(pnprefix.c_str())); + this->CreateString(pnprefix)); buildSettings->AddAttribute("EXECUTABLE_SUFFIX", - this->CreateString(pnsuffix.c_str())); + this->CreateString(pnsuffix)); } else if(gtgt->GetType() == cmState::OBJECT_LIBRARY) { @@ -2112,12 +2112,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, std::string pncdir = this->GetObjectsNormalDirectory( this->CurrentProject, configName, gtgt); buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR", - this->CreateString(pncdir.c_str())); + this->CreateString(pncdir)); } else { buildSettings->AddAttribute("OBJROOT", - this->CreateString(pndir.c_str())); + this->CreateString(pndir)); pndir = this->GetObjectsNormalDirectory( this->CurrentProject, configName, gtgt); } @@ -2125,9 +2125,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, // Store the product name for all target types. buildSettings->AddAttribute("PRODUCT_NAME", - this->CreateString(realName.c_str())); + this->CreateString(realName)); buildSettings->AddAttribute("SYMROOT", - this->CreateString(pndir.c_str())); + this->CreateString(pndir)); // Handle settings for each target type. switch(gtgt->GetType()) @@ -2203,7 +2203,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { std::string fw_version = gtgt->GetFrameworkVersion(); buildSettings->AddAttribute("FRAMEWORK_VERSION", - this->CreateString(fw_version.c_str())); + this->CreateString(fw_version)); std::string plist = this->ComputeInfoPListLocation(gtgt); // Xcode will create the final version of Info.plist at build time, @@ -2282,17 +2282,17 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { std::string frameworkDir = *i; frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str()); + frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); if(emitted.insert(frameworkDir).second) { - fdirs.Add(this->XCodeEscapePath(frameworkDir.c_str()).c_str()); + fdirs.Add(this->XCodeEscapePath(frameworkDir)); } } else { std::string incpath = - this->XCodeEscapePath(i->c_str()); - dirs.Add(incpath.c_str()); + this->XCodeEscapePath(*i); + dirs.Add(incpath); } } // Add framework search paths needed for linking. @@ -2304,7 +2304,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { if(emitted.insert(*fdi).second) { - fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str()); + fdirs.Add(this->XCodeEscapePath(*fdi)); } } } @@ -2390,17 +2390,17 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, if (*li == "CXX") { buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS", - this->CreateString(flags.c_str())); + this->CreateString(flags)); } else if (*li == "Fortran") { buildSettings->AddAttribute("IFORT_OTHER_FLAGS", - this->CreateString(flags.c_str())); + this->CreateString(flags)); } else if (*li == "C") { buildSettings->AddAttribute("OTHER_CFLAGS", - this->CreateString(flags.c_str())); + this->CreateString(flags)); } } @@ -2444,11 +2444,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { install_name_dir = ""; extraLinkOptions += " -install_name "; - extraLinkOptions += XCodeEscapePath(install_name.c_str()); + extraLinkOptions += XCodeEscapePath(install_name); } } buildSettings->AddAttribute("INSTALL_PATH", - this->CreateString(install_name_dir.c_str())); + this->CreateString(install_name_dir)); // Create the LD_RUNPATH_SEARCH_PATHS cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName); @@ -2473,18 +2473,18 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, { search_paths += " "; } - search_paths += this->XCodeEscapePath(runpath.c_str()); + search_paths += this->XCodeEscapePath(runpath); } } if(!search_paths.empty()) { buildSettings->AddAttribute("LD_RUNPATH_SEARCH_PATHS", - this->CreateString(search_paths.c_str())); + this->CreateString(search_paths)); } } buildSettings->AddAttribute(this->GetTargetLinkFlagsVar(gtgt), - this->CreateString(extraLinkOptions.c_str())); + this->CreateString(extraLinkOptions)); buildSettings->AddAttribute("OTHER_REZFLAGS", this->CreateString("")); buildSettings->AddAttribute("SECTORDER_FLAGS", @@ -2525,7 +2525,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, v << major << "." << minor << "." << patch; } buildSettings->AddAttribute("DYLIB_CURRENT_VERSION", - this->CreateString(v.str().c_str())); + this->CreateString(v.str())); // SOVERSION -> compatibility_version gtgt->GetTargetVersion(true, major, minor, patch); @@ -2537,7 +2537,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, vso << major << "." << minor << "." << patch; } buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION", - this->CreateString(vso.str().c_str())); + this->CreateString(vso.str())); } // put this last so it can override existing settings // Convert "XCODE_ATTRIBUTE_*" properties directly. @@ -2674,14 +2674,14 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target, this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); this->CreateBuildSettings(gtgt, buildSettings, configVector[i].c_str()); - config->AddAttribute("name", this->CreateString(configVector[i].c_str())); + config->AddAttribute("name", this->CreateString(configVector[i])); config->SetComment(configVector[i].c_str()); config->AddAttribute("buildSettings", buildSettings); } if(!configVector.empty()) { configlist->AddAttribute("defaultConfigurationName", - this->CreateString(configVector[0].c_str())); + this->CreateString(configVector[0])); configlist->AddAttribute("defaultConfigurationIsVisible", this->CreateString("0")); return configVector[0]; @@ -2813,7 +2813,7 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmGeneratorTarget* gtgt, { fullName = gtgt->GetFullName(defConfig.c_str()); } - fileRef->AddAttribute("path", this->CreateString(fullName.c_str())); + fileRef->AddAttribute("path", this->CreateString(fullName)); if(this->XcodeVersion == 15) { fileRef->AddAttribute("refType", this->CreateString("0")); @@ -3021,7 +3021,7 @@ void cmGlobalXCodeGenerator { linkObjs += sep; sep = " "; - linkObjs += this->XCodeEscapePath(oi->c_str()); + linkObjs += this->XCodeEscapePath(*oi); } this->AppendBuildSettingAttribute( target, this->GetTargetLinkFlagsVar(gt), @@ -3068,10 +3068,10 @@ void cmGlobalXCodeGenerator // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it: linkDirs += " "; linkDirs += this->XCodeEscapePath( - (*libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)").c_str()); + *libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"); } linkDirs += " "; - linkDirs += this->XCodeEscapePath(libDir->c_str()); + linkDirs += this->XCodeEscapePath(*libDir); } } this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS", @@ -3091,7 +3091,7 @@ void cmGlobalXCodeGenerator sep = " "; if(li->IsPath) { - linkLibs += this->XCodeEscapePath(li->Value.c_str()); + linkLibs += this->XCodeEscapePath(li->Value); } else if (!li->Target || li->Target->GetType() != cmState::INTERFACE_LIBRARY) @@ -3200,7 +3200,7 @@ cmXCodeObject *cmGlobalXCodeGenerator cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup); cmXCodeObject* groupChildren = this->CreateObject(cmXCodeObject::OBJECT_LIST); - group->AddAttribute("name", this->CreateString(name.c_str())); + group->AddAttribute("name", this->CreateString(name)); group->AddAttribute("children", groupChildren); if(this->XcodeVersion == 15) { @@ -3447,7 +3447,7 @@ bool cmGlobalXCodeGenerator std::string pdir = this->RelativeToBinary(root->GetCurrentSourceDirectory()); this->RootObject->AddAttribute("projectDirPath", - this->CreateString(pdir.c_str())); + this->CreateString(pdir)); this->RootObject->AddAttribute("projectRoot", this->CreateString("")); } cmXCodeObject* configlist = @@ -3528,7 +3528,7 @@ bool cmGlobalXCodeGenerator else { // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO). - buildSettings->AddAttribute("ARCHS", this->CreateString(archs.c_str())); + buildSettings->AddAttribute("ARCHS", this->CreateString(archs)); } if(deploymentTarget && *deploymentTarget) { @@ -3538,12 +3538,12 @@ bool cmGlobalXCodeGenerator if(!this->GeneratorToolset.empty()) { buildSettings->AddAttribute("GCC_VERSION", - this->CreateString(this->GeneratorToolset.c_str())); + this->CreateString(this->GeneratorToolset)); } std::string symroot = root->GetCurrentBinaryDirectory(); symroot += "/build"; - buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot.c_str())); + buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot)); for(Configs::iterator i = configs.begin(); i != configs.end(); ++i) { @@ -3932,17 +3932,16 @@ std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p) } //---------------------------------------------------------------------------- -std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p) +std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p) { - std::string ret = p; - if(ret.find(' ') != ret.npos) + if(p.find(' ') != p.npos) { - std::string t = ret; - ret = "\""; - ret += t; - ret += "\""; + std::string t = "\""; + t += p; + t += "\""; + return t; } - return ret; + return p; } //---------------------------------------------------------------------------- @@ -4025,7 +4024,7 @@ cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs, // Append the flag with needed escapes. std::string tmp; this->AppendFlag(tmp, def); - defs.Add(tmp.c_str()); + defs.Add(tmp); } } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 862746f..f7bfb26 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -96,7 +96,7 @@ private: bool CreateGroups(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); - std::string XCodeEscapePath(const char* p); + std::string XCodeEscapePath(const std::string& p); std::string RelativeToSource(const char* p); std::string RelativeToBinary(const char* p); std::string ConvertToRelativeForMake(const char* p); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 3a56c2a..f01ff74 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1824,10 +1824,11 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, cmState::CacheEntryType type, bool force) { - bool haveVal = value ? true : false; - std::string val = haveVal ? value : ""; const char* existingValue = this->GetState()->GetInitializedCacheValue(name); + // must be outside the following if() to keep it alive long enough + std::string nvalue; + if(existingValue && (this->GetState()->GetCacheEntryType(name) == cmState::UNINITIALIZED)) @@ -1836,15 +1837,16 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, // if it is a force, then use the value being passed in if(!force) { - val = existingValue; - haveVal = true; + value = existingValue; } if ( type == cmState::PATH || type == cmState::FILEPATH ) { std::vector<std::string>::size_type cc; std::vector<std::string> files; - std::string nvalue = ""; - cmSystemTools::ExpandListArgument(val, files); + nvalue = value ? value : ""; + + cmSystemTools::ExpandListArgument(nvalue, files); + nvalue = ""; for ( cc = 0; cc < files.size(); cc ++ ) { if(!cmSystemTools::IsOff(files[cc].c_str())) @@ -1859,13 +1861,12 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, } this->GetCMakeInstance()->AddCacheEntry(name, nvalue.c_str(), doc, type); - val = this->GetState()->GetInitializedCacheValue(name); - haveVal = true; + nvalue = this->GetState()->GetInitializedCacheValue(name); + value = nvalue.c_str(); } } - this->GetCMakeInstance()->AddCacheEntry(name, haveVal ? val.c_str() : 0, - doc, type); + this->GetCMakeInstance()->AddCacheEntry(name, value, doc, type); // if there was a definition then remove it this->StateSnapshot.RemoveDefinition(name); } diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 4cab81f..9b2362a 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -25,6 +25,87 @@ # include "cmGlobalVisualStudioGenerator.h" #endif +static std::string GetAutogenTargetName( + cmGeneratorTarget const* target) +{ + std::string autogenTargetName = target->GetName(); + autogenTargetName += "_automoc"; + return autogenTargetName; +} + +static std::string GetAutogenTargetDir( + cmGeneratorTarget const* target) +{ + cmMakefile* makefile = target->Target->GetMakefile(); + std::string targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + targetDir += ".dir/"; + return targetDir; +} + +static std::string GetAutogenTargetBuildDir( + cmGeneratorTarget const* target) +{ + cmMakefile* makefile = target->Target->GetMakefile(); + std::string targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + targetDir += ".dir/"; + return targetDir; +} + +static std::string GetSourceRelativePath( + cmGeneratorTarget const* target, + const std::string& fileName) +{ + std::string pathRel; + // Test if the file is child to any of the known directories + { + const std::string fileNameReal = cmsys::SystemTools::GetRealPath(fileName); + std::string parentDirectory; + bool match ( false ); + { + std::string testDirs[4]; + { + cmMakefile* makefile = target->Target->GetMakefile(); + testDirs[0] = makefile->GetCurrentSourceDirectory(); + testDirs[1] = makefile->GetCurrentBinaryDirectory(); + testDirs[2] = makefile->GetHomeDirectory(); + testDirs[3] = makefile->GetHomeOutputDirectory(); + } + for(int ii=0; ii != sizeof(testDirs)/sizeof(std::string); ++ii ) + { + const ::std::string testDir = cmsys::SystemTools::GetRealPath( + testDirs[ii]); + if (!testDir.empty() + && cmsys::SystemTools::IsSubDirectory(fileNameReal, testDir) ) + { + parentDirectory = testDir; + match = true; + break; + } + } + } + // Use root as fallback parent directory + if (!match) + { + cmsys::SystemTools::SplitPathRootComponent(fileNameReal, + &parentDirectory); + } + pathRel = cmsys::SystemTools::RelativePath( + parentDirectory, cmsys::SystemTools::GetParentDirectory(fileNameReal)); + } + // Sanitize relative path + if (!pathRel.empty()) + { + pathRel += '/'; + cmSystemTools::ReplaceString(pathRel, "..", "__"); + } + return pathRel; +} + static void SetupSourceFiles(cmGeneratorTarget const* target, std::vector<std::string>& skipMoc, std::vector<std::string>& mocSources, @@ -61,13 +142,16 @@ static void SetupSourceFiles(cmGeneratorTarget const* target, if (ext == "qrc" && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { + + std::string rcc_output_dir = GetAutogenTargetBuildDir(target); + rcc_output_dir += GetSourceRelativePath(target,absFile); + cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); + std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(absFile); - std::string rcc_output_dir = target->GetSupportDirectory(); - cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); std::string rcc_output_file = rcc_output_dir; - rcc_output_file += "/qrc_" + basename + ".cpp"; + rcc_output_file += "qrc_" + basename + ".cpp"; makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", rcc_output_file.c_str(), false); makefile->GetOrCreateSource(rcc_output_file, true); @@ -433,26 +517,6 @@ static void MergeRccOptions(std::vector<std::string> &opts, opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); } -std::string GetAutogenTargetName( - cmGeneratorTarget const* target) -{ - std::string autogenTargetName = target->GetName(); - autogenTargetName += "_automoc"; - return autogenTargetName; -} - -std::string GetAutogenTargetDir( - cmGeneratorTarget const* target) -{ - cmMakefile* makefile = target->Target->GetMakefile(); - std::string targetDir = makefile->GetCurrentBinaryDirectory(); - targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); - targetDir += "/"; - targetDir += GetAutogenTargetName(target); - targetDir += ".dir/"; - return targetDir; -} - static void copyTargetProperty(cmTarget* destinationTarget, cmTarget* sourceTarget, const std::string& propertyName) @@ -528,8 +592,10 @@ static std::string ListQt5RccInputs(cmSourceFile* sf, &retVal, 0, cmSystemTools::OUTPUT_NONE); if (!result || retVal) { - std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath() - << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl; + std::stringstream err; + err << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath() + << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl; + std::cerr << err.str(); return std::string(); } @@ -559,8 +625,10 @@ static std::string ListQt5RccInputs(cmSourceFile* sf, std::string::size_type pos = eline.find(searchString); if (pos == std::string::npos) { - std::cerr << "AUTOGEN: error: Rcc lists unparsable output " - << eline << std::endl; + std::stringstream err; + err << "AUTOGEN: error: Rcc lists unparsable output " + << eline << std::endl; + std::cerr << err.str(); return std::string(); } pos += searchString.length(); @@ -858,14 +926,18 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( if (ext == "qrc" && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { - std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(absFile); - - std::string rcc_output_dir = target->GetSupportDirectory(); - cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); - std::string rcc_output_file = rcc_output_dir; - rcc_output_file += "/qrc_" + basename + ".cpp"; - rcc_output.push_back(rcc_output_file); + + { + std::string rcc_output_dir = GetAutogenTargetBuildDir(target); + rcc_output_dir += GetSourceRelativePath(target,absFile); + cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFile); + std::string rcc_output_file = rcc_output_dir; + rcc_output_file += "qrc_" + basename + ".cpp"; + rcc_output.push_back(rcc_output_file); + } if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index ebe08b0..07fc239 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -410,9 +410,12 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile( void cmQtAutoGenerators::Init() { - this->OutMocCppFilename = this->Builddir; - this->OutMocCppFilename += this->TargetName; - this->OutMocCppFilename += ".cpp"; + this->TargetBuildSubDir = this->TargetName; + this->TargetBuildSubDir += ".dir/"; + + this->OutMocCppFilenameRel = this->TargetName; + this->OutMocCppFilenameRel += ".cpp"; + this->OutMocCppFilenameAbs = this->Builddir + this->OutMocCppFilenameRel; std::vector<std::string> cdefList; cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); @@ -464,7 +467,7 @@ void cmQtAutoGenerators::Init() std::list<std::string>::iterator it = this->MocIncludes.begin(); while (it != this->MocIncludes.end()) { - if (this->StartsWith(*it, binDir)) + if (cmsys::SystemTools::StringStartsWith(*it, binDir.c_str())) { sortedMocIncludes.push_back(*it); it = this->MocIncludes.erase(it); @@ -477,7 +480,7 @@ void cmQtAutoGenerators::Init() it = this->MocIncludes.begin(); while (it != this->MocIncludes.end()) { - if (this->StartsWith(*it, srcDir)) + if (cmsys::SystemTools::StringStartsWith(*it, srcDir.c_str())) { sortedMocIncludes.push_back(*it); it = this->MocIncludes.erase(it); @@ -505,7 +508,7 @@ static std::string ReadAll(const std::string& filename) bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) { - if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) + if (!cmsys::SystemTools::FileExists(this->OutMocCppFilenameAbs.c_str()) || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) { this->GenerateAll = true; @@ -546,7 +549,9 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) const std::string &absFilename = *it; if (this->Verbose) { - std::cout << "AUTOGEN: Checking " << absFilename << std::endl; + std::stringstream err; + err << "AUTOGEN: Checking " << absFilename << std::endl; + this->LogInfo(err.str()); } if (this->RelaxedMode) { @@ -574,7 +579,9 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) const std::string &absFilename = *it; if (this->Verbose) { - std::cout << "AUTOGEN: Checking " << absFilename << std::endl; + std::stringstream err; + err << "AUTOGEN: Checking " << absFilename << std::endl; + this->LogInfo(err.str()); } this->ParseForUic(absFilename, includedUis); } @@ -589,93 +596,37 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) std::map<std::string, std::string> notIncludedMocs; this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs, includedUis); - // run moc on all the moc's that are #included in source files - for(std::map<std::string, std::string>::const_iterator - it = includedMocs.begin(); - it != includedMocs.end(); - ++it) + if(!this->MocExecutable.empty()) { - this->GenerateMoc(it->first, it->second); + this->GenerateMocFiles ( includedMocs, notIncludedMocs ); } - for(std::map<std::string, std::vector<std::string> >::const_iterator - it = includedUis.begin(); - it != includedUis.end(); - ++it) + if(!this->UicExecutable.empty()) { - for (std::vector<std::string>::const_iterator nit = it->second.begin(); - nit != it->second.end(); - ++nit) - { - this->GenerateUi(it->first, *nit); - } + this->GenerateUiFiles ( includedUis ); } - if(!this->RccExecutable.empty()) { - this->GenerateQrc(); - } - - std::stringstream outStream; - outStream << "/* This file is autogenerated, do not edit*/\n"; - - bool automocCppChanged = false; - if (notIncludedMocs.empty()) - { - outStream << "enum some_compilers { need_more_than_nothing };\n"; - } - else - { - // run moc on the remaining headers and include them in - // the _automoc.cpp file - for(std::map<std::string, std::string>::const_iterator - it = notIncludedMocs.begin(); - it != notIncludedMocs.end(); - ++it) - { - bool mocSuccess = this->GenerateMoc(it->first, it->second); - if (mocSuccess) - { - automocCppChanged = true; - } - outStream << "#include \"" << it->second << "\"\n"; - } + this->GenerateQrcFiles(); } if (this->RunMocFailed) { - std::cerr << "moc failed..." << std::endl; + std::stringstream err; err << "moc failed..." << std::endl; + this->LogError(err.str()); return false; } - if (this->RunUicFailed) { - std::cerr << "uic failed..." << std::endl; + std::stringstream err; err << "uic failed..." << std::endl; + this->LogError(err.str()); return false; } if (this->RunRccFailed) { - std::cerr << "rcc failed..." << std::endl; + std::stringstream err; err << "rcc failed..." << std::endl; + this->LogError(err.str()); return false; } - outStream.flush(); - std::string automocSource = outStream.str(); - if (!automocCppChanged) - { - // compare contents of the _automoc.cpp file - const std::string oldContents = ReadAll(this->OutMocCppFilename); - if (oldContents == automocSource) - { - // nothing changed: don't touch the _automoc.cpp file - return true; - } - } - - // source file that includes all remaining moc files (_automoc.cpp file) - cmsys::ofstream outfile; - outfile.open(this->OutMocCppFilename.c_str(), - std::ios::trunc); - outfile << automocSource; - outfile.close(); return true; } @@ -693,8 +644,10 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, const std::string contentsString = ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": file is empty\n" + << std::endl; + this->LogError(err.str()); return; } this->ParseForUic(absFilename, contentsString, includedUis); @@ -726,7 +679,6 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, do { const std::string currentMoc = mocIncludeRegExp.match(1); - //std::cout << "found moc include: " << currentMoc << std::endl; std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(currentMoc); @@ -759,20 +711,21 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, } else { - std::cerr << "AUTOGEN: error: " << absFilename << ": The file " - << "includes the moc file \"" << currentMoc << "\", " - << "but could not find header \"" << basename - << '{' << this->Join(headerExtensions, ',') << "}\" "; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << ": The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->JoinExts(headerExtensions) << "}\" "; if (mocSubDir.empty()) { - std::cerr << "in " << absPath << "\n" << std::endl; + err << "in " << absPath << "\n" << std::endl; } else { - std::cerr << "neither in " << absPath - << " nor in " << mocSubDir << "\n" << std::endl; + err << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; } - + this->LogError(err.str()); ::exit(EXIT_FAILURE); } } @@ -790,34 +743,40 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, fileToMoc = headerToMoc; if ((requiresMoc==false) &&(basename==scannedFileBasename)) { - std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " - "includes the moc file \"" << currentMoc << - "\", but does not contain a " << macroName - << " macro. Running moc on " - << "\"" << headerToMoc << "\" ! Include \"moc_" - << basename << ".cpp\" for a compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", but does not contain a " << macroName + << " macro. Running moc on " + << "\"" << headerToMoc << "\" ! Include \"moc_" + << basename << ".cpp\" for a compatibility with " + "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" + << std::endl; + this->LogError(err.str()); } else { - std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " - "includes the moc file \"" << currentMoc << - "\" instead of \"moc_" << basename << ".cpp\". " - "Running moc on " - << "\"" << headerToMoc << "\" ! Include \"moc_" - << basename << ".cpp\" for compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\" instead of \"moc_" << basename << ".cpp\". " + "Running moc on " + << "\"" << headerToMoc << "\" ! Include \"moc_" + << basename << ".cpp\" for compatibility with " + "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" + << std::endl; + this->LogError(err.str()); } } else { - std::cerr <<"AUTOGEN: error: " << absFilename << ": The file " - "includes the moc file \"" << currentMoc << - "\", which seems to be the moc file from a different " - "source file. CMake also could not find a matching " - "header.\n" << std::endl; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. CMake also could not find a matching " + "header.\n" << std::endl; + this->LogError(err.str()); ::exit(EXIT_FAILURE); } } @@ -841,27 +800,33 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, if (mocUnderscoreIncluded == true) { // this is for KDE4 compatibility: - std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " - << "contains a " << macroName << " macro, but does not " - "include " - << "\"" << scannedFileBasename << ".moc\", but instead " - "includes " - << "\"" << ownMocUnderscoreFile << "\". Running moc on " - << "\"" << absFilename << "\" ! Better include \"" - << scannedFileBasename << ".moc\" for compatibility with " - "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": The file " + << "contains a " << macroName << " macro, but does not " + "include " + << "\"" << scannedFileBasename << ".moc\", but instead " + "includes " + << "\"" << ownMocUnderscoreFile << "\". Running moc on " + << "\"" << absFilename << "\" ! Better include \"" + << scannedFileBasename << ".moc\" for compatibility with " + "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n" + << std::endl; + this->LogError(err.str()); + includedMocs[absFilename] = ownMocUnderscoreFile; includedMocs.erase(ownMocHeaderFile); } else { // otherwise always error out since it will not compile: - std::cerr << "AUTOGEN: error: " << absFilename << ": The file " - << "contains a " << macroName << " macro, but does not " - "include " - << "\"" << scannedFileBasename << ".moc\" !\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << ": The file " + << "contains a " << macroName << " macro, but does not " + "include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + this->LogError(err.str()); + ::exit(EXIT_FAILURE); } } @@ -881,8 +846,10 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, const std::string contentsString = ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": file is empty\n" + << std::endl; + this->LogError(err.str()); return; } this->ParseForUic(absFilename, contentsString, includedUis); @@ -934,20 +901,21 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, } else { - std::cerr << "AUTOGEN: error: " << absFilename << " The file " - << "includes the moc file \"" << currentMoc << "\", " - << "but could not find header \"" << basename - << '{' << this->Join(headerExtensions, ',') << "}\" "; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << " The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->JoinExts(headerExtensions) << "}\" "; if (mocSubDir.empty()) { - std::cerr << "in " << absPath << "\n" << std::endl; + err << "in " << absPath << "\n" << std::endl; } else { - std::cerr << "neither in " << absPath - << " nor in " << mocSubDir << "\n" << std::endl; + err << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; } - + this->LogError(err.str()); ::exit(EXIT_FAILURE); } } @@ -955,12 +923,14 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, { if (basename != scannedFileBasename) { - std::cerr <<"AUTOGEN: error: " << absFilename << ": The file " - "includes the moc file \"" << currentMoc << - "\", which seems to be the moc file from a different " - "source file. This is not supported. " - "Include \"" << scannedFileBasename << ".moc\" to run " - "moc on this source file.\n" << std::endl; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. This is not supported. " + "Include \"" << scannedFileBasename << ".moc\" to run " + "moc on this source file.\n" << std::endl; + this->LogError(err.str()); ::exit(EXIT_FAILURE); } dotMocIncluded = true; @@ -979,10 +949,12 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, macroName))) { // otherwise always error out since it will not compile: - std::cerr << "AUTOGEN: error: " << absFilename << ": The file " - << "contains a " << macroName << " macro, but does not include " - << "\"" << scannedFileBasename << ".moc\" !\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: error: " << absFilename << ": The file " + << "contains a " << macroName << " macro, but does not include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + this->LogError(err.str()); ::exit(EXIT_FAILURE); } @@ -999,8 +971,10 @@ void cmQtAutoGenerators::ParseForUic(const std::string& absFilename, const std::string contentsString = ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" - << std::endl; + std::stringstream err; + err << "AUTOGEN: warning: " << absFilename << ": file is empty\n" + << std::endl; + this->LogError(err.str()); return; } this->ParseForUic(absFilename, contentsString, includedUis); @@ -1101,17 +1075,19 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders, { if (this->Verbose) { - std::cout << "AUTOGEN: Checking " << headerName << std::endl; + std::stringstream err; + err << "AUTOGEN: Checking " << headerName << std::endl; + this->LogInfo(err.str()); } - const std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(headerName); - - const std::string currentMoc = "moc_" + basename + ".cpp"; std::string macroName; if (requiresMocing(contents, macroName)) { - //std::cout << "header contains Q_OBJECT macro"; + const std::string parentDir = this->TargetBuildSubDir + + this->SourceRelativePath ( headerName ); + const std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(headerName); + const std::string currentMoc = parentDir + "moc_" + basename + ".cpp"; notIncludedMocs[headerName] = currentMoc; } } @@ -1119,6 +1095,125 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders, } } + +bool cmQtAutoGenerators::GenerateMocFiles( + const std::map<std::string, std::string>& includedMocs, + const std::map<std::string, std::string>& notIncludedMocs ) +{ + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + // Test merged map of included and notIncluded + std::map<std::string, std::string> mergedMocs ( includedMocs ); + mergedMocs.insert ( notIncludedMocs.begin(), notIncludedMocs.end() ); + if( this->NameCollisionTest ( mergedMocs, collisions ) ) + { + std::stringstream err; + err << + "AUTOGEN: error: " + "The same moc file will be generated " + "from different sources." << std::endl << + "To avoid this error either" << std::endl << + "- rename the source files or" << std::endl << + "- do not include the (moc_NAME.cpp|NAME.moc) file" << std::endl; + this->NameCollisionLog ( err.str(), collisions ); + ::exit(EXIT_FAILURE); + } + } + + // generate moc files that are included by source files. + for(std::map<std::string, std::string>::const_iterator + it = includedMocs.begin(); it != includedMocs.end(); ++it) + { + if (!this->GenerateMoc(it->first, it->second)) + { + if (this->RunMocFailed) + { + return false; + } + } + } + + // generate moc files that are _not_ included by source files. + bool automocCppChanged = false; + for(std::map<std::string, std::string>::const_iterator + it = notIncludedMocs.begin(); it != notIncludedMocs.end(); ++it) + { + if (this->GenerateMoc(it->first, it->second)) + { + automocCppChanged = true; + } + else + { + if (this->RunMocFailed) + { + return false; + } + } + } + + // compose _automoc.cpp content + std::string automocSource; + { + std::stringstream outStream; + outStream << "/* This file is autogenerated, do not edit*/\n"; + if( notIncludedMocs.empty() ) + { + outStream << "enum some_compilers { need_more_than_nothing };\n"; + } + else + { + for(std::map<std::string, std::string>::const_iterator + it = notIncludedMocs.begin(); + it != notIncludedMocs.end(); + ++it) + { + outStream << "#include \"" << it->second << "\"\n"; + } + } + outStream.flush(); + automocSource = outStream.str(); + } + + // check if we even need to update _automoc.cpp + if (!automocCppChanged) + { + // compare contents of the _automoc.cpp file + const std::string oldContents = ReadAll(this->OutMocCppFilenameAbs); + if (oldContents == automocSource) + { + // nothing changed: don't touch the _automoc.cpp file + if (this->Verbose) + { + std::stringstream err; + err << "AUTOGEN: " << this->OutMocCppFilenameRel + << " still up to date" << std::endl; + this->LogInfo(err.str()); + } + return true; + } + } + + // actually write _automoc.cpp + { + std::string msg = "Generating moc compilation "; + msg += this->OutMocCppFilenameRel; + cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue + |cmsysTerminal_Color_ForegroundBold, + msg.c_str(), true, this->ColorOutput); + } + { + cmsys::ofstream outfile; + outfile.open(this->OutMocCppFilenameAbs.c_str(), + std::ios::trunc); + outfile << automocSource; + outfile.close(); + } + + return true; +} + + bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, const std::string& mocFileName) { @@ -1136,7 +1231,7 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, cmsys::SystemTools::MakeDirectory(mocDir.c_str()); } - std::string msg = "Generating "; + std::string msg = "Generating moc source "; msg += mocFileName; cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |cmsysTerminal_Color_ForegroundBold, @@ -1159,13 +1254,7 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, if (this->Verbose) { - for(std::vector<std::string>::const_iterator cmdIt = command.begin(); - cmdIt != command.end(); - ++cmdIt) - { - std::cout << *cmdIt << " "; - } - std::cout << std::endl; + this->LogCommand(command); } std::string output; @@ -1174,8 +1263,10 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, &retVal); if (!result || retVal) { - std::cerr << "AUTOGEN: error: process for " << mocFilePath <<" failed:\n" - << output << std::endl; + std::stringstream err; + err << "AUTOGEN: error: process for " << mocFilePath <<" failed:\n" + << output << std::endl; + this->LogError(err.str()); this->RunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath); } @@ -1184,28 +1275,91 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, return false; } + +bool cmQtAutoGenerators::GenerateUiFiles( + const std::map<std::string, std::vector<std::string> >& includedUis ) +{ + // 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 = includedUis.begin(); it != includedUis.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::multimap<std::string, std::string> collisions; + if( this->NameCollisionTest ( testMap, collisions ) ) + { + std::stringstream err; + err << "AUTOGEN: error: The same ui_NAME.h file will be generated " + "from different sources." << std::endl + << "To avoid this error rename the source files." << std::endl; + this->NameCollisionLog ( err.str(), collisions ); + ::exit(EXIT_FAILURE); + } + } + 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) + { + for(std::map<std::string, std::string>::const_iterator + sit = it->second.begin(); + sit != it->second.end(); + ++sit) + { + if (!this->GenerateUi(it->first, sit->first, sit->second) ) + { + if (this->RunUicFailed) + { + return false; + } + } + } + } + + return true; +} + + bool cmQtAutoGenerators::GenerateUi(const std::string& realName, - const std::string& uiFileName) + const std::string& uiInputFile, + const std::string& uiOutputFile) { if (!cmsys::SystemTools::FileExists(this->Builddir.c_str(), false)) { cmsys::SystemTools::MakeDirectory(this->Builddir.c_str()); } - const std::string path = cmsys::SystemTools::GetFilenamePath( - realName) + '/'; - - std::string ui_output_file = "ui_" + uiFileName + ".h"; - std::string ui_input_file = path + uiFileName + ".ui"; + const ::std::string uiBuildFile = this->Builddir + uiOutputFile; int sourceNewerThanUi = 0; - bool success = cmsys::SystemTools::FileTimeCompare(ui_input_file, - this->Builddir + ui_output_file, + bool success = cmsys::SystemTools::FileTimeCompare(uiInputFile, + uiBuildFile, &sourceNewerThanUi); if (this->GenerateAll || !success || sourceNewerThanUi >= 0) { - std::string msg = "Generating "; - msg += ui_output_file; + std::string msg = "Generating ui header "; + msg += uiOutputFile; cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |cmsysTerminal_Color_ForegroundBold, msg.c_str(), true, this->ColorOutput); @@ -1215,7 +1369,7 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName, std::vector<std::string> opts = this->UicTargetOptions; std::map<std::string, std::string>::const_iterator optionIt - = this->UicOptions.find(ui_input_file); + = this->UicOptions.find(uiInputFile); if (optionIt != this->UicOptions.end()) { std::vector<std::string> fileOpts; @@ -1226,18 +1380,12 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName, command.insert(command.end(), opts.begin(), opts.end()); command.push_back("-o"); - command.push_back(this->Builddir + ui_output_file); - command.push_back(ui_input_file); + command.push_back(uiBuildFile); + command.push_back(uiInputFile); if (this->Verbose) { - for(std::vector<std::string>::const_iterator cmdIt = command.begin(); - cmdIt != command.end(); - ++cmdIt) - { - std::cout << *cmdIt << " "; - } - std::cout << std::endl; + this->LogCommand(command); } std::string output; int retVal = 0; @@ -1245,11 +1393,13 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName, &retVal); if (!result || retVal) { - std::cerr << "AUTOUIC: error: process for " << ui_output_file << - " needed by\n \"" << realName << "\"\nfailed:\n" << output - << std::endl; + std::stringstream err; + err << "AUTOUIC: error: process for " << uiOutputFile << + " needed by\n \"" << realName << "\"\nfailed:\n" << output + << std::endl; + this->LogError(err.str()); this->RunUicFailed = true; - cmSystemTools::RemoveFile(ui_output_file); + cmSystemTools::RemoveFile(uiOutputFile); return false; } return true; @@ -1276,79 +1426,251 @@ bool cmQtAutoGenerators::InputFilesNewerThanQrc(const std::string& qrcFile, return false; } -bool cmQtAutoGenerators::GenerateQrc() +bool cmQtAutoGenerators::GenerateQrcFiles() { + // generate single map with input / output names + std::map<std::string, std::string> qrcGenMap; for(std::vector<std::string>::const_iterator si = this->RccSources.begin(); si != this->RccSources.end(); ++si) { - std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si); + const std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si); + if (ext == ".qrc") + { + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(*si); + std::string qrcOutputFile = this->TargetBuildSubDir + + this->SourceRelativePath ( *si ) + + "qrc_" + basename + ".cpp"; + //std::string qrcOutputFile = "CMakeFiles/" + this->OriginTargetName + // + ".dir/qrc_" + basename + ".cpp"; + qrcGenMap[*si] = qrcOutputFile; + } + } - if (ext != ".qrc") + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + if( this->NameCollisionTest ( qrcGenMap, collisions ) ) { - continue; + std::stringstream err; + err << "AUTOGEN: error: The same qrc_NAME.cpp file" + " will be generated from different sources." << std::endl + << "To avoid this error rename the source .qrc files." + << std::endl; + this->NameCollisionLog ( err.str(), collisions ); + ::exit(EXIT_FAILURE); + } + } + + // generate qrc files + for(std::map<std::string, std::string>::const_iterator + si = qrcGenMap.begin(); si != qrcGenMap.end(); ++si) + { + if (!this->GenerateQrc( si->first, si->second)) + { + if (this->RunRccFailed) + { + return false; + } } + } + return true; +} + +bool cmQtAutoGenerators::GenerateQrc ( + const std::string& qrcInputFile, + const std::string& qrcOutputFile ) +{ + std::string relName = this->SourceRelativePath ( qrcInputFile ); + cmSystemTools::ReplaceString(relName, "/", "_"); + relName += cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcInputFile); + + const ::std::string qrcBuildFile = this->Builddir + qrcOutputFile; + + int sourceNewerThanQrc = 0; + bool generateQrc = !cmsys::SystemTools::FileTimeCompare(qrcInputFile, + qrcBuildFile, + &sourceNewerThanQrc); + generateQrc = generateQrc || (sourceNewerThanQrc >= 0); + generateQrc = generateQrc || this->InputFilesNewerThanQrc(qrcInputFile, + qrcBuildFile); + + if (this->GenerateAll || generateQrc) + { + std::string msg = "Generating qrc source "; + msg += qrcOutputFile; + cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue + |cmsysTerminal_Color_ForegroundBold, + msg.c_str(), true, this->ColorOutput); + std::vector<std::string> command; command.push_back(this->RccExecutable); - std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(*si); - - std::string rcc_output_file = this->Builddir - + "CMakeFiles/" + this->OriginTargetName - + ".dir/qrc_" + basename + ".cpp"; + std::map<std::string, std::string>::const_iterator optionIt + = this->RccOptions.find(qrcInputFile); + if (optionIt != this->RccOptions.end()) + { + cmSystemTools::ExpandListArgument(optionIt->second, command); + } - int sourceNewerThanQrc = 0; - bool generateQrc = !cmsys::SystemTools::FileTimeCompare(*si, - rcc_output_file, - &sourceNewerThanQrc); - generateQrc = generateQrc || (sourceNewerThanQrc >= 0); - generateQrc = generateQrc || this->InputFilesNewerThanQrc(*si, - rcc_output_file); + command.push_back("-name"); + command.push_back(relName); + command.push_back("-o"); + command.push_back(qrcBuildFile); + command.push_back(qrcInputFile); - if (this->GenerateAll || generateQrc) + if (this->Verbose) { - std::map<std::string, std::string>::const_iterator optionIt - = this->RccOptions.find(*si); - if (optionIt != this->RccOptions.end()) - { - cmSystemTools::ExpandListArgument(optionIt->second, command); - } + this->LogCommand(command); + } + std::string output; + int retVal = 0; + bool result = cmSystemTools::RunSingleCommand(command, &output, &output, + &retVal); + if (!result || retVal) + { + std::stringstream err; + err << "AUTORCC: error: process for " << qrcOutputFile << + " failed:\n" << output << std::endl; + this->LogError(err.str()); + this->RunRccFailed = true; + cmSystemTools::RemoveFile(qrcBuildFile); + return false; + } + } + return true; +} - command.push_back("-name"); - command.push_back(basename); - command.push_back("-o"); - command.push_back(rcc_output_file); - command.push_back(*si); +std::string cmQtAutoGenerators::SourceRelativePath(const std::string& filename) +{ + std::string pathRel; - if (this->Verbose) + // Test if the file is child to any of the known directories + { + std::string fileNameReal = cmsys::SystemTools::GetRealPath( filename ); + std::string parentDirectory; + bool match ( false ); + { + const ::std::string* testDirs[4]; + testDirs[0] = &(this->Srcdir); + testDirs[1] = &(this->Builddir); + testDirs[2] = &(this->ProjectSourceDir); + testDirs[3] = &(this->ProjectBinaryDir); + for(int ii=0; ii != sizeof(testDirs)/sizeof(const ::std::string*); ++ii ) { - for(std::vector<std::string>::const_iterator cmdIt = command.begin(); - cmdIt != command.end(); - ++cmdIt) + const ::std::string testDir = cmsys::SystemTools::GetRealPath( + *(testDirs[ii])); + if (cmsys::SystemTools::IsSubDirectory(fileNameReal, + testDir) ) { - std::cout << *cmdIt << " "; + parentDirectory = testDir; + match = true; + break; } - std::cout << std::endl; } - std::string output; - int retVal = 0; - bool result = cmSystemTools::RunSingleCommand(command, &output, &output, - &retVal); - if (!result || retVal) + } + // Use root as fallback parent directory + if ( !match ) + { + cmsys::SystemTools::SplitPathRootComponent(fileNameReal, + &parentDirectory); + } + pathRel = cmsys::SystemTools::RelativePath( + parentDirectory, cmsys::SystemTools::GetParentDirectory(fileNameReal)); + } + + // Sanitize relative path + if (!pathRel.empty()) + { + pathRel += '/'; + cmSystemTools::ReplaceString(pathRel, "..", "__"); + } + return pathRel; +} + +/** + * @brief Collects name collisions as output/input pairs + * @return True if there were collisions + */ +bool cmQtAutoGenerators::NameCollisionTest( + const std::map<std::string, std::string >& genFiles, + std::multimap<std::string, std::string>& collisions) +{ + typedef std::map<std::string, std::string>::const_iterator Iter; + typedef std::map<std::string, std::string>::value_type VType; + for(Iter ait = genFiles.begin(); ait != genFiles.end(); ++ait ) + { + bool first_match ( true ); + for (Iter bit = (++Iter(ait)); bit != genFiles.end(); ++bit) + { + if(ait->second == bit->second) { - std::cerr << "AUTORCC: error: process for " << rcc_output_file << - " failed:\n" << output << std::endl; - this->RunRccFailed = true; - cmSystemTools::RemoveFile(rcc_output_file); - return false; + if (first_match) + { + if (collisions.find(ait->second) != collisions.end()) + { + // We already know of this collision from before + break; + } + collisions.insert(VType(ait->second, ait->first)); + first_match = false; + } + collisions.insert(VType(bit->second, bit->first)); } } } - return true; + + return !collisions.empty(); +} + +void cmQtAutoGenerators::NameCollisionLog( + const std::string& message, + const std::multimap<std::string, std::string>& collisions) +{ + typedef std::multimap<std::string, std::string>::const_iterator Iter; + + std::stringstream err; + // Add message + err << message; + // Append collision list + for(Iter it = collisions.begin(); it != collisions.end(); ++it ) + { + err << it->first << " : " << it->second << std::endl; + } + this->LogError(err.str()); +} + +void cmQtAutoGenerators::LogInfo(const std::string& message) +{ + std::cout << message; +} + +void cmQtAutoGenerators::LogError(const std::string& message) +{ + std::cerr << message; +} + +void cmQtAutoGenerators::LogCommand(const std::vector<std::string>& command) +{ + std::stringstream sbuf; + for(std::vector<std::string>::const_iterator cmdIt = command.begin(); + cmdIt != command.end(); + ++cmdIt) + { + if ( cmdIt != command.begin() ) + { + sbuf << " "; + } + sbuf << *cmdIt; + } + if ( !sbuf.str().empty() ) + { + sbuf << std::endl; + this->LogInfo ( sbuf.str() ); + } } -std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst, - char separator) +std::string cmQtAutoGenerators::JoinExts(const std::vector<std::string>& lst) { if (lst.empty()) { @@ -1356,30 +1678,17 @@ std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst, } std::string result; + std::string separator = ","; for (std::vector<std::string>::const_iterator it = lst.begin(); it != lst.end(); ++it) { - result += "." + (*it) + separator; + if(it != lst.begin()) + { + result += separator; + } + result += '.' + (*it); } result.erase(result.end() - 1); return result; } - - -bool cmQtAutoGenerators::StartsWith(const std::string& str, - const std::string& with) -{ - return (str.substr(0, with.length()) == with); -} - - -bool cmQtAutoGenerators::EndsWith(const std::string& str, - const std::string& with) -{ - if (with.length() > (str.length())) - { - return false; - } - return (str.substr(str.length() - with.length(), with.length()) == with); -} diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index ab7b6ed..e46e0fc 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -39,10 +39,19 @@ private: std::string MakeCompileSettingsString(cmMakefile* makefile); bool RunAutogen(cmMakefile* makefile); + bool GenerateMocFiles( + const std::map<std::string, std::string>& includedMocs, + const std::map<std::string, std::string>& notIncludedMocs); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); - bool GenerateUi(const std::string& realName, const std::string& uiFileName); - bool GenerateQrc(); + bool GenerateUiFiles( + const std::map<std::string, std::vector<std::string> >& includedUis ); + bool GenerateUi(const std::string& realName, + const std::string& uiInputFile, + const std::string& uiOutputFile ); + bool GenerateQrcFiles(); + bool GenerateQrc(const std::string& qrcInputFile, + const std::string& qrcOutputFile); void ParseCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs, @@ -69,9 +78,18 @@ private: void Init(); - std::string Join(const std::vector<std::string>& lst, char separator); - bool EndsWith(const std::string& str, const std::string& with); - bool StartsWith(const std::string& str, const std::string& with); + std::string SourceRelativePath(const std::string& filename); + + bool NameCollisionTest(const std::map<std::string, std::string >& genFiles, + std::multimap<std::string, std::string>& collisions ); + void NameCollisionLog( + const std::string& message, + const std::multimap<std::string, std::string>& collisions ); + + void LogInfo(const std::string& message); + void LogError(const std::string& message); + void LogCommand(const std::vector<std::string>& command); + std::string JoinExts(const std::vector<std::string>& lst); static void MergeUicOptions(std::vector<std::string> &opts, const std::vector<std::string> &fileOpts, bool isQt5); @@ -101,7 +119,9 @@ private: std::string CurrentCompileSettingsStr; std::string OldCompileSettingsStr; - std::string OutMocCppFilename; + std::string TargetBuildSubDir; + std::string OutMocCppFilenameRel; + std::string OutMocCppFilenameAbs; std::list<std::string> MocIncludes; std::list<std::string> MocDefinitions; std::vector<std::string> MocOptions; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 3c28c35..0b9518c 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -389,13 +389,17 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) tidy_cmd.push_back("--"); tidy_cmd.insert(tidy_cmd.end(), orig_cmd.begin()+1, orig_cmd.end()); - // Run the tidy command line. - if(!cmSystemTools::RunSingleCommand(tidy_cmd, 0, 0, &ret, 0, - cmSystemTools::OUTPUT_PASSTHROUGH)) + // Run the tidy command line. Capture its stdout and hide its stderr. + std::string stdOut; + if(!cmSystemTools::RunSingleCommand(tidy_cmd, &stdOut, 0, &ret, 0, + cmSystemTools::OUTPUT_NONE)) { std::cerr << "Error running '" << tidy_cmd[0] << "'\n"; return 1; } + + // Output the stdout from clang-tidy to stderr + std::cerr << stdOut; } // Now run the real compiler command and return its result value. |