diff options
Diffstat (limited to 'Source/cmVisualStudioGeneratorOptions.cxx')
-rw-r--r-- | Source/cmVisualStudioGeneratorOptions.cxx | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx new file mode 100644 index 0000000..c0913e6 --- /dev/null +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -0,0 +1,357 @@ +#include "cmVisualStudioGeneratorOptions.h" + +#include "cmLocalVisualStudioGenerator.h" +#include "cmOutputConverter.h" +#include "cmSystemTools.h" +#include "cmVisualStudio10TargetGenerator.h" + +static std::string cmVisualStudio10GeneratorOptionsEscapeForXML( + std::string ret) +{ + cmSystemTools::ReplaceString(ret, ";", "%3B"); + cmSystemTools::ReplaceString(ret, "&", "&"); + cmSystemTools::ReplaceString(ret, "<", "<"); + cmSystemTools::ReplaceString(ret, ">", ">"); + return ret; +} + +static std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret) +{ + cmSystemTools::ReplaceString(ret, "&", "&"); + cmSystemTools::ReplaceString(ret, "\"", """); + cmSystemTools::ReplaceString(ret, "<", "<"); + cmSystemTools::ReplaceString(ret, ">", ">"); + cmSystemTools::ReplaceString(ret, "\n", "
"); + return ret; +} + +cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions( + cmLocalVisualStudioGenerator* lg, Tool tool, + cmVisualStudio10TargetGenerator* g) + : cmIDEOptions() + , LocalGenerator(lg) + , Version(lg->GetVersion()) + , CurrentTool(tool) + , TargetGenerator(g) +{ + // 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; +} + +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. + this->AddTable(table); + this->AddTable(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::AddTable(cmVS7FlagTable const* table) +{ + if (table) { + for (int i = 0; i < FlagTableCount; ++i) { + if (!this->FlagTable[i]) { + this->FlagTable[i] = table; + break; + } + } + } +} + +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 cmGlobalVisualStudioGenerator::VS7: + case cmGlobalVisualStudioGenerator::VS71: + this->FlagMap["ExceptionHandling"] = "FALSE"; + break; + case cmGlobalVisualStudioGenerator::VS10: + case cmGlobalVisualStudioGenerator::VS11: + case cmGlobalVisualStudioGenerator::VS12: + case cmGlobalVisualStudioGenerator::VS14: + case cmGlobalVisualStudioGenerator::VS15: + // 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 < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : ""; + } +} + +bool cmVisualStudioGeneratorOptions::IsDebug() const +{ + if (this->CurrentTool != CSharpCompiler) { + return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end(); + } + std::map<std::string, FlagValue>::const_iterator i = + this->FlagMap.find("DebugType"); + if (i != this->FlagMap.end()) { + if (i->second.size() == 1) { + return i->second[0] != "none"; + } + } + return false; +} + +bool cmVisualStudioGeneratorOptions::IsWinRt() const +{ + return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end(); +} + +bool cmVisualStudioGeneratorOptions::IsManaged() const +{ + return this->FlagMap.find("CompileAsManaged") != this->FlagMap.end(); +} + +bool cmVisualStudioGeneratorOptions::UsingUnicode() const +{ + // 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() const +{ + // 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 += cmOutputConverter::EscapeWindowsShellArgument( + flag, cmOutputConverter::Shell_Flag_AllowMakeVariables | + cmOutputConverter::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 std::string& lang) +{ + if (this->Defines.empty()) { + return; + } + if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + // if there are configuration specific flags, then + // use the configuration specific tag for PreprocessorDefinitions + if (!this->Configuration.empty()) { + 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 < cmGlobalVisualStudioGenerator::VS10) { + define = this->LocalGenerator->EscapeForShell(di->c_str(), true); + } else { + define = *di; + } + // Escape this flag for the IDE. + if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + define = cmVisualStudio10GeneratorOptionsEscapeForXML(define); + + if (lang == "RC") { + cmSystemTools::ReplaceString(define, "\"", "\\\""); + } + } else { + define = cmVisualStudioGeneratorOptionsEscapeForXML(define); + } + // Store the flag in the project file. + fout << sep << define; + sep = ";"; + } + if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix; + } else { + fout << "\"" << suffix; + } +} + +void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout, + const char* indent) +{ + if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin(); + m != this->FlagMap.end(); ++m) { + fout << indent; + if (!this->Configuration.empty()) { + this->TargetGenerator->WritePlatformConfigTag( + m->first.c_str(), this->Configuration.c_str(), 0, 0, 0, &fout); + } else { + fout << "<" << m->first << ">"; + } + const char* sep = ""; + for (std::vector<std::string>::iterator i = m->second.begin(); + i != m->second.end(); ++i) { + fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(*i); + sep = ";"; + } + fout << "</" << m->first << ">\n"; + } + } else { + for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin(); + m != this->FlagMap.end(); ++m) { + fout << indent << m->first << "=\""; + const char* sep = ""; + for (std::vector<std::string>::iterator i = m->second.begin(); + i != m->second.end(); ++i) { + fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(*i); + sep = ";"; + } + fout << "\"\n"; + } + } +} + +void cmVisualStudioGeneratorOptions::OutputAdditionalOptions( + std::ostream& fout, const char* prefix, const char* suffix) +{ + if (!this->FlagString.empty()) { + if (this->Version >= cmGlobalVisualStudioGenerator::VS10) { + fout << prefix; + if (!this->Configuration.empty()) { + this->TargetGenerator->WritePlatformConfigTag( + "AdditionalOptions", this->Configuration.c_str(), 0, 0, 0, &fout); + } else { + fout << "<AdditionalOptions>"; + } + fout << "%(AdditionalOptions) " + << cmVisualStudio10GeneratorOptionsEscapeForXML(this->FlagString) + << "</AdditionalOptions>\n"; + } else { + fout << prefix << "AdditionalOptions=\""; + fout << cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString); + fout << "\"" << suffix; + } + } +} |