mirror of
https://github.com/reactos/CMake.git
synced 2024-12-13 14:27:23 +00:00
ba89e92ba6
For Visual Studio using the Preprocessor Define _SBCS. This behavior is similar to the way that _UNICODE and _MBCS work already. Added tests to confirm this behavior.
371 lines
11 KiB
C++
371 lines
11 KiB
C++
#include "cmVisualStudioGeneratorOptions.h"
|
|
#include "cmSystemTools.h"
|
|
#include <cmsys/System.h>
|
|
#include "cmVisualStudio10TargetGenerator.h"
|
|
|
|
inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
|
|
{
|
|
std::string ret = s;
|
|
cmSystemTools::ReplaceString(ret, "&", "&");
|
|
cmSystemTools::ReplaceString(ret, "<", "<");
|
|
cmSystemTools::ReplaceString(ret, ">", ">");
|
|
return ret;
|
|
}
|
|
|
|
inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
|
|
{
|
|
std::string ret = s;
|
|
cmSystemTools::ReplaceString(ret, "&", "&");
|
|
cmSystemTools::ReplaceString(ret, "\"", """);
|
|
cmSystemTools::ReplaceString(ret, "<", "<");
|
|
cmSystemTools::ReplaceString(ret, ">", ">");
|
|
cmSystemTools::ReplaceString(ret, "\n", "
");
|
|
return ret;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmVisualStudioGeneratorOptions
|
|
::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
|
|
Tool tool,
|
|
cmVS7FlagTable const* table,
|
|
cmVS7FlagTable const* extraTable,
|
|
cmVisualStudio10TargetGenerator* g):
|
|
cmIDEOptions(),
|
|
LocalGenerator(lg), Version(lg->GetVersion()), CurrentTool(tool),
|
|
TargetGenerator(g)
|
|
{
|
|
// Store the given flag tables.
|
|
cmIDEFlagTable const** ft = this->FlagTable;
|
|
if(table) { *ft++ = table; }
|
|
if(extraTable) { *ft++ = extraTable; }
|
|
|
|
// Preprocessor definitions are not allowed for linker tools.
|
|
this->AllowDefine = (tool != Linker);
|
|
|
|
// Slash options are allowed for VS.
|
|
this->AllowSlash = true;
|
|
|
|
this->FortranRuntimeDebug = false;
|
|
this->FortranRuntimeDLL = false;
|
|
this->FortranRuntimeMT = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
|
|
{
|
|
// Exception handling is on by default because the platform file has
|
|
// "/EHsc" in the flags. Normally, that will override this
|
|
// initialization to off, but the user has the option of removing
|
|
// the flag to disable exception handling. When the user does
|
|
// remove the flag we need to override the IDE default of on.
|
|
switch (this->Version)
|
|
{
|
|
case cmLocalVisualStudioGenerator::VS7:
|
|
case cmLocalVisualStudioGenerator::VS71:
|
|
this->FlagMap["ExceptionHandling"] = "FALSE";
|
|
break;
|
|
case cmLocalVisualStudioGenerator::VS10:
|
|
case cmLocalVisualStudioGenerator::VS11:
|
|
// by default VS puts <ExceptionHandling></ExceptionHandling> empty
|
|
// for a project, to make our projects look the same put a new line
|
|
// and space over for the closing </ExceptionHandling> as the default
|
|
// value
|
|
this->FlagMap["ExceptionHandling"] = "\n ";
|
|
break;
|
|
default:
|
|
this->FlagMap["ExceptionHandling"] = "0";
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
|
|
{
|
|
// If verbose makefiles have been requested and the /nologo option
|
|
// was not given explicitly in the flags we want to add an attribute
|
|
// to the generated project to disable logo suppression. Otherwise
|
|
// the GUI default is to enable suppression.
|
|
//
|
|
// On Visual Studio 10 (and later!), the value of this attribute should be
|
|
// an empty string, instead of "FALSE", in order to avoid a warning:
|
|
// "cl ... warning D9035: option 'nologo-' has been deprecated"
|
|
//
|
|
if(verbose &&
|
|
this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end())
|
|
{
|
|
this->FlagMap["SuppressStartupBanner"] =
|
|
this->Version < cmLocalVisualStudioGenerator::VS10 ? "FALSE" : "";
|
|
}
|
|
}
|
|
|
|
bool cmVisualStudioGeneratorOptions::IsDebug()
|
|
{
|
|
return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmVisualStudioGeneratorOptions::UsingUnicode()
|
|
{
|
|
// Look for the a _UNICODE definition.
|
|
for(std::vector<std::string>::const_iterator di = this->Defines.begin();
|
|
di != this->Defines.end(); ++di)
|
|
{
|
|
if(*di == "_UNICODE")
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
bool cmVisualStudioGeneratorOptions::UsingSBCS()
|
|
{
|
|
// Look for the a _SBCS definition.
|
|
for(std::vector<std::string>::const_iterator di = this->Defines.begin();
|
|
di != this->Defines.end(); ++di)
|
|
{
|
|
if(*di == "_SBCS")
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::Parse(const char* flags)
|
|
{
|
|
// Parse the input string as a windows command line since the string
|
|
// is intended for writing directly into the build files.
|
|
std::vector<std::string> args;
|
|
cmSystemTools::ParseWindowsCommandLine(flags, args);
|
|
|
|
// Process flags that need to be represented specially in the IDE
|
|
// project file.
|
|
for(std::vector<std::string>::iterator ai = args.begin();
|
|
ai != args.end(); ++ai)
|
|
{
|
|
this->HandleFlag(ai->c_str());
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::ParseFinish()
|
|
{
|
|
if(this->CurrentTool == FortranCompiler)
|
|
{
|
|
// "RuntimeLibrary" attribute values:
|
|
// "rtMultiThreaded", "0", /threads /libs:static
|
|
// "rtMultiThreadedDLL", "2", /threads /libs:dll
|
|
// "rtMultiThreadedDebug", "1", /threads /dbglibs /libs:static
|
|
// "rtMultiThreadedDebugDLL", "3", /threads /dbglibs /libs:dll
|
|
// These seem unimplemented by the IDE:
|
|
// "rtSingleThreaded", "4", /libs:static
|
|
// "rtSingleThreadedDLL", "10", /libs:dll
|
|
// "rtSingleThreadedDebug", "5", /dbglibs /libs:static
|
|
// "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll
|
|
std::string rl = "rtMultiThreaded";
|
|
rl += this->FortranRuntimeDebug? "Debug" : "";
|
|
rl += this->FortranRuntimeDLL? "DLL" : "";
|
|
this->FlagMap["RuntimeLibrary"] = rl;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
|
|
{
|
|
// Look for Intel Fortran flags that do not map well in the flag table.
|
|
if(this->CurrentTool == FortranCompiler)
|
|
{
|
|
if(strcmp(flag, "/dbglibs") == 0)
|
|
{
|
|
this->FortranRuntimeDebug = true;
|
|
return;
|
|
}
|
|
if(strcmp(flag, "/threads") == 0)
|
|
{
|
|
this->FortranRuntimeMT = true;
|
|
return;
|
|
}
|
|
if(strcmp(flag, "/libs:dll") == 0)
|
|
{
|
|
this->FortranRuntimeDLL = true;
|
|
return;
|
|
}
|
|
if(strcmp(flag, "/libs:static") == 0)
|
|
{
|
|
this->FortranRuntimeDLL = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// This option is not known. Store it in the output flags.
|
|
this->FlagString += " ";
|
|
this->FlagString +=
|
|
cmSystemTools::EscapeWindowsShellArgument(
|
|
flag,
|
|
cmsysSystem_Shell_Flag_AllowMakeVariables |
|
|
cmsysSystem_Shell_Flag_VSIDE);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config)
|
|
{
|
|
this->Configuration = config;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
cmVisualStudioGeneratorOptions
|
|
::OutputPreprocessorDefinitions(std::ostream& fout,
|
|
const char* prefix,
|
|
const char* suffix,
|
|
const char* lang)
|
|
{
|
|
if(this->Defines.empty())
|
|
{
|
|
return;
|
|
}
|
|
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
// if there are configuration specifc flags, then
|
|
// use the configuration specific tag for PreprocessorDefinitions
|
|
if(this->Configuration.size())
|
|
{
|
|
fout << prefix;
|
|
this->TargetGenerator->WritePlatformConfigTag(
|
|
"PreprocessorDefinitions",
|
|
this->Configuration.c_str(),
|
|
0,
|
|
0, 0, &fout);
|
|
}
|
|
else
|
|
{
|
|
fout << prefix << "<PreprocessorDefinitions>";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fout << prefix << "PreprocessorDefinitions=\"";
|
|
}
|
|
const char* sep = "";
|
|
for(std::vector<std::string>::const_iterator di = this->Defines.begin();
|
|
di != this->Defines.end(); ++di)
|
|
{
|
|
// Escape the definition for the compiler.
|
|
std::string define;
|
|
if(this->Version < cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
define =
|
|
this->LocalGenerator->EscapeForShell(di->c_str(), true);
|
|
}
|
|
else
|
|
{
|
|
define = *di;
|
|
}
|
|
// Escape this flag for the IDE.
|
|
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
|
|
|
|
if(0 == strcmp(lang, "RC"))
|
|
{
|
|
cmSystemTools::ReplaceString(define, "\"", "\\\"");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
|
|
}
|
|
// Store the flag in the project file.
|
|
fout << sep << define;
|
|
sep = ";";
|
|
}
|
|
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix;
|
|
}
|
|
else
|
|
{
|
|
fout << "\"" << suffix;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
cmVisualStudioGeneratorOptions
|
|
::OutputFlagMap(std::ostream& fout, const char* indent)
|
|
{
|
|
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
|
|
m != this->FlagMap.end(); ++m)
|
|
{
|
|
fout << indent;
|
|
if(this->Configuration.size())
|
|
{
|
|
this->TargetGenerator->WritePlatformConfigTag(
|
|
m->first.c_str(),
|
|
this->Configuration.c_str(),
|
|
0,
|
|
0, 0, &fout);
|
|
}
|
|
else
|
|
{
|
|
fout << "<" << m->first << ">";
|
|
}
|
|
fout << m->second;
|
|
if (m->first == "AdditionalIncludeDirectories")
|
|
{
|
|
fout << ";%(AdditionalIncludeDirectories)";
|
|
}
|
|
fout << "</" << m->first << ">\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
|
|
m != this->FlagMap.end(); ++m)
|
|
{
|
|
fout << indent << m->first << "=\"" << m->second << "\"\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
cmVisualStudioGeneratorOptions
|
|
::OutputAdditionalOptions(std::ostream& fout,
|
|
const char* prefix,
|
|
const char* suffix)
|
|
{
|
|
if(!this->FlagString.empty())
|
|
{
|
|
if(this->Version >= cmLocalVisualStudioGenerator::VS10)
|
|
{
|
|
fout << prefix;
|
|
if(this->Configuration.size())
|
|
{
|
|
this->TargetGenerator->WritePlatformConfigTag(
|
|
"AdditionalOptions",
|
|
this->Configuration.c_str(),
|
|
0,
|
|
0, 0, &fout);
|
|
}
|
|
else
|
|
{
|
|
fout << "<AdditionalOptions>";
|
|
}
|
|
fout << this->FlagString.c_str()
|
|
<< " %(AdditionalOptions)</AdditionalOptions>\n";
|
|
}
|
|
else
|
|
{
|
|
fout << prefix << "AdditionalOptions=\"";
|
|
fout <<
|
|
cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString.c_str());
|
|
fout << "\"" << suffix;
|
|
}
|
|
}
|
|
}
|