diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index ac33deb795..39c842f252 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -816,11 +816,14 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( /* clang-format on */ } + cm::optional const charSet = + targetOptions.GetCharSet(); + // If unicode is enabled change the character set to unicode, if not // then default to MBCS. - if (targetOptions.UsingUnicode()) { + if (charSet == cmGeneratorTarget::MsvcCharSet::Unicode) { fout << "\t\t\tCharacterSet=\"1\">\n"; - } else if (targetOptions.UsingSBCS()) { + } else if (charSet == cmGeneratorTarget::MsvcCharSet::SingleByte) { fout << "\t\t\tCharacterSet=\"0\">\n"; } else { fout << "\t\t\tCharacterSet=\"2\">\n"; @@ -1220,7 +1223,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( fout << "\t\t\t\tSubSystem=\"8\"\n"; if (!linkOptions.GetFlag("EntryPointSymbol")) { - char const* entryPointSymbol = targetOptions.UsingUnicode() + char const* entryPointSymbol = targetOptions.GetCharSet() == + cmGeneratorTarget::MsvcCharSet::Unicode ? (isWin32Executable ? "wWinMainCRTStartup" : "mainWCRTStartup") : (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup"); fout << "\t\t\t\tEntryPointSymbol=\"" << entryPointSymbol << "\"\n"; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9beb99bc69..bc3546a146 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -433,6 +433,17 @@ void cmVisualStudio10TargetGenerator::Generate() if (!this->ComputeLibOptions()) { return; } + for (std::string const& config : this->Configurations) { + // Default character set if not populated above. + this->CharSet.emplace( + config, + (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") || + this->GlobalGenerator->TargetsWindowsPhone() || + this->GlobalGenerator->TargetsWindowsStore() || + this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) + ? MsvcCharSet::Unicode + : MsvcCharSet::MultiByte); + } } std::string path = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/', @@ -1536,15 +1547,11 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( } if ((this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY && - this->ClOptions[config]->UsingUnicode()) || - this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") || - this->GlobalGenerator->TargetsWindowsPhone() || - this->GlobalGenerator->TargetsWindowsStore() || - this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { + this->CharSet[config] == MsvcCharSet::Unicode)) { e1.Element("CharacterSet", "Unicode"); } else if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY && - this->ClOptions[config]->UsingSBCS()) { + this->CharSet[config] == MsvcCharSet::SingleByte) { e1.Element("CharacterSet", "NotSet"); } else { e1.Element("CharacterSet", "MultiByte"); @@ -3631,6 +3638,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } } + if (cm::optional charSet = clOptions.GetCharSet()) { + this->CharSet.emplace(configName, *charSet); + } + if (this->ProjectType != VsProjectType::csproj && (clOptions.IsManaged() || clOptions.HasFlag("CLRSupport"))) { this->Managed = true; @@ -4608,7 +4619,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( if (this->GlobalGenerator->TargetsWindowsCE()) { linkOptions.AddFlag("SubSystem", "WindowsCE"); if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { - if (this->ClOptions[config]->UsingUnicode()) { + if (this->CharSet[config] == MsvcCharSet::Unicode) { linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup"); } else { linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); @@ -4621,7 +4632,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( if (this->GlobalGenerator->TargetsWindowsCE()) { linkOptions.AddFlag("SubSystem", "WindowsCE"); if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { - if (this->ClOptions[config]->UsingUnicode()) { + if (this->CharSet[config] == MsvcCharSet::Unicode) { linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup"); } else { linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 162a140e2b..1bfc92916b 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -276,6 +276,9 @@ private: using ToolSourceMap = std::map; ToolSourceMap Tools; + using MsvcCharSet = cmGeneratorTarget::MsvcCharSet; + std::map CharSet; + std::set ExpectedResxHeaders; std::set ExpectedXamlHeaders; std::set ExpectedXamlSources; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index ee66e747c8..5f10e02337 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -7,6 +7,7 @@ #include #include +#include #include #include "cmAlgorithms.h" @@ -134,44 +135,18 @@ bool cmVisualStudioGeneratorOptions::IsManaged() const return this->FlagMap.find("CompileAsManaged") != this->FlagMap.end(); } -void cmVisualStudioGeneratorOptions::CacheCharsetValue() const +cm::optional +cmVisualStudioGeneratorOptions::GetCharSet() const { - using MsvcCharSet = cmGeneratorTarget::MsvcCharSet; - - if (this->CachedCharset.has_value()) { - return; + // Look for a project- or user-specified character set definition. + for (std::string const& define : this->Defines) { + cmGeneratorTarget::MsvcCharSet charSet = + cmGeneratorTarget::GetMsvcCharSet(define); + if (charSet != cmGeneratorTarget::MsvcCharSet::None) { + return charSet; + } } - - MsvcCharSet newValue = MsvcCharSet::None; - - // Look for a any charset definition. - // Real charset will be updated if something is found. - auto it = std::find_if(this->Defines.begin(), this->Defines.end(), - [&newValue](std::string const& define) { - newValue = - cmGeneratorTarget::GetMsvcCharSet(define); - return newValue != MsvcCharSet::None; - }); - - if (it == this->Defines.end()) { - // Default to multi-byte, as Visual Studio does - newValue = MsvcCharSet::MultiByte; - } - - this->CachedCharset = newValue; -} - -bool cmVisualStudioGeneratorOptions::UsingUnicode() const -{ - this->CacheCharsetValue(); - return this->CachedCharset.value() == - cmGeneratorTarget::MsvcCharSet::Unicode; -} -bool cmVisualStudioGeneratorOptions::UsingSBCS() const -{ - this->CacheCharsetValue(); - return this->CachedCharset.value() == - cmGeneratorTarget::MsvcCharSet::SingleByte; + return cm::nullopt; } void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 76977061b6..5837876b9f 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -60,9 +60,8 @@ public: // Store options for verbose builds. void SetVerboseMakefile(bool verbose); - // Check for specific options. - bool UsingUnicode() const; - bool UsingSBCS() const; + // Detect a character set definition. + cm::optional GetCharSet() const; void FixCudaCodeGeneration(); @@ -98,11 +97,7 @@ private: std::string UnknownFlagField; - mutable cm::optional CachedCharset; - void StoreUnknownFlag(std::string const& flag) override; FlagValue TakeFlag(std::string const& key); - - void CacheCharsetValue() const; };