diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWPackage.cxx | 172 | ||||
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWPackage.h | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestMemCheckHandler.cxx | 12 | ||||
-rw-r--r-- | Source/QtDialog/AddCacheEntry.cxx | 2 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 5 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 2 | ||||
-rw-r--r-- | Source/cmTimestamp.cxx | 11 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 209 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 42 |
16 files changed, 453 insertions, 59 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 89ffb82..8290ba3 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 7) -set(CMake_VERSION_PATCH 20170122) +set(CMake_VERSION_PATCH 20170127) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index c868a14..e23b1b9 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -62,6 +62,13 @@ cmCPackIFWPackage::DependenceStruct::DependenceStruct( } else if ((pos = dependence.find('>')) != std::string::npos) { Compare.Type = CompareGreater; Compare.Value = dependence.substr(pos + 1); + } else if ((pos = dependence.find('-')) != std::string::npos) { + Compare.Type = CompareNone; + Compare.Value = dependence.substr(pos + 1); + } + size_t dashPos = dependence.find('-'); + if (dashPos != std::string::npos) { + pos = dashPos; } Name = pos == std::string::npos ? dependence : dependence.substr(0, pos); } @@ -74,6 +81,10 @@ std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const std::string result = Name; + if (Compare.Type != CompareNone || !Compare.Value.empty()) { + result += "-"; + } + if (Compare.Type == CompareLessOrEqual) { result += "<="; } else if (Compare.Type == CompareGreaterOrEqual) { @@ -154,11 +165,14 @@ void cmCPackIFWPackage::DefaultConfiguration() Script = ""; Licenses.clear(); UserInterfaces.clear(); + Translations.clear(); SortingPriority = ""; + UpdateText = ""; Default = ""; Essential = ""; Virtual = ""; ForcedInstallation = ""; + RequiresAdminRights = ""; } // Defaul configuration (all in one package) @@ -245,24 +259,6 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) } } - // QtIFW dependencies - if (const char* option = this->GetOption(prefix + "DEPENDS")) { - std::vector<std::string> deps; - cmSystemTools::ExpandListArgument(option, deps); - for (std::vector<std::string>::iterator dit = deps.begin(); - dit != deps.end(); ++dit) { - DependenceStruct dep(*dit); - if (!Generator->Packages.count(dep.Name)) { - bool hasDep = Generator->DependentPackages.count(dep.Name) > 0; - DependenceStruct& depRef = Generator->DependentPackages[dep.Name]; - if (!hasDep) { - depRef = dep; - } - AlienDependencies.insert(&depRef); - } - } - } - // Licenses if (const char* option = this->GetOption(prefix + "LICENSES")) { Licenses.clear(); @@ -280,6 +276,11 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) // Priority if (const char* option = this->GetOption(prefix + "PRIORITY")) { SortingPriority = option; + cmCPackLogger( + cmCPackLog::LOG_WARNING, "The \"PRIORITY\" option is set " + << "for component \"" << component->Name << "\", but there option is " + << "deprecated. Please use \"SORTING_PRIORITY\" option instead." + << std::endl); } // Default @@ -352,6 +353,12 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) // Priority if (const char* option = this->GetOption(prefix + "PRIORITY")) { SortingPriority = option; + cmCPackLogger( + cmCPackLog::LOG_WARNING, "The \"PRIORITY\" option is set " + << "for component group \"" << group->Name + << "\", but there option is " + << "deprecated. Please use \"SORTING_PRIORITY\" option instead." + << std::endl); } return ConfigureFromPrefix(prefix); @@ -420,6 +427,79 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) ReleaseDate = value; } + // Sorting priority + option = prefix + "SORTING_PRIORITY"; + if (IsSetToEmpty(option)) { + SortingPriority.clear(); + } else if (const char* value = GetOption(option)) { + SortingPriority = value; + } + + // Update text + option = prefix + "UPDATE_TEXT"; + if (IsSetToEmpty(option)) { + UpdateText.clear(); + } else if (const char* value = GetOption(option)) { + UpdateText = value; + } + + // Translations + option = prefix + "TRANSLATIONS"; + if (IsSetToEmpty(option)) { + Translations.clear(); + } else if (const char* value = this->GetOption(option)) { + Translations.clear(); + cmSystemTools::ExpandListArgument(value, Translations); + } + + // QtIFW dependencies + std::vector<std::string> deps; + option = prefix + "DEPENDS"; + if (const char* value = this->GetOption(option)) { + cmSystemTools::ExpandListArgument(value, deps); + } + option = prefix + "DEPENDENCIES"; + if (const char* value = this->GetOption(option)) { + cmSystemTools::ExpandListArgument(value, deps); + } + for (std::vector<std::string>::iterator dit = deps.begin(); + dit != deps.end(); ++dit) { + DependenceStruct dep(*dit); + if (Generator->Packages.count(dep.Name)) { + cmCPackIFWPackage& depPkg = Generator->Packages[dep.Name]; + dep.Name = depPkg.Name; + } + bool hasDep = Generator->DependentPackages.count(dep.Name) > 0; + DependenceStruct& depRef = Generator->DependentPackages[dep.Name]; + if (!hasDep) { + depRef = dep; + } + AlienDependencies.insert(&depRef); + } + + // Automatic dependency on + option = prefix + "AUTO_DEPEND_ON"; + if (IsSetToEmpty(option)) { + AlienAutoDependOn.clear(); + } else if (const char* value = this->GetOption(option)) { + std::vector<std::string> depsOn; + cmSystemTools::ExpandListArgument(value, depsOn); + for (std::vector<std::string>::iterator dit = depsOn.begin(); + dit != depsOn.end(); ++dit) { + DependenceStruct dep(*dit); + if (Generator->Packages.count(dep.Name)) { + cmCPackIFWPackage& depPkg = Generator->Packages[dep.Name]; + dep.Name = depPkg.Name; + } + bool hasDep = Generator->DependentPackages.count(dep.Name) > 0; + DependenceStruct& depRef = Generator->DependentPackages[dep.Name]; + if (!hasDep) { + depRef = dep; + } + AlienAutoDependOn.insert(&depRef); + } + } + // Visibility option = prefix + "VIRTUAL"; if (IsSetToEmpty(option)) { @@ -455,6 +535,16 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) ForcedInstallation = "false"; } + // Requires admin rights + option = prefix + "REQUIRES_ADMIN_RIGHTS"; + if (IsSetToEmpty(option)) { + RequiresAdminRights.clear(); + } else if (IsOn(option)) { + RequiresAdminRights = "true"; + } else if (IsSetToOff(option)) { + RequiresAdminRights = "false"; + } + return 1; } @@ -481,6 +571,12 @@ void cmCPackIFWPackage::GeneratePackageFile() xout.Element("DisplayName", DisplayName); xout.Element("Description", Description); + + // Update text + if (!UpdateText.empty()) { + xout.Element("UpdateText", UpdateText); + } + xout.Element("Name", Name); xout.Element("Version", Version); @@ -515,6 +611,23 @@ void cmCPackIFWPackage::GeneratePackageFile() xout.EndElement(); } + // Translations (copy to meta dir) + std::vector<std::string> translations = Translations; + for (size_t i = 0; i < translations.size(); i++) { + std::string name = cmSystemTools::GetFilenameName(translations[i]); + std::string path = Directory + "/meta/" + name; + cmsys::SystemTools::CopyFileIfDifferent(translations[i].data(), + path.data()); + translations[i] = name; + } + if (!translations.empty()) { + xout.StartElement("Translations"); + for (size_t i = 0; i < translations.size(); i++) { + xout.Element("Translation", translations[i]); + } + xout.EndElement(); + } + // Dependencies std::set<DependenceStruct> compDepSet; for (std::set<DependenceStruct*>::iterator ait = AlienDependencies.begin(); @@ -538,6 +651,25 @@ void cmCPackIFWPackage::GeneratePackageFile() xout.Element("Dependencies", dependencies.str()); } + // Automatic dependency on + std::set<DependenceStruct> compAutoDepSet; + for (std::set<DependenceStruct*>::iterator ait = AlienAutoDependOn.begin(); + ait != AlienAutoDependOn.end(); ++ait) { + compAutoDepSet.insert(*(*ait)); + } + // Write automatic dependency on + if (!compAutoDepSet.empty()) { + std::ostringstream dependencies; + std::set<DependenceStruct>::iterator it = compAutoDepSet.begin(); + dependencies << it->NameWithCompare(); + ++it; + while (it != compAutoDepSet.end()) { + dependencies << "," << it->NameWithCompare(); + ++it; + } + xout.Element("AutoDependOn", dependencies.str()); + } + // Licenses (copy to meta dir) std::vector<std::string> licenses = Licenses; for (size_t i = 1; i < licenses.size(); i += 2) { @@ -561,6 +693,10 @@ void cmCPackIFWPackage::GeneratePackageFile() xout.Element("ForcedInstallation", ForcedInstallation); } + if (!RequiresAdminRights.empty()) { + xout.Element("RequiresAdminRights", RequiresAdminRights); + } + if (!Virtual.empty()) { xout.Element("Virtual", Virtual); } else if (!Default.empty()) { diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h index 76ed540..bd1d6c5 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.h +++ b/Source/CPack/IFW/cmCPackIFWPackage.h @@ -92,9 +92,15 @@ public: /// List of pages to load std::vector<std::string> UserInterfaces; + /// List of translation files to load + std::vector<std::string> Translations; + /// Priority of the component in the tree std::string SortingPriority; + /// Description added to the component description + std::string UpdateText; + /// Set to true to preselect the component in the installer std::string Default; @@ -107,6 +113,9 @@ public: /// Determines that the package must always be installed std::string ForcedInstallation; + /// Package needs to be installed with elevated permissions + std::string RequiresAdminRights; + public: // Internal implementation @@ -139,6 +148,8 @@ public: std::set<cmCPackIFWPackage*> Dependencies; // Collection of unresolved dependencies std::set<DependenceStruct*> AlienDependencies; + // Collection of unresolved automatic dependency on + std::set<DependenceStruct*> AlienAutoDependOn; // Patch to package directory std::string Directory; diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index a062e64..620e237 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -607,9 +607,13 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterDynamicOptions.push_back("-E"); this->MemoryTesterDynamicOptions.push_back("env"); std::string envVar; - std::string extraOptions = ":" + - this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions"); + std::string extraOptions; std::string suppressionsOption; + if (!this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions") + .empty()) { + extraOptions = ":" + + this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions"); + } if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile") .empty()) { suppressionsOption = ":suppressions=" + @@ -631,8 +635,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() cmCTestMemCheckHandler::UB_SANITIZER) { envVar = "UBSAN_OPTIONS"; } + // Quote log_path with single quotes; see + // https://bugs.chromium.org/p/chromium/issues/detail?id=467936 std::string outputFile = - envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\""; + envVar + "=log_path='" + this->MemoryTesterOutputFile + "'"; this->MemoryTesterEnvironmentVariable = outputFile + suppressionsOption + extraOptions; break; diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index daf4bd1..6284ac9 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -46,7 +46,7 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames, QString AddCacheEntry::name() const { - return this->Name->text(); + return this->Name->text().trimmed(); } QVariant AddCacheEntry::value() const diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index b6db0d6..dcf3764 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4419,9 +4419,10 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config, // The generator may add the configuration's subdirectory. if (!conf.empty()) { - bool iosPlatform = this->Makefile->PlatformIsAppleIos(); + bool useEPN = + this->GlobalGenerator->UseEffectivePlatformName(this->Makefile); std::string suffix = - usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : ""; + usesDefaultOutputDir && useEPN ? "${EFFECTIVE_PLATFORM_NAME}" : ""; this->LocalGenerator->GetGlobalGenerator()->AppendDirectoryForConfig( "/", conf, suffix, out); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2808051..f118250 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2342,8 +2342,8 @@ void cmGlobalGenerator::AddGlobalTarget_Install( singleLine.push_back(cmd); if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') { std::string cfgArg = "-DBUILD_TYPE="; - bool iosPlatform = mf->PlatformIsAppleIos(); - if (iosPlatform) { + bool useEPN = this->UseEffectivePlatformName(mf); + if (useEPN) { cfgArg += "$(CONFIGURATION)"; singleLine.push_back(cfgArg); cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 88ef8da..18e3730 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -333,6 +333,10 @@ public: virtual bool UseFolderProperty() const; + /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is + relevant for mixed macOS and iOS builds. */ + virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; } + std::string GetSharedLibFlagsForLanguage(std::string const& lang) const; /** Generate an <output>.rule file path for a given command output. */ diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 96535eb..d448315 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -22,6 +22,7 @@ #include "cmOutputConverter.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" +#include "cmState.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -3544,6 +3545,19 @@ bool cmGlobalXCodeGenerator::IsMultiConfig() const return true; } +bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const +{ + const char* epnValue = + this->GetCMakeInstance()->GetState()->GetGlobalProperty( + "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME"); + + if (!epnValue) { + return mf->PlatformIsAppleIos(); + } + + return cmSystemTools::IsOn(epnValue); +} + void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* gt) const { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 42c39aa..1aaf9c7 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -86,6 +86,8 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ bool IsMultiConfig() const CM_OVERRIDE; + bool UseEffectivePlatformName(cmMakefile* mf) const CM_OVERRIDE; + bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) CM_OVERRIDE; void AppendFlag(std::string& flags, std::string const& flag); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 379ae16..866c132 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -631,7 +631,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop); std::string const tidy_prop = lang + "_CLANG_TIDY"; const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop); - if ((iwyu && *iwyu) || (tidy && *tidy)) { + std::string const cpplint_prop = lang + "_CPPLINT"; + const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop); + if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint)) { std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_iwyu"; if (iwyu && *iwyu) { run_iwyu += " --iwyu="; @@ -640,6 +642,12 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( if (tidy && *tidy) { run_iwyu += " --tidy="; run_iwyu += this->LocalGenerator->EscapeForShell(tidy); + } + if (cpplint && *cpplint) { + run_iwyu += " --cpplint="; + run_iwyu += this->LocalGenerator->EscapeForShell(cpplint); + } + if ((tidy && *tidy) || (cpplint && *cpplint)) { run_iwyu += " --source="; run_iwyu += sourceFile; } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 8ad2efe..0b33b19 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -600,7 +600,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop); std::string const tidy_prop = lang + "_CLANG_TIDY"; const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop); - if ((iwyu && *iwyu) || (tidy && *tidy)) { + std::string const cpplint_prop = lang + "_CPPLINT"; + const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop); + if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint)) { std::string run_iwyu = this->GetLocalGenerator()->ConvertToOutputFormat( cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL); run_iwyu += " -E __run_iwyu"; @@ -611,6 +613,12 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) if (tidy && *tidy) { run_iwyu += " --tidy="; run_iwyu += this->GetLocalGenerator()->EscapeForShell(tidy); + } + if (cpplint && *cpplint) { + run_iwyu += " --cpplint="; + run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint); + } + if ((tidy && *tidy) || (cpplint && *cpplint)) { run_iwyu += " --source=$in"; } run_iwyu += " -- "; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d825e5c..8c62c48 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -255,6 +255,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("MACOSX_RPATH", CM_NULLPTR); this->SetPropertyDefault("C_CLANG_TIDY", CM_NULLPTR); this->SetPropertyDefault("C_COMPILER_LAUNCHER", CM_NULLPTR); + this->SetPropertyDefault("C_CPPLINT", CM_NULLPTR); this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", CM_NULLPTR); this->SetPropertyDefault("LINK_WHAT_YOU_USE", CM_NULLPTR); this->SetPropertyDefault("C_STANDARD", CM_NULLPTR); @@ -262,6 +263,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, this->SetPropertyDefault("C_EXTENSIONS", CM_NULLPTR); this->SetPropertyDefault("CXX_CLANG_TIDY", CM_NULLPTR); this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", CM_NULLPTR); + this->SetPropertyDefault("CXX_CPPLINT", CM_NULLPTR); this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", CM_NULLPTR); this->SetPropertyDefault("CXX_STANDARD", CM_NULLPTR); this->SetPropertyDefault("CXX_STANDARD_REQUIRED", CM_NULLPTR); diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 4a97114..1e5ac5b 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -5,6 +5,7 @@ #include <cmConfigure.h> #include <cstring> #include <sstream> +#include <stdlib.h> #include "cmSystemTools.h" @@ -12,6 +13,16 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString, bool utcFlag) { time_t currentTimeT = time(CM_NULLPTR); + std::string source_date_epoch; + cmSystemTools::GetEnv("SOURCE_DATE_EPOCH", source_date_epoch); + if (!source_date_epoch.empty()) { + std::istringstream iss(source_date_epoch); + iss >> currentTimeT; + if (iss.fail() || !iss.eof()) { + cmSystemTools::Error("Cannot parse SOURCE_DATE_EPOCH as integer"); + exit(27); + } + } if (currentTimeT == time_t(-1)) { return std::string(); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 89380eb..2e6c19b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -610,30 +610,91 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() this->GeneratorTarget->GetResxSources(resxObjs, ""); if (!resxObjs.empty()) { this->WriteString("<ItemGroup>\n", 1); + std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + this->ConvertToWindowsSlash(srcDir); for (std::vector<cmSourceFile const*>::const_iterator oi = resxObjs.begin(); oi != resxObjs.end(); ++oi) { std::string obj = (*oi)->GetFullPath(); this->WriteString("<EmbeddedResource Include=\"", 2); this->ConvertToWindowsSlash(obj); + bool useRelativePath = false; + if (csproj == this->ProjectType && this->InSourceBuild) { + // If we do an in-source build and the resource file is in a + // subdirectory + // of the .csproj file, we have to use relative pathnames, otherwise + // visual studio does not show the file in the IDE. Sorry. + if (obj.find(srcDir) == 0) { + obj = this->ConvertPath(obj, true); + this->ConvertToWindowsSlash(obj); + useRelativePath = true; + } + } (*this->BuildFileStream) << obj << "\">\n"; - this->WriteString("<DependentUpon>", 3); - std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; - (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; - - for (std::vector<std::string>::const_iterator i = - this->Configurations.begin(); - i != this->Configurations.end(); ++i) { - this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); - if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || - // Handle variant of VS_GLOBAL_<variable> for RootNamespace. - this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { - (*this->BuildFileStream) << "$(RootNamespace)."; + if (csproj != this->ProjectType) { + this->WriteString("<DependentUpon>", 3); + std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; + (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; + + for (std::vector<std::string>::const_iterator i = + this->Configurations.begin(); + i != this->Configurations.end(); ++i) { + this->WritePlatformConfigTag("LogicalName", i->c_str(), 3); + if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || + // Handle variant of VS_GLOBAL_<variable> for RootNamespace. + this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { + (*this->BuildFileStream) << "$(RootNamespace)."; + } + (*this->BuildFileStream) << "%(Filename)"; + (*this->BuildFileStream) << ".resources"; + (*this->BuildFileStream) << "</LogicalName>\n"; + } + } else { + std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + this->ConvertToWindowsSlash(binDir); + // If the resource was NOT added using a relative path (which should + // be the default), we have to provide a link here + if (!useRelativePath) { + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } + // Determine if this is a generated resource from a .Designer.cs file + std::string designerResource = + cmSystemTools::GetFilenamePath((*oi)->GetFullPath()) + "/" + + cmSystemTools::GetFilenameWithoutLastExtension( + (*oi)->GetFullPath()) + + ".Designer.cs"; + if (cmsys::SystemTools::FileExists(designerResource)) { + std::string generator = "PublicResXFileCodeGenerator"; + if (const char* g = (*oi)->GetProperty("VS_RESOURCE_GENERATOR")) { + generator = g; + } + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(generator) + << "</Generator>\n"; + if (designerResource.find(srcDir) == 0) { + designerResource = designerResource.substr(srcDir.length() + 1); + } else if (designerResource.find(binDir) == 0) { + designerResource = designerResource.substr(binDir.length() + 1); + } else { + designerResource = + cmsys::SystemTools::GetFilenameName(designerResource); + } + this->ConvertToWindowsSlash(designerResource); + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << designerResource << "</LastGenOutput>\n"; } - (*this->BuildFileStream) << "%(Filename)"; - (*this->BuildFileStream) << ".resources"; - (*this->BuildFileStream) << "</LogicalName>\n"; } this->WriteString("</EmbeddedResource>\n", 2); @@ -661,6 +722,24 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() } this->WriteSource(xamlType, *oi, ">\n"); + if (csproj == this->ProjectType && !this->InSourceBuild) { + // add <Link> tag to written XAML source if necessary + const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); + const std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); + std::string link; + if (obj.find(srcDir) == 0) { + link = obj.substr(srcDir.length() + 1); + } else if (obj.find(binDir) == 0) { + link = obj.substr(binDir.length() + 1); + } else { + link = cmsys::SystemTools::GetFilenameName(obj); + } + if (!link.empty()) { + this->ConvertToWindowsSlash(link); + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << link << "</Link>\n"; + } + } this->WriteString("<SubType>Designer</SubType>\n", 3); this->WriteString("</", 2); (*this->BuildFileStream) << xamlType << ">\n"; @@ -1348,7 +1427,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) std::string shaderEntryPoint; std::string shaderModel; std::string shaderAdditionalFlags; + std::string settingsGenerator; + std::string settingsLastGenOutput; std::string sourceLink; + std::string subType; + std::string copyToOutDir; + std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); if (csproj == this->ProjectType) { // EVERY extra source file must have a <Link>, otherwise it might not @@ -1405,6 +1489,28 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) tool = "XML"; } else if (ext == "natvis") { tool = "Natvis"; + } else if (ext == "settings") { + // remove path to current source dir (if files are in current source dir) + if (!sourceLink.empty()) { + settingsLastGenOutput = sourceLink; + } else { + settingsLastGenOutput = sf->GetFullPath(); + } + std::size_t pos = settingsLastGenOutput.find(".settings"); + settingsLastGenOutput.replace(pos, 9, ".Designer.cs"); + settingsGenerator = "SettingsSingleFileGenerator"; + toolHasSettings = true; + } else if (ext == "vsixmanifest") { + subType = "Designer"; + } + if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { + copyToOutDir = c; + toolHasSettings = true; + } + if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) { + includeInVsix = "True"; + tool = "Content"; + toolHasSettings = true; } if (this->NsightTegra) { @@ -1495,10 +1601,35 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) (*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags) << "</AdditionalOptions>\n"; } + if (!settingsGenerator.empty()) { + this->WriteString("<Generator>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsGenerator) + << "</Generator>\n"; + } + if (!settingsLastGenOutput.empty()) { + this->WriteString("<LastGenOutput>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(settingsLastGenOutput) + << "</LastGenOutput>\n"; + } if (!sourceLink.empty()) { this->WriteString("<Link>", 3); (*this->BuildFileStream) << cmVS10EscapeXML(sourceLink) << "</Link>\n"; } + if (!subType.empty()) { + this->WriteString("<SubType>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(subType) << "</SubType>\n"; + } + if (!copyToOutDir.empty()) { + this->WriteString("<CopyToOutputDirectory>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(copyToOutDir) + << "</CopyToOutputDirectory>\n"; + } + if (!includeInVsix.empty()) { + this->WriteString("<IncludeInVSIX>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(includeInVsix) + << "</IncludeInVSIX>\n"; + } + this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } else { @@ -1540,12 +1671,6 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, this->GlobalGenerator->PathTooLong(this->GeneratorTarget, sf, sourceRel); } } - if (csproj == this->ProjectType && this->InSourceBuild) { - std::string srcdir = this->Makefile->GetCurrentSourceDirectory(); - if (sourceFile.find(srcdir) != std::string::npos) { - sourceFile = sourceFile.substr(srcdir.size() + 1); - } - } this->ConvertToWindowsSlash(sourceFile); this->WriteString("<", 2); (*this->BuildFileStream) << tool << " Include=\"" @@ -1815,9 +1940,43 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( sourceFileTags["Link"] = link; } } - // - // NOTE: in future commits additional props will be added! - // + // check if file is a generated .Designer.cs or .xaml.cs file + // to add additional necessary tags + const std::string fileExtension = + cmsys::SystemTools::GetFilenameExtension(f); + if (fileExtension == ".Designer.cs" || fileExtension == ".xaml.cs") { + f = f.substr(0, f.length() - fileExtension.length()); + if (sourceFileTags.find("Link") == sourceFileTags.end() && + !this->InSourceBuild) { + // add link fallback + sourceFileTags["Link"] = + cmsys::SystemTools::GetFilenameName(f) + fileExtension; + } + std::vector<std::string> extensions; + extensions.push_back(".resx"); + extensions.push_back(".settings"); + extensions.push_back(".xaml"); + extensions.push_back(".cs"); + std::string dependencyExtension; + for (std::vector<std::string>::iterator i = extensions.begin(); + i != extensions.end(); ++i) { + if (cmsys::SystemTools::FileExists(f + *i)) { + dependencyExtension = *i; + // There should never be more than one match. Otherwise + // one cannot tell on which match the file depends. + break; + } + } + if (dependencyExtension == ".resx") { + sourceFileTags["DesignTime"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } else if (dependencyExtension == ".settings") { + sourceFileTags["DesignTimeSharedInput"] = "True"; + sourceFileTags["AutoGen"] = "True"; + } + sourceFileTags["DependentUpon"] = + cmsys::SystemTools::GetFilenameName(f) + dependencyExtension; + } // write source file specific tags if (!sourceFileTags.empty()) { hasFlags = true; @@ -1825,7 +1984,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( firstString = ""; for (CsPropMap::const_iterator i = sourceFileTags.begin(); i != sourceFileTags.end(); ++i) { - this->WriteString("<", 2); + this->WriteString("<", 3); (*this->BuildFileStream) << i->first << ">" << cmVS10EscapeXML(i->second) << "</" << i->first << ">\n"; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 5b12a75..823b38f 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -276,7 +276,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if (args[1] == "__run_iwyu") { if (args.size() < 3) { std::cerr << "__run_iwyu Usage: -E __run_iwyu [--iwyu=/path/iwyu]" - " [--tidy=/path/tidy] -- compile command\n"; + " [--cpplint=/path/cpplint] [--tidy=/path/tidy]" + " -- compile command\n"; return 1; } bool doing_options = true; @@ -285,6 +286,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) std::string tidy; std::string sourceFile; std::string lwyu; + std::string cpplint; for (std::string::size_type cc = 2; cc < args.size(); cc++) { std::string const& arg = args[cc]; if (arg == "--") { @@ -297,6 +299,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) sourceFile = arg.substr(9); } else if (doing_options && cmHasLiteralPrefix(arg, "--lwyu=")) { lwyu = arg.substr(7); + } else if (doing_options && cmHasLiteralPrefix(arg, "--cpplint=")) { + cpplint = arg.substr(10); } else if (doing_options) { std::cerr << "__run_iwyu given unknown argument: " << arg << "\n"; return 1; @@ -304,12 +308,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) orig_cmd.push_back(arg); } } - if (tidy.empty() && iwyu.empty() && lwyu.empty()) { - std::cerr << "__run_iwyu missing --tidy= or --iwyu=\n"; + if (tidy.empty() && iwyu.empty() && lwyu.empty() && cpplint.empty()) { + std::cerr << "__run_iwyu missing --cpplint=, --iwyu=, --lwyu=, and/or" + " --tidy=\n"; return 1; } - if (!tidy.empty() && sourceFile.empty()) { - std::cerr << "__run_iwyu --tidy= requires --source=\n"; + if ((!cpplint.empty() || !tidy.empty()) && sourceFile.empty()) { + std::cerr << "__run_iwyu --cpplint= and/or __run_iwyu --tidy=" + " require --source=\n"; return 1; } if (orig_cmd.empty() && lwyu.empty()) { @@ -403,6 +409,32 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) std::cerr << "Warning: " << stdOut; } } + + if (!cpplint.empty()) { + // Construct the cpplint command line. + std::vector<std::string> cpplint_cmd; + cmSystemTools::ExpandListArgument(cpplint, cpplint_cmd, true); + cpplint_cmd.push_back(sourceFile); + + // Run the cpplint command line. Capture its output. + std::string stdOut; + if (!cmSystemTools::RunSingleCommand(cpplint_cmd, &stdOut, &stdOut, + &ret, CM_NULLPTR, + cmSystemTools::OUTPUT_NONE)) { + std::cerr << "Error running '" << cpplint_cmd[0] << "': " << stdOut + << "\n"; + return 1; + } + + // Output the output from cpplint to stderr + std::cerr << stdOut; + + // If cpplint exited with an error do the same. + if (ret != 0) { + return ret; + } + } + ret = 0; // Now run the real compiler command and return its result value. if (lwyu.empty() && |