1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

VS: Refactor MSVC character set selection

This commit is contained in:
Brad King
2025-10-10 16:45:08 -04:00
parent 8a135ea018
commit 19a61e56cf
5 changed files with 42 additions and 54 deletions

View File

@@ -816,11 +816,14 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
/* clang-format on */
}
cm::optional<cmGeneratorTarget::MsvcCharSet> 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";

View File

@@ -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<MsvcCharSet> 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");

View File

@@ -276,6 +276,9 @@ private:
using ToolSourceMap = std::map<std::string, ToolSources>;
ToolSourceMap Tools;
using MsvcCharSet = cmGeneratorTarget::MsvcCharSet;
std::map<std::string, MsvcCharSet> CharSet;
std::set<std::string> ExpectedResxHeaders;
std::set<std::string> ExpectedXamlHeaders;
std::set<std::string> ExpectedXamlSources;

View File

@@ -7,6 +7,7 @@
#include <vector>
#include <cm/iterator>
#include <cm/optional>
#include <cmext/string_view>
#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<cmGeneratorTarget::MsvcCharSet>
cmVisualStudioGeneratorOptions::GetCharSet() const
{
using MsvcCharSet = cmGeneratorTarget::MsvcCharSet;
if (this->CachedCharset.has_value()) {
return;
}
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 =
// Look for a project- or user-specified character set definition.
for (std::string const& define : this->Defines) {
cmGeneratorTarget::MsvcCharSet charSet =
cmGeneratorTarget::GetMsvcCharSet(define);
return newValue != MsvcCharSet::None;
});
if (it == this->Defines.end()) {
// Default to multi-byte, as Visual Studio does
newValue = MsvcCharSet::MultiByte;
if (charSet != cmGeneratorTarget::MsvcCharSet::None) {
return charSet;
}
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()

View File

@@ -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<cmGeneratorTarget::MsvcCharSet> GetCharSet() const;
void FixCudaCodeGeneration();
@@ -98,11 +97,7 @@ private:
std::string UnknownFlagField;
mutable cm::optional<cmGeneratorTarget::MsvcCharSet> CachedCharset;
void StoreUnknownFlag(std::string const& flag) override;
FlagValue TakeFlag(std::string const& key);
void CacheCharsetValue() const;
};