1 #include "cmVisualStudioGeneratorOptions.h"
2 #include "cmSystemTools.h"
3 #include <cmsys/System.h>
4 #include "cmVisualStudio10TargetGenerator.h"
6 inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
9 cmSystemTools::ReplaceString(ret, ";", "%3B");
10 cmSystemTools::ReplaceString(ret, "&", "&");
11 cmSystemTools::ReplaceString(ret, "<", "<");
12 cmSystemTools::ReplaceString(ret, ">", ">");
16 inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
19 cmSystemTools::ReplaceString(ret, "&", "&");
20 cmSystemTools::ReplaceString(ret, "\"", """);
21 cmSystemTools::ReplaceString(ret, "<", "<");
22 cmSystemTools::ReplaceString(ret, ">", ">");
23 cmSystemTools::ReplaceString(ret, "\n", "
");
27 //----------------------------------------------------------------------------
28 cmVisualStudioGeneratorOptions
29 ::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
31 cmVS7FlagTable const* table,
32 cmVS7FlagTable const* extraTable,
33 cmVisualStudio10TargetGenerator* g):
35 LocalGenerator(lg), Version(lg->GetVersion()), CurrentTool(tool),
38 // Store the given flag tables.
39 cmIDEFlagTable const** ft = this->FlagTable;
40 if(table) { *ft++ = table; }
41 if(extraTable) { *ft++ = extraTable; }
43 // Preprocessor definitions are not allowed for linker tools.
44 this->AllowDefine = (tool != Linker);
46 // Slash options are allowed for VS.
47 this->AllowSlash = true;
49 this->FortranRuntimeDebug = false;
50 this->FortranRuntimeDLL = false;
51 this->FortranRuntimeMT = false;
54 //----------------------------------------------------------------------------
55 void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
57 // Exception handling is on by default because the platform file has
58 // "/EHsc" in the flags. Normally, that will override this
59 // initialization to off, but the user has the option of removing
60 // the flag to disable exception handling. When the user does
61 // remove the flag we need to override the IDE default of on.
62 switch (this->Version)
64 case cmLocalVisualStudioGenerator::VS7:
65 case cmLocalVisualStudioGenerator::VS71:
66 this->FlagMap["ExceptionHandling"] = "FALSE";
68 case cmLocalVisualStudioGenerator::VS10:
69 case cmLocalVisualStudioGenerator::VS11:
70 case cmLocalVisualStudioGenerator::VS12:
71 // by default VS puts <ExceptionHandling></ExceptionHandling> empty
72 // for a project, to make our projects look the same put a new line
73 // and space over for the closing </ExceptionHandling> as the default
75 this->FlagMap["ExceptionHandling"] = "\n ";
78 this->FlagMap["ExceptionHandling"] = "0";
83 //----------------------------------------------------------------------------
84 void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
86 // If verbose makefiles have been requested and the /nologo option
87 // was not given explicitly in the flags we want to add an attribute
88 // to the generated project to disable logo suppression. Otherwise
89 // the GUI default is to enable suppression.
91 // On Visual Studio 10 (and later!), the value of this attribute should be
92 // an empty string, instead of "FALSE", in order to avoid a warning:
93 // "cl ... warning D9035: option 'nologo-' has been deprecated"
96 this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end())
98 this->FlagMap["SuppressStartupBanner"] =
99 this->Version < cmLocalVisualStudioGenerator::VS10 ? "FALSE" : "";
103 bool cmVisualStudioGeneratorOptions::IsDebug() const
105 return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
108 //----------------------------------------------------------------------------
109 bool cmVisualStudioGeneratorOptions::UsingUnicode() const
111 // Look for the a _UNICODE definition.
112 for(std::vector<std::string>::const_iterator di = this->Defines.begin();
113 di != this->Defines.end(); ++di)
115 if(*di == "_UNICODE")
122 //----------------------------------------------------------------------------
123 bool cmVisualStudioGeneratorOptions::UsingSBCS() const
125 // Look for the a _SBCS definition.
126 for(std::vector<std::string>::const_iterator di = this->Defines.begin();
127 di != this->Defines.end(); ++di)
137 //----------------------------------------------------------------------------
138 void cmVisualStudioGeneratorOptions::Parse(const char* flags)
140 // Parse the input string as a windows command line since the string
141 // is intended for writing directly into the build files.
142 std::vector<std::string> args;
143 cmSystemTools::ParseWindowsCommandLine(flags, args);
145 // Process flags that need to be represented specially in the IDE
147 for(std::vector<std::string>::iterator ai = args.begin();
148 ai != args.end(); ++ai)
150 this->HandleFlag(ai->c_str());
154 //----------------------------------------------------------------------------
155 void cmVisualStudioGeneratorOptions::ParseFinish()
157 if(this->CurrentTool == FortranCompiler)
159 // "RuntimeLibrary" attribute values:
160 // "rtMultiThreaded", "0", /threads /libs:static
161 // "rtMultiThreadedDLL", "2", /threads /libs:dll
162 // "rtMultiThreadedDebug", "1", /threads /dbglibs /libs:static
163 // "rtMultiThreadedDebugDLL", "3", /threads /dbglibs /libs:dll
164 // These seem unimplemented by the IDE:
165 // "rtSingleThreaded", "4", /libs:static
166 // "rtSingleThreadedDLL", "10", /libs:dll
167 // "rtSingleThreadedDebug", "5", /dbglibs /libs:static
168 // "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll
169 std::string rl = "rtMultiThreaded";
170 rl += this->FortranRuntimeDebug? "Debug" : "";
171 rl += this->FortranRuntimeDLL? "DLL" : "";
172 this->FlagMap["RuntimeLibrary"] = rl;
176 //----------------------------------------------------------------------------
177 void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
179 // Look for Intel Fortran flags that do not map well in the flag table.
180 if(this->CurrentTool == FortranCompiler)
182 if(strcmp(flag, "/dbglibs") == 0)
184 this->FortranRuntimeDebug = true;
187 if(strcmp(flag, "/threads") == 0)
189 this->FortranRuntimeMT = true;
192 if(strcmp(flag, "/libs:dll") == 0)
194 this->FortranRuntimeDLL = true;
197 if(strcmp(flag, "/libs:static") == 0)
199 this->FortranRuntimeDLL = false;
204 // This option is not known. Store it in the output flags.
205 this->FlagString += " ";
207 cmSystemTools::EscapeWindowsShellArgument(
209 cmsysSystem_Shell_Flag_AllowMakeVariables |
210 cmsysSystem_Shell_Flag_VSIDE);
213 //----------------------------------------------------------------------------
214 void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config)
216 this->Configuration = config;
219 //----------------------------------------------------------------------------
221 cmVisualStudioGeneratorOptions
222 ::OutputPreprocessorDefinitions(std::ostream& fout,
227 if(this->Defines.empty())
231 if(this->Version >= cmLocalVisualStudioGenerator::VS10)
233 // if there are configuration specific flags, then
234 // use the configuration specific tag for PreprocessorDefinitions
235 if(this->Configuration.size())
238 this->TargetGenerator->WritePlatformConfigTag(
239 "PreprocessorDefinitions",
240 this->Configuration.c_str(),
246 fout << prefix << "<PreprocessorDefinitions>";
251 fout << prefix << "PreprocessorDefinitions=\"";
253 const char* sep = "";
254 for(std::vector<std::string>::const_iterator di = this->Defines.begin();
255 di != this->Defines.end(); ++di)
257 // Escape the definition for the compiler.
259 if(this->Version < cmLocalVisualStudioGenerator::VS10)
262 this->LocalGenerator->EscapeForShell(di->c_str(), true);
268 // Escape this flag for the IDE.
269 if(this->Version >= cmLocalVisualStudioGenerator::VS10)
271 define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
273 if(0 == strcmp(lang, "RC"))
275 cmSystemTools::ReplaceString(define, "\"", "\\\"");
280 define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
282 // Store the flag in the project file.
283 fout << sep << define;
286 if(this->Version >= cmLocalVisualStudioGenerator::VS10)
288 fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix;
292 fout << "\"" << suffix;
296 //----------------------------------------------------------------------------
298 cmVisualStudioGeneratorOptions
299 ::OutputFlagMap(std::ostream& fout, const char* indent)
301 if(this->Version >= cmLocalVisualStudioGenerator::VS10)
303 for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
304 m != this->FlagMap.end(); ++m)
307 if(this->Configuration.size())
309 this->TargetGenerator->WritePlatformConfigTag(
311 this->Configuration.c_str(),
317 fout << "<" << m->first << ">";
320 if (m->first == "AdditionalIncludeDirectories")
322 fout << ";%(AdditionalIncludeDirectories)";
324 fout << "</" << m->first << ">\n";
329 for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
330 m != this->FlagMap.end(); ++m)
332 fout << indent << m->first << "=\"" << m->second << "\"\n";
337 //----------------------------------------------------------------------------
339 cmVisualStudioGeneratorOptions
340 ::OutputAdditionalOptions(std::ostream& fout,
344 if(!this->FlagString.empty())
346 if(this->Version >= cmLocalVisualStudioGenerator::VS10)
349 if(this->Configuration.size())
351 this->TargetGenerator->WritePlatformConfigTag(
353 this->Configuration.c_str(),
359 fout << "<AdditionalOptions>";
361 fout << this->FlagString.c_str()
362 << " %(AdditionalOptions)</AdditionalOptions>\n";
366 fout << prefix << "AdditionalOptions=\"";
368 cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString.c_str());
369 fout << "\"" << suffix;