1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "msbuild_objectmodel.h"
5
6#include "msvc_objectmodel.h"
7#include "msvc_vcproj.h"
8#include "msvc_vcxproj.h"
9#include <qscopedpointer.h>
10#include <qstringlist.h>
11#include <qfileinfo.h>
12#include <qregularexpression.h>
13#include <qvarlengtharray.h>
14
15QT_BEGIN_NAMESPACE
16
17// XML Tags ---------------------------------------------------------
18const char _CLCompile[] = "ClCompile";
19const char _ItemGroup[] = "ItemGroup";
20const char _Link[] = "Link";
21const char _Lib[] = "Lib";
22const char _Midl[] = "Midl";
23const char _ResourceCompile[] = "ResourceCompile";
24
25// XML Properties ---------------------------------------------------
26const char _AddModuleNamesToAssembly[] = "AddModuleNamesToAssembly";
27const char _AdditionalDependencies[] = "AdditionalDependencies";
28const char _AdditionalIncludeDirectories[] = "AdditionalIncludeDirectories";
29const char _AdditionalLibraryDirectories[] = "AdditionalLibraryDirectories";
30const char _AdditionalManifestDependencies[] = "AdditionalManifestDependencies";
31const char _AdditionalOptions[] = "AdditionalOptions";
32const char _AdditionalUsingDirectories[] = "AdditionalUsingDirectories";
33const char _AllowIsolation[] = "AllowIsolation";
34const char _ApplicationConfigurationMode[] = "ApplicationConfigurationMode";
35const char _AssemblerListingLocation[] = "AssemblerListingLocation";
36const char _AssemblerOutput[] = "AssemblerOutput";
37const char _AssemblyDebug[] = "AssemblyDebug";
38const char _AssemblyLinkResource[] = "AssemblyLinkResource";
39const char _ATLMinimizesCRunTimeLibraryUsage[] = "ATLMinimizesCRunTimeLibraryUsage";
40const char _BaseAddress[] = "BaseAddress";
41const char _BasicRuntimeChecks[] = "BasicRuntimeChecks";
42const char _BrowseInformation[] = "BrowseInformation";
43const char _BrowseInformationFile[] = "BrowseInformationFile";
44const char _BufferSecurityCheck[] = "BufferSecurityCheck";
45const char _BuildBrowserInformation[] = "BuildBrowserInformation";
46const char _CallingConvention[] = "CallingConvention";
47const char _CharacterSet[] = "CharacterSet";
48const char _ClientStubFile[] = "ClientStubFile";
49const char _CLRImageType[] = "CLRImageType";
50const char _CLRSupportLastError[] = "CLRSupportLastError";
51const char _CLRThreadAttribute[] = "CLRThreadAttribute";
52const char _CLRUnmanagedCodeCheck[] = "CLRUnmanagedCodeCheck";
53const char _Command[] = "Command";
54const char _CompileAs[] = "CompileAs";
55const char _CompileAsManaged[] = "CompileAsManaged";
56const char _CompileAsWinRT[] = "CompileAsWinRT";
57const char _ConfigurationType[] = "ConfigurationType";
58const char _CPreprocessOptions[] = "CPreprocessOptions";
59const char _CreateHotpatchableImage[] = "CreateHotpatchableImage";
60const char _Culture[] = "Culture";
61const char _DataExecutionPrevention[] = "DataExecutionPrevention";
62const char _DebugInformationFormat[] = "DebugInformationFormat";
63const char _DefaultCharType[] = "DefaultCharType";
64const char _DelayLoadDLLs[] = "DelayLoadDLLs";
65const char _DelaySign[] = "DelaySign";
66const char _DeleteExtensionsOnClean[] = "DeleteExtensionsOnClean";
67const char _DisableLanguageExtensions[] = "DisableLanguageExtensions";
68const char _DisableSpecificWarnings[] = "DisableSpecificWarnings";
69const char _DLLDataFileName[] = "DLLDataFileName";
70const char _EmbedManagedResourceFile[] = "EmbedManagedResourceFile";
71const char _EmbedManifest[] = "EmbedManifest";
72const char _EnableCOMDATFolding[] = "EnableCOMDATFolding";
73const char _EnableUAC[] = "EnableUAC";
74const char _EnableErrorChecks[] = "EnableErrorChecks";
75const char _EnableEnhancedInstructionSet[] = "EnableEnhancedInstructionSet";
76const char _EnableFiberSafeOptimizations[] = "EnableFiberSafeOptimizations";
77const char _EnablePREfast[] = "EnablePREfast";
78const char _EntryPointSymbol[] = "EntryPointSymbol";
79const char _ErrorCheckAllocations[] = "ErrorCheckAllocations";
80const char _ErrorCheckBounds[] = "ErrorCheckBounds";
81const char _ErrorCheckEnumRange[] = "ErrorCheckEnumRange";
82const char _ErrorCheckRefPointers[] = "ErrorCheckRefPointers";
83const char _ErrorCheckStubData[] = "ErrorCheckStubData";
84const char _ErrorReporting[] = "ErrorReporting";
85const char _ExceptionHandling[] = "ExceptionHandling";
86const char _ExpandAttributedSource[] = "ExpandAttributedSource";
87const char _ExportNamedFunctions[] = "ExportNamedFunctions";
88const char _FavorSizeOrSpeed[] = "FavorSizeOrSpeed";
89const char _FloatingPointModel[] = "FloatingPointModel";
90const char _FloatingPointExceptions[] = "FloatingPointExceptions";
91const char _ForceConformanceInForLoopScope[] = "ForceConformanceInForLoopScope";
92const char _ForceSymbolReferences[] = "ForceSymbolReferences";
93const char _ForcedIncludeFiles[] = "ForcedIncludeFiles";
94const char _ForcedUsingFiles[] = "ForcedUsingFiles";
95const char _FunctionLevelLinking[] = "FunctionLevelLinking";
96const char _FunctionOrder[] = "FunctionOrder";
97const char _GenerateClientFiles[] = "GenerateClientFiles";
98const char _GenerateDebugInformation[] = "GenerateDebugInformation";
99const char _GenerateManifest[] = "GenerateManifest";
100const char _GenerateMapFile[] = "GenerateMapFile";
101const char _GenerateServerFiles[] = "GenerateServerFiles";
102const char _GenerateStublessProxies[] = "GenerateStublessProxies";
103const char _GenerateTypeLibrary[] = "GenerateTypeLibrary";
104const char _GenerateWindowsMetadata[] = "GenerateWindowsMetadata";
105const char _GenerateXMLDocumentationFiles[] = "GenerateXMLDocumentationFiles";
106const char _HeaderFileName[] = "HeaderFileName";
107const char _HeapCommitSize[] = "HeapCommitSize";
108const char _HeapReserveSize[] = "HeapReserveSize";
109const char _IgnoreAllDefaultLibraries[] = "IgnoreAllDefaultLibraries";
110const char _IgnoreEmbeddedIDL[] = "IgnoreEmbeddedIDL";
111const char _IgnoreImportLibrary[] = "IgnoreImportLibrary";
112const char _ImageHasSafeExceptionHandlers[] = "ImageHasSafeExceptionHandlers";
113const char _IgnoreSpecificDefaultLibraries[] = "IgnoreSpecificDefaultLibraries";
114const char _IgnoreStandardIncludePath[] = "IgnoreStandardIncludePath";
115const char _ImportLibrary[] = "ImportLibrary";
116const char _InlineFunctionExpansion[] = "InlineFunctionExpansion";
117const char _IntrinsicFunctions[] = "IntrinsicFunctions";
118const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
119const char _IntermediateDirectory[] = "IntermediateDirectory";
120const char _KeyContainer[] = "KeyContainer";
121const char _KeyFile[] = "KeyFile";
122const char _LanguageStandard[] = "LanguageStandard";
123const char _LanguageStandard_C[] = "LanguageStandard_C";
124const char _LargeAddressAware[] = "LargeAddressAware";
125const char _LinkDLL[] = "LinkDLL";
126const char _LinkErrorReporting[] = "LinkErrorReporting";
127const char _LinkIncremental[] = "LinkIncremental";
128const char _LinkStatus[] = "LinkStatus";
129const char _LinkTimeCodeGeneration[] = "LinkTimeCodeGeneration";
130const char _LocaleID[] = "LocaleID";
131const char _ManifestFile[] = "ManifestFile";
132const char _MapExports[] = "MapExports";
133const char _MapFileName[] = "MapFileName";
134const char _MergedIDLBaseFileName[] = "MergedIDLBaseFileName";
135const char _MergeSections[] = "MergeSections";
136const char _Message[] = "Message";
137const char _MidlCommandFile[] = "MidlCommandFile";
138const char _MinimalRebuild[] = "MinimalRebuild";
139const char _MkTypLibCompatible[] = "MkTypLibCompatible";
140const char _ModuleDefinitionFile[] = "ModuleDefinitionFile";
141const char _MultiProcessorCompilation[] = "MultiProcessorCompilation";
142const char _Name[] = "Name";
143const char _NoEntryPoint[] = "NoEntryPoint";
144const char _ObjectFileName[] = "ObjectFileName";
145const char _OmitDefaultLibName[] = "OmitDefaultLibName";
146const char _OmitFramePointers[] = "OmitFramePointers";
147const char _OpenMPSupport[] = "OpenMPSupport";
148const char _Optimization[] = "Optimization";
149const char _OptimizeReferences[] = "OptimizeReferences";
150const char _OutputDirectory[] = "OutputDirectory";
151const char _OutputFile[] = "OutputFile";
152const char _PlatformToolSet[] = "PlatformToolset";
153const char _PrecompiledHeader[] = "PrecompiledHeader";
154const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile";
155const char _PrecompiledHeaderOutputFile[] = "PrecompiledHeaderOutputFile";
156const char _PreprocessorDefinitions[] = "PreprocessorDefinitions";
157const char _PreprocessKeepComments[] = "PreprocessKeepComments";
158const char _PreprocessOutputPath[] = "PreprocessOutputPath";
159const char _PreprocessSuppressLineNumbers[] = "PreprocessSuppressLineNumbers";
160const char _PreprocessToFile[] = "PreprocessToFile";
161const char _PreventDllBinding[] = "PreventDllBinding";
162const char _PrimaryOutput[] = "PrimaryOutput";
163const char _ProcessorNumber[] = "ProcessorNumber";
164const char _ProgramDatabase[] = "ProgramDatabase";
165const char _ProgramDataBaseFileName[] = "ProgramDataBaseFileName";
166const char _ProgramDatabaseFile[] = "ProgramDatabaseFile";
167const char _ProxyFileName[] = "ProxyFileName";
168const char _RandomizedBaseAddress[] = "RandomizedBaseAddress";
169const char _RedirectOutputAndErrors[] = "RedirectOutputAndErrors";
170const char _RegisterOutput[] = "RegisterOutput";
171const char _ResourceOutputFileName[] = "ResourceOutputFileName";
172const char _RuntimeLibrary[] = "RuntimeLibrary";
173const char _RuntimeTypeInfo[] = "RuntimeTypeInfo";
174const char _SectionAlignment[] = "SectionAlignment";
175const char _ServerStubFile[] = "ServerStubFile";
176const char _SetChecksum[] = "SetChecksum";
177const char _ShowIncludes[] = "ShowIncludes";
178const char _ShowProgress[] = "ShowProgress";
179const char _SmallerTypeCheck[] = "SmallerTypeCheck";
180const char _StackCommitSize[] = "StackCommitSize";
181const char _StackReserveSize[] = "StackReserveSize";
182const char _StringPooling[] = "StringPooling";
183const char _StripPrivateSymbols[] = "StripPrivateSymbols";
184const char _StructMemberAlignment[] = "StructMemberAlignment";
185const char _SubSystem[] = "SubSystem";
186const char _SupportUnloadOfDelayLoadedDLL[] = "SupportUnloadOfDelayLoadedDLL";
187const char _SuppressCompilerWarnings[] = "SuppressCompilerWarnings";
188const char _SuppressStartupBanner[] = "SuppressStartupBanner";
189const char _SwapRunFromCD[] = "SwapRunFromCD";
190const char _SwapRunFromNet[] = "SwapRunFromNet";
191const char _TargetEnvironment[] = "TargetEnvironment";
192const char _TargetMachine[] = "TargetMachine";
193const char _TerminalServerAware[] = "TerminalServerAware";
194const char _TreatLinkerWarningAsErrors[] = "TreatLinkerWarningAsErrors";
195const char _TreatSpecificWarningsAsErrors[] = "TreatSpecificWarningsAsErrors";
196const char _TreatWarningAsError[] = "TreatWarningAsError";
197const char _TreatWChar_tAsBuiltInType[] = "TreatWChar_tAsBuiltInType";
198const char _TurnOffAssemblyGeneration[] = "TurnOffAssemblyGeneration";
199const char _TypeLibFormat[] = "TypeLibFormat";
200const char _TypeLibraryFile[] = "TypeLibraryFile";
201const char _TypeLibraryName[] = "TypeLibraryName";
202const char _TypeLibraryResourceID[] = "TypeLibraryResourceID";
203const char _UACExecutionLevel[] = "UACExecutionLevel";
204const char _UACUIAccess[] = "UACUIAccess";
205const char _UndefineAllPreprocessorDefinitions[]= "UndefineAllPreprocessorDefinitions";
206const char _UndefinePreprocessorDefinitions[] = "UndefinePreprocessorDefinitions";
207const char _UseFullPaths[] = "UseFullPaths";
208const char _UseOfATL[] = "UseOfATL";
209const char _UseOfMfc[] = "UseOfMfc";
210const char _UseUnicodeForAssemblerListing[] = "UseUnicodeForAssemblerListing";
211const char _ValidateAllParameters[] = "ValidateAllParameters";
212const char _Version[] = "Version";
213const char _WarnAsError[] = "WarnAsError";
214const char _WarningLevel[] = "WarningLevel";
215const char _WholeProgramOptimization[] = "WholeProgramOptimization";
216const char _WindowsMetadataFile[] = "WindowsMetadataFile";
217const char _XMLDocumentationFileName[] = "XMLDocumentationFileName";
218
219
220// XmlOutput stream functions ------------------------------
221inline XmlOutput::xml_output attrTagT(const char *name, const triState v)
222{
223 if(v == unset)
224 return noxml();
225 return tagValue(tagName: name, value: (v == _True ? "true" : "false"));
226}
227
228inline XmlOutput::xml_output attrTagL(const char *name, qint64 v)
229{
230 return tagValue(tagName: name, value: QString::number(v));
231}
232
233/*ifNot version*/
234inline XmlOutput::xml_output attrTagL(const char *name, qint64 v, qint64 ifn)
235{
236 if (v == ifn)
237 return noxml();
238 return tagValue(tagName: name, value: QString::number(v));
239}
240
241inline XmlOutput::xml_output attrTagS(const char *name, const QString &v)
242{
243 if(v.isEmpty())
244 return noxml();
245 return tagValue(tagName: name, value: v);
246}
247
248inline XmlOutput::xml_output attrTagX(const char *name, const QStringList &v, const char *s = ",")
249{
250 if(v.isEmpty())
251 return noxml();
252 QStringList temp = v;
253 temp.append(t: QString("%(%1)").arg(a: name));
254 return tagValue(tagName: name, value: temp.join(sep: s));
255}
256
257inline XmlOutput::xml_output valueTagX(const QStringList &v, const char *s = " ")
258{
259 if(v.isEmpty())
260 return noxml();
261 return valueTag(value: v.join(sep: s));
262}
263
264inline XmlOutput::xml_output valueTagDefX(const QStringList &v, const QString &tagName, const char *s = " ")
265{
266 if(v.isEmpty())
267 return noxml();
268 QStringList temp = v;
269 temp.append(t: QString("%(%1)").arg(a: tagName));
270 return valueTag(value: temp.join(sep: s));
271}
272
273inline XmlOutput::xml_output valueTagT( const triState v)
274{
275 if(v == unset)
276 return noxml();
277 return valueTag(value: v == _True ? "true" : "false");
278}
279
280static QString commandLinesForOutput(QStringList commands)
281{
282 // MSBuild puts the contents of the custom commands into a batch file and calls it.
283 // As we want every sub-command to be error-checked (as is done by makefile-based
284 // backends), we insert the checks ourselves, using the undocumented jump target.
285 static QString errchk = QStringLiteral("if errorlevel 1 goto VCEnd");
286 for (int i = commands.size() - 2; i >= 0; --i) {
287 if (!commands.at(i).startsWith(s: "rem", cs: Qt::CaseInsensitive))
288 commands.insert(i: i + 1, t: errchk);
289 }
290 return commands.join(sep: "\r\n");
291}
292
293static QString unquote(const QString &value)
294{
295 QString result = value;
296 result.replace(before: QLatin1String("\\\""), after: QLatin1String("\""));
297 return result;
298}
299
300static QStringList unquote(const QStringList &values)
301{
302 QStringList result;
303 result.reserve(asize: values.size());
304 for (int i = 0; i < values.size(); ++i)
305 result << unquote(value: values.at(i));
306 return result;
307}
308
309// Tree file generation ---------------------------------------------
310void XTreeNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName,
311 VCProject &tool, const QString &filter)
312{
313 if (children.size()) {
314 // Filter
315 QString tempFilterName;
316 ChildrenMap::ConstIterator it, end = children.constEnd();
317 if (!tagName.isEmpty()) {
318 tempFilterName.append(s: filter);
319 tempFilterName.append(s: "\\");
320 tempFilterName.append(s: tagName);
321 xmlFilter << tag(name: _ItemGroup);
322 xmlFilter << tag(name: "Filter")
323 << attrTag(name: "Include", value: tempFilterName)
324 << closetag();
325 xmlFilter << closetag();
326 }
327 // First round, do nested filters
328 for (it = children.constBegin(); it != end; ++it)
329 if ((*it)->children.size())
330 {
331 if ( !tempFilterName.isEmpty() )
332 (*it)->generateXML(xml, xmlFilter, tagName: it.key(), tool, filter: tempFilterName);
333 else
334 (*it)->generateXML(xml, xmlFilter, tagName: it.key(), tool, filter);
335 }
336 // Second round, do leafs
337 for (it = children.constBegin(); it != end; ++it)
338 if (!(*it)->children.size())
339 {
340 if ( !tempFilterName.isEmpty() )
341 (*it)->generateXML(xml, xmlFilter, tagName: it.key(), tool, filter: tempFilterName);
342 else
343 (*it)->generateXML(xml, xmlFilter, tagName: it.key(), tool, filter);
344 }
345 } else {
346 // Leaf
347 xml << tag(name: _ItemGroup);
348 xmlFilter << tag(name: _ItemGroup);
349 VCXProjectWriter::outputFileConfigs(project&: tool, xml, xmlFilter, info, filtername: filter);
350 xmlFilter << closetag();
351 xml << closetag();
352 }
353}
354
355// Flat file generation ---------------------------------------------
356void XFlatNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &/*tagName*/,
357 VCProject &tool, const QString &filter)
358{
359 if (children.size()) {
360 ChildrenMapFlat::ConstIterator it = children.constBegin();
361 ChildrenMapFlat::ConstIterator end = children.constEnd();
362 xml << tag(name: _ItemGroup);
363 xmlFilter << tag(name: _ItemGroup);
364 for (; it != end; ++it) {
365 VCXProjectWriter::outputFileConfigs(project&: tool, xml, xmlFilter, info: (*it), filtername: filter);
366 }
367 xml << closetag();
368 xmlFilter << closetag();
369 }
370}
371
372void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
373{
374 xml.setIndentString(" ");
375
376 xml << decl(version: "1.0", encoding: "utf-8")
377 << tag(name: "Project")
378 << attrTag(name: "DefaultTargets",value: "Build")
379 << attrTagToolsVersion(config: tool.Configuration)
380 << attrTag(name: "xmlns", value: "http://schemas.microsoft.com/developer/msbuild/2003")
381 << tag(name: "ItemGroup")
382 << attrTag(name: "Label", value: "ProjectConfigurations");
383
384 xml << tag(name: "ProjectConfiguration")
385 << attrTag(name: "Include" , value: tool.Configuration.Name)
386 << tagValue(tagName: "Configuration", value: tool.Configuration.ConfigurationName)
387 << tagValue(tagName: "Platform", value: tool.PlatformName)
388 << closetag();
389
390 xml << closetag()
391 << tag(name: "PropertyGroup")
392 << attrTag(name: "Label", value: "Globals")
393 << tagValue(tagName: "ProjectGuid", value: tool.ProjectGUID)
394 << tagValue(tagName: "RootNamespace", value: tool.Name)
395 << tagValue(tagName: "Keyword", value: tool.Keyword)
396 << closetag();
397
398 // config part.
399 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
400
401 write(xml, tool.Configuration);
402 const QString condition = generateCondition(config: tool.Configuration);
403
404 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.props");
405
406 // Extension settings
407 xml << tag(name: "ImportGroup")
408 << attrTag(name: "Label", value: "ExtensionSettings")
409 << closetag();
410
411 // PropertySheets
412 xml << tag(name: "ImportGroup")
413 << attrTag(name: "Condition", value: condition)
414 << attrTag(name: "Label", value: "PropertySheets");
415
416 xml << tag(name: "Import")
417 << attrTag(name: "Project", value: "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props")
418 << attrTag(name: "Condition", value: "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')")
419 << closetag()
420 << closetag();
421
422 // UserMacros
423 xml << tag(name: "PropertyGroup")
424 << attrTag(name: "Label", value: "UserMacros")
425 << closetag();
426
427 xml << tag(name: "PropertyGroup");
428
429 if ( !tool.Configuration.OutputDirectory.isEmpty() ) {
430 xml<< tag(name: "OutDir")
431 << attrTag(name: "Condition", value: condition)
432 << valueTag(value: tool.Configuration.OutputDirectory);
433 }
434 if ( !tool.Configuration.IntermediateDirectory.isEmpty() ) {
435 xml<< tag(name: "IntDir")
436 << attrTag(name: "Condition", value: condition)
437 << valueTag(value: tool.Configuration.IntermediateDirectory);
438 }
439 if ( !tool.Configuration.PrimaryOutput.isEmpty() ) {
440 xml<< tag(name: "TargetName")
441 << attrTag(name: "Condition", value: condition)
442 << valueTag(value: tool.Configuration.PrimaryOutput);
443 }
444 if (!tool.Configuration.PrimaryOutputExtension.isEmpty()) {
445 xml<< tag(name: "TargetExt")
446 << attrTag(name: "Condition", value: condition)
447 << valueTag(value: tool.Configuration.PrimaryOutputExtension);
448 }
449 if ( tool.Configuration.linker.IgnoreImportLibrary != unset) {
450 xml<< tag(name: "IgnoreImportLibrary")
451 << attrTag(name: "Condition", value: condition)
452 << valueTagT(v: tool.Configuration.linker.IgnoreImportLibrary);
453 }
454
455 if ( tool.Configuration.linker.LinkIncremental != linkIncrementalDefault) {
456 const triState ts = (tool.Configuration.linker.LinkIncremental == linkIncrementalYes ? _True : _False);
457 xml<< tag(name: "LinkIncremental")
458 << attrTag(name: "Condition", value: condition)
459 << valueTagT(v: ts);
460 }
461
462 if ( tool.Configuration.preBuild.ExcludedFromBuild != unset )
463 {
464 xml<< tag(name: "PreBuildEventUseInBuild")
465 << attrTag(name: "Condition", value: condition)
466 << valueTagT(v: !tool.Configuration.preBuild.ExcludedFromBuild);
467 }
468
469 if ( tool.Configuration.preLink.ExcludedFromBuild != unset )
470 {
471 xml<< tag(name: "PreLinkEventUseInBuild")
472 << attrTag(name: "Condition", value: condition)
473 << valueTagT(v: !tool.Configuration.preLink.ExcludedFromBuild);
474 }
475
476 if ( tool.Configuration.postBuild.ExcludedFromBuild != unset )
477 {
478 xml<< tag(name: "PostBuildEventUseInBuild")
479 << attrTag(name: "Condition", value: condition)
480 << valueTagT(v: !tool.Configuration.postBuild.ExcludedFromBuild);
481 }
482 xml << closetag();
483
484 xml << tag(name: "ItemDefinitionGroup")
485 << attrTag(name: "Condition", value: condition);
486
487 // ClCompile
488 write(xml, tool.Configuration.compiler);
489
490 // Link
491 write(xml, tool.Configuration.linker);
492
493 // Midl
494 write(xml, tool.Configuration.idl);
495
496 // ResourceCompiler
497 write(xml, tool.Configuration.resource);
498
499 // Post build event
500 if ( tool.Configuration.postBuild.ExcludedFromBuild != unset )
501 write(xml, tool.Configuration.postBuild);
502
503 // Pre build event
504 if ( tool.Configuration.preBuild.ExcludedFromBuild != unset )
505 write(xml, tool.Configuration.preBuild);
506
507 // Pre link event
508 if ( tool.Configuration.preLink.ExcludedFromBuild != unset )
509 write(xml, tool.Configuration.preLink);
510
511 xml << closetag();
512
513 QFile filterFile;
514 filterFile.setFileName(Option::output.fileName().append(s: ".filters"));
515 filterFile.open(flags: QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
516 QTextStream ts(&filterFile);
517 XmlOutput xmlFilter(ts, XmlOutput::NoConversion);
518
519 xmlFilter.setIndentString(" ");
520
521 xmlFilter << decl(version: "1.0", encoding: "utf-8")
522 << tag(name: "Project")
523 << attrTagToolsVersion(config: tool.Configuration)
524 << attrTag(name: "xmlns", value: "http://schemas.microsoft.com/developer/msbuild/2003");
525
526 xmlFilter << tag(name: "ItemGroup");
527
528 VCProject tempProj;
529 tempProj.SingleProjects += tool;
530
531 addFilters(project&: tempProj, xmlFilter, filterName: "Form Files");
532 addFilters(project&: tempProj, xmlFilter, filterName: "Generated Files");
533 addFilters(project&: tempProj, xmlFilter, filterName: "Header Files");
534 addFilters(project&: tempProj, xmlFilter, filterName: "LexYacc Files");
535 addFilters(project&: tempProj, xmlFilter, filterName: "Resource Files");
536 addFilters(project&: tempProj, xmlFilter, filterName: "Source Files");
537 addFilters(project&: tempProj, xmlFilter, filterName: "Translation Files");
538 addFilters(project&: tempProj, xmlFilter, filterName: "Deployment Files");
539 addFilters(project&: tempProj, xmlFilter, filterName: "Distribution Files");
540
541 tempProj.ExtraCompilers.reserve(asize: tool.ExtraCompilersFiles.size());
542 std::transform(first: tool.ExtraCompilersFiles.cbegin(), last: tool.ExtraCompilersFiles.cend(),
543 result: std::back_inserter(x&: tempProj.ExtraCompilers),
544 unary_op: [] (const VCFilter &filter) { return filter.Name; });
545 tempProj.ExtraCompilers.removeDuplicates();
546
547 for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x)
548 addFilters(project&: tempProj, xmlFilter, filterName: tempProj.ExtraCompilers.at(i: x));
549
550 xmlFilter << closetag();
551
552 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Source Files");
553 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Header Files");
554 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Generated Files");
555 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "LexYacc Files");
556 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Translation Files");
557 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Form Files");
558 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Resource Files");
559 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Deployment Files");
560 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Distribution Files");
561
562 for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x) {
563 outputFilter(project&: tempProj, xml, xmlFilter, filtername: tempProj.ExtraCompilers.at(i: x));
564 }
565
566 outputFilter(project&: tempProj, xml, xmlFilter, filtername: "Root Files");
567
568 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.targets");
569
570 xml << tag(name: "ImportGroup")
571 << attrTag(name: "Label", value: "ExtensionTargets")
572 << closetag();
573}
574
575void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
576{
577 if (tool.SingleProjects.size() == 0) {
578 warn_msg(t: WarnLogic, fmt: "Generator: .NET: no single project in merge project, no output");
579 return;
580 }
581
582 xml.setIndentString(" ");
583
584 xml << decl(version: "1.0", encoding: "utf-8")
585 << tag(name: "Project")
586 << attrTag(name: "DefaultTargets",value: "Build")
587 << attrTagToolsVersion(config: tool.SingleProjects.first().Configuration)
588 << attrTag(name: "xmlns", value: "http://schemas.microsoft.com/developer/msbuild/2003")
589 << tag(name: "ItemGroup")
590 << attrTag(name: "Label", value: "ProjectConfigurations");
591
592 for (int i = 0; i < tool.SingleProjects.size(); ++i) {
593 xml << tag(name: "ProjectConfiguration")
594 << attrTag(name: "Include" , value: tool.SingleProjects.at(i).Configuration.Name)
595 << tagValue(tagName: "Configuration", value: tool.SingleProjects.at(i).Configuration.ConfigurationName)
596 << tagValue(tagName: "Platform", value: tool.SingleProjects.at(i).PlatformName)
597 << closetag();
598 }
599
600 xml << closetag()
601 << tag(name: "PropertyGroup")
602 << attrTag(name: "Label", value: "Globals")
603 << tagValue(tagName: "ProjectGuid", value: tool.ProjectGUID)
604 << tagValue(tagName: "RootNamespace", value: tool.Name)
605 << tagValue(tagName: "Keyword", value: tool.Keyword);
606
607 if (!tool.WindowsTargetPlatformVersion.isEmpty())
608 xml << tagValue(tagName: "WindowsTargetPlatformVersion", value: tool.WindowsTargetPlatformVersion);
609 if (!tool.WindowsTargetPlatformMinVersion.isEmpty())
610 xml << tagValue(tagName: "WindowsTargetPlatformMinVersion", value: tool.WindowsTargetPlatformMinVersion);
611
612 xml << closetag();
613
614 // config part.
615 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
616 for (int i = 0; i < tool.SingleProjects.size(); ++i)
617 write(xml, tool.SingleProjects.at(i).Configuration);
618 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.props");
619
620 // Extension settings
621 xml << tag(name: "ImportGroup")
622 << attrTag(name: "Label", value: "ExtensionSettings")
623 << closetag();
624
625 // PropertySheets
626 for (int i = 0; i < tool.SingleProjects.size(); ++i) {
627 xml << tag(name: "ImportGroup")
628 << attrTag(name: "Condition", value: generateCondition(config: tool.SingleProjects.at(i).Configuration))
629 << attrTag(name: "Label", value: "PropertySheets");
630
631 xml << tag(name: "Import")
632 << attrTag(name: "Project", value: "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props")
633 << attrTag(name: "Condition", value: "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')")
634 << closetag()
635 << closetag();
636 }
637
638 // UserMacros
639 xml << tag(name: "PropertyGroup")
640 << attrTag(name: "Label", value: "UserMacros")
641 << closetag();
642
643 xml << tag(name: "PropertyGroup");
644 for (int i = 0; i < tool.SingleProjects.size(); ++i) {
645 const VCConfiguration &config = tool.SingleProjects.at(i).Configuration;
646 const QString condition = generateCondition(config);
647
648 if (!config.OutputDirectory.isEmpty()) {
649 xml << tag(name: "OutDir")
650 << attrTag(name: "Condition", value: condition)
651 << valueTag(value: config.OutputDirectory);
652 }
653 if (!config.IntermediateDirectory.isEmpty()) {
654 xml << tag(name: "IntDir")
655 << attrTag(name: "Condition", value: condition)
656 << valueTag(value: config.IntermediateDirectory);
657 }
658 if (!config.PrimaryOutput.isEmpty()) {
659 xml << tag(name: "TargetName")
660 << attrTag(name: "Condition", value: condition)
661 << valueTag(value: config.PrimaryOutput);
662 }
663 if (!config.PrimaryOutputExtension.isEmpty()) {
664 xml << tag(name: "TargetExt")
665 << attrTag(name: "Condition", value: condition)
666 << valueTag(value: config.PrimaryOutputExtension);
667 }
668 if (config.linker.IgnoreImportLibrary != unset) {
669 xml << tag(name: "IgnoreImportLibrary")
670 << attrTag(name: "Condition", value: condition)
671 << valueTagT(v: config.linker.IgnoreImportLibrary);
672 }
673
674 if (config.linker.LinkIncremental != linkIncrementalDefault) {
675 const triState ts = (config.linker.LinkIncremental == linkIncrementalYes ? _True : _False);
676 xml << tag(name: "LinkIncremental")
677 << attrTag(name: "Condition", value: condition)
678 << valueTagT(v: ts);
679 }
680
681 const triState generateManifest = config.linker.GenerateManifest;
682 if (generateManifest != unset) {
683 xml << tag(name: "GenerateManifest")
684 << attrTag(name: "Condition", value: condition)
685 << valueTagT(v: generateManifest);
686 }
687
688 if (config.preBuild.ExcludedFromBuild != unset)
689 {
690 xml << tag(name: "PreBuildEventUseInBuild")
691 << attrTag(name: "Condition", value: condition)
692 << valueTagT(v: !config.preBuild.ExcludedFromBuild);
693 }
694
695 if (config.preLink.ExcludedFromBuild != unset)
696 {
697 xml << tag(name: "PreLinkEventUseInBuild")
698 << attrTag(name: "Condition", value: condition)
699 << valueTagT(v: !config.preLink.ExcludedFromBuild);
700 }
701
702 if (config.postBuild.ExcludedFromBuild != unset)
703 {
704 xml << tag(name: "PostBuildEventUseInBuild")
705 << attrTag(name: "Condition", value: condition)
706 << valueTagT(v: !config.postBuild.ExcludedFromBuild);
707 }
708 }
709 xml << closetag();
710
711 for (int i = 0; i < tool.SingleProjects.size(); ++i) {
712 const VCConfiguration &config = tool.SingleProjects.at(i).Configuration;
713
714 xml << tag(name: "ItemDefinitionGroup")
715 << attrTag(name: "Condition", value: generateCondition(config));
716
717 // ClCompile
718 write(xml, config.compiler);
719
720 // Librarian / Linker
721 if (config.ConfigurationType == typeStaticLibrary)
722 write(xml, config.librarian);
723 else
724 write(xml, config.linker);
725
726 // Midl
727 write(xml, config.idl);
728
729 // ResourceCompiler
730 write(xml, config.resource);
731
732 // Post build event
733 if (config.postBuild.ExcludedFromBuild != unset)
734 write(xml, config.postBuild);
735
736 // Pre build event
737 if (config.preBuild.ExcludedFromBuild != unset)
738 write(xml, config.preBuild);
739
740 // Pre link event
741 if (config.preLink.ExcludedFromBuild != unset)
742 write(xml, config.preLink);
743
744 xml << closetag();
745
746 // windeployqt
747 if (!config.windeployqt.ExcludedFromBuild)
748 write(xml, config.windeployqt);
749 }
750
751 // The file filters are added in a separate file for MSBUILD.
752 QFile filterFile;
753 filterFile.setFileName(Option::output.fileName().append(s: ".filters"));
754 filterFile.open(flags: QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
755 QTextStream ts(&filterFile);
756 XmlOutput xmlFilter(ts, XmlOutput::NoConversion);
757
758 xmlFilter.setIndentString(" ");
759
760 xmlFilter << decl(version: "1.0", encoding: "utf-8")
761 << tag(name: "Project")
762 << attrTagToolsVersion(config: tool.SingleProjects.first().Configuration)
763 << attrTag(name: "xmlns", value: "http://schemas.microsoft.com/developer/msbuild/2003");
764
765 xmlFilter << tag(name: "ItemGroup");
766
767 addFilters(project&: tool, xmlFilter, filterName: "Form Files");
768 addFilters(project&: tool, xmlFilter, filterName: "Generated Files");
769 addFilters(project&: tool, xmlFilter, filterName: "Header Files");
770 addFilters(project&: tool, xmlFilter, filterName: "LexYacc Files");
771 addFilters(project&: tool, xmlFilter, filterName: "Resource Files");
772 addFilters(project&: tool, xmlFilter, filterName: "Source Files");
773 addFilters(project&: tool, xmlFilter, filterName: "Translation Files");
774 addFilters(project&: tool, xmlFilter, filterName: "Deployment Files");
775 addFilters(project&: tool, xmlFilter, filterName: "Distribution Files");
776
777 for (int x = 0; x < tool.ExtraCompilers.size(); ++x)
778 addFilters(project&: tool, xmlFilter, filterName: tool.ExtraCompilers.at(i: x));
779
780 xmlFilter << closetag();
781
782 outputFilter(project&: tool, xml, xmlFilter, filtername: "Source Files");
783 outputFilter(project&: tool, xml, xmlFilter, filtername: "Header Files");
784 outputFilter(project&: tool, xml, xmlFilter, filtername: "Generated Files");
785 outputFilter(project&: tool, xml, xmlFilter, filtername: "LexYacc Files");
786 outputFilter(project&: tool, xml, xmlFilter, filtername: "Translation Files");
787 outputFilter(project&: tool, xml, xmlFilter, filtername: "Form Files");
788 outputFilter(project&: tool, xml, xmlFilter, filtername: "Resource Files");
789 outputFilter(project&: tool, xml, xmlFilter, filtername: "Deployment Files");
790 outputFilter(project&: tool, xml, xmlFilter, filtername: "Distribution Files");
791 for (int x = 0; x < tool.ExtraCompilers.size(); ++x) {
792 outputFilter(project&: tool, xml, xmlFilter, filtername: tool.ExtraCompilers.at(i: x));
793 }
794 outputFilter(project&: tool, xml, xmlFilter, filtername: "Root Files");
795
796 xml << import(tagName: "Project", value: "$(VCTargetsPath)\\Microsoft.Cpp.targets")
797 << tag(name: "ImportGroup")
798 << attrTag(name: "Label", value: "ExtensionTargets")
799 << closetag();
800}
801
802static inline QString toString(asmListingOption option)
803{
804 switch (option) {
805 case asmListingNone:
806 break;
807 case asmListingAsmMachine:
808 return "AssemblyAndMachineCode";
809 case asmListingAsmMachineSrc:
810 return "All";
811 case asmListingAsmSrc:
812 return "AssemblyAndSourceCode";
813 case asmListingAssemblyOnly:
814 return "AssemblyCode";
815 }
816 return QString();
817}
818
819static inline QString toString(basicRuntimeCheckOption option)
820{
821 switch (option) {
822 case runtimeBasicCheckNone:
823 return "";
824 case runtimeCheckStackFrame:
825 return "StackFrameRuntimeCheck";
826 case runtimeCheckUninitVariables:
827 return "UninitializedLocalUsageCheck";
828 case runtimeBasicCheckAll:
829 return "EnableFastChecks";
830 }
831 return QString();
832}
833
834static inline QString toString(callingConventionOption option)
835{
836 switch (option) {
837 case callConventionDefault:
838 break;
839 case callConventionCDecl:
840 return "Cdecl";
841 case callConventionFastCall:
842 return "FastCall";
843 case callConventionStdCall:
844 return "StdCall";
845 }
846 return QString();
847}
848
849static inline QString toString(CompileAsOptions option)
850{
851 switch (option) {
852 case compileAsDefault:
853 break;
854 case compileAsC:
855 return "CompileAsC";
856 case compileAsCPlusPlus:
857 return "CompileAsCpp";
858 }
859 return QString();
860}
861
862static inline QString toString(compileAsManagedOptions option)
863{
864 switch (option) {
865 case managedDefault:
866 case managedAssemblySafe:
867 break;
868 case managedAssembly:
869 return "true";
870 case managedAssemblyPure:
871 return "Safe";
872 case managedAssemblyOldSyntax:
873 return "OldSyntax";
874 }
875 return QString();
876}
877
878static inline QString toString(debugOption option, DotNET compilerVersion)
879{
880 switch (option) {
881 case debugUnknown:
882 case debugLineInfoOnly:
883 break;
884 case debugDisabled:
885 if (compilerVersion <= NET2010)
886 break;
887 return "None";
888 case debugOldStyleInfo:
889 return "OldStyle";
890 case debugEditAndContinue:
891 return "EditAndContinue";
892 case debugEnabled:
893 return "ProgramDatabase";
894 }
895 return QString();
896}
897
898static inline QString toString(enhancedInstructionSetOption option)
899{
900 switch (option) {
901 case archNotSet:
902 break;
903 case archSSE:
904 return "StreamingSIMDExtensions";
905 case archSSE2:
906 return "StreamingSIMDExtensions2";
907 }
908 return QString();
909}
910
911static inline QString toString(exceptionHandling option)
912{
913 switch (option) {
914 case ehDefault:
915 break;
916 case ehNone:
917 return "false";
918 case ehNoSEH:
919 return "Sync";
920 case ehSEH:
921 return "Async";
922 }
923 return QString();
924}
925
926static inline QString toString(favorSizeOrSpeedOption option)
927{
928 switch (option) {
929 case favorNone:
930 break;
931 case favorSize:
932 return "Size";
933 case favorSpeed:
934 return "Speed";
935 }
936 return QString();
937}
938
939static inline QString toString(floatingPointModel option)
940{
941 switch (option) {
942 case floatingPointNotSet:
943 break;
944 case floatingPointFast:
945 return "Fast";
946 case floatingPointPrecise:
947 return "Precise";
948 case floatingPointStrict:
949 return "Strict";
950 }
951 return QString();
952}
953
954static inline QString toString(inlineExpansionOption option)
955{
956 switch (option) {
957 case expandDefault:
958 break;
959 case expandDisable:
960 return "Disabled";
961 case expandOnlyInline:
962 return "OnlyExplicitInline";
963 case expandAnySuitable:
964 return "AnySuitable";
965 }
966 return QString();
967}
968
969static inline QString toString(optimizeOption option)
970{
971 switch (option) {
972 case optimizeCustom:
973 case optimizeDefault:
974 break;
975 case optimizeDisabled:
976 return "Disabled";
977 case optimizeMinSpace:
978 return "MinSpace";
979 case optimizeMaxSpeed:
980 return "MaxSpeed";
981 case optimizeFull:
982 return "Full";
983 }
984 return QString();
985}
986
987static inline QString toString(pchOption option)
988{
989 switch (option) {
990 case pchUnset:
991 case pchGenerateAuto:
992 break;
993 case pchNone:
994 return "NotUsing";
995 case pchCreateUsingSpecific:
996 return "Create";
997 case pchUseUsingSpecific:
998 return "Use";
999 }
1000 return QString();
1001}
1002
1003static inline QString toString(runtimeLibraryOption option)
1004{
1005 switch (option) {
1006 case rtUnknown:
1007 case rtSingleThreaded:
1008 case rtSingleThreadedDebug:
1009 break;
1010 case rtMultiThreaded:
1011 return "MultiThreaded";
1012 case rtMultiThreadedDLL:
1013 return "MultiThreadedDLL";
1014 case rtMultiThreadedDebug:
1015 return "MultiThreadedDebug";
1016 case rtMultiThreadedDebugDLL:
1017 return "MultiThreadedDebugDLL";
1018 }
1019 return QString();
1020}
1021
1022static inline QString toString(structMemberAlignOption option)
1023{
1024 switch (option) {
1025 case alignNotSet:
1026 break;
1027 case alignSingleByte:
1028 return "1Byte";
1029 case alignTwoBytes:
1030 return "2Bytes";
1031 case alignFourBytes:
1032 return "4Bytes";
1033 case alignEightBytes:
1034 return "8Bytes";
1035 case alignSixteenBytes:
1036 return "16Bytes";
1037 }
1038 return QString();
1039}
1040
1041static inline QString toString(warningLevelOption option)
1042{
1043 switch (option) {
1044 case warningLevelUnknown:
1045 break;
1046 case warningLevel_0:
1047 return "TurnOffAllWarnings";
1048 case warningLevel_1:
1049 return "Level1";
1050 case warningLevel_2:
1051 return "Level2";
1052 case warningLevel_3:
1053 return "Level3";
1054 case warningLevel_4:
1055 return "Level4";
1056 }
1057 return QString();
1058}
1059
1060static inline QString toString(optLinkTimeCodeGenType option)
1061{
1062 switch (option) {
1063 case optLTCGDefault:
1064 break;
1065 case optLTCGEnabled:
1066 return "UseLinkTimeCodeGeneration";
1067 case optLTCGIncremental:
1068 return "UseFastLinkTimeCodeGeneration";
1069 case optLTCGInstrument:
1070 return "PGInstrument";
1071 case optLTCGOptimize:
1072 return "PGOptimization";
1073 case optLTCGUpdate:
1074 return "PGUpdate";
1075 }
1076 return QString();
1077}
1078
1079static inline QString toString(subSystemOption option)
1080{
1081 switch (option) {
1082 case subSystemNotSet:
1083 break;
1084 case subSystemConsole:
1085 return "Console";
1086 case subSystemWindows:
1087 return "Windows";
1088 }
1089 return QString();
1090}
1091
1092static inline QString toString(triState genDebugInfo, linkerDebugOption option)
1093{
1094 switch (genDebugInfo) {
1095 case unset:
1096 break;
1097 case _False:
1098 return "false";
1099 case _True:
1100 if (option == linkerDebugOptionFastLink)
1101 return "DebugFastLink";
1102 else if (option == linkerDebugOptionFull)
1103 return "DebugFull";
1104 return "true";
1105 }
1106 return QString();
1107}
1108
1109static inline QString toString(machineTypeOption option)
1110{
1111 switch (option) {
1112 case machineNotSet:
1113 break;
1114 case machineX86:
1115 return "MachineX86";
1116 case machineX64:
1117 return "MachineX64";
1118 }
1119 return QString();
1120}
1121
1122static inline QString toString(midlCharOption option)
1123{
1124 switch (option) {
1125 case midlCharUnsigned:
1126 return "Unsigned";
1127 case midlCharSigned:
1128 return "Signed";
1129 case midlCharAscii7:
1130 return "Ascii";
1131 }
1132 return QString();
1133}
1134
1135static inline QString toString(midlErrorCheckOption option)
1136{
1137 switch (option) {
1138 case midlEnableCustom:
1139 break;
1140 case midlDisableAll:
1141 return "None";
1142 case midlEnableAll:
1143 return "All";
1144 }
1145 return QString();
1146}
1147
1148static inline QString toString(midlStructMemberAlignOption option)
1149{
1150 switch (option) {
1151 case midlAlignNotSet:
1152 break;
1153 case midlAlignSingleByte:
1154 return "1";
1155 case midlAlignTwoBytes:
1156 return "2";
1157 case midlAlignFourBytes:
1158 return "4";
1159 case midlAlignEightBytes:
1160 return "8";
1161 case midlAlignSixteenBytes:
1162 return "16";
1163 }
1164 return QString();
1165}
1166
1167static inline QString toString(midlTargetEnvironment option)
1168{
1169 switch (option) {
1170 case midlTargetNotSet:
1171 break;
1172 case midlTargetWin32:
1173 return "Win32";
1174 case midlTargetWin64:
1175 return "X64";
1176 }
1177 return QString();
1178}
1179
1180static inline QString toString(midlWarningLevelOption option)
1181{
1182 switch (option) {
1183 case midlWarningLevel_0:
1184 return "0";
1185 case midlWarningLevel_1:
1186 return "1";
1187 case midlWarningLevel_2:
1188 return "2";
1189 case midlWarningLevel_3:
1190 return "3";
1191 case midlWarningLevel_4:
1192 return "4";
1193 }
1194 return QString();
1195}
1196
1197static inline QString toString(enumResourceLangID option)
1198{
1199 if (option == 0)
1200 return QString();
1201 else
1202 return QString::number(qlonglong(option));
1203}
1204
1205static inline QString toString(charSet option)
1206{
1207 switch (option) {
1208 case charSetNotSet:
1209 return "NotSet";
1210 case charSetUnicode:
1211 return "Unicode";
1212 case charSetMBCS:
1213 return "MultiByte";
1214 }
1215 return QString();
1216}
1217
1218static inline QString toString(ConfigurationTypes option)
1219{
1220 switch (option) {
1221 case typeUnknown:
1222 case typeGeneric:
1223 break;
1224 case typeApplication:
1225 return "Application";
1226 case typeDynamicLibrary:
1227 return "DynamicLibrary";
1228 case typeStaticLibrary:
1229 return "StaticLibrary";
1230 }
1231 return QString();
1232}
1233
1234static inline QString toString(useOfATL option)
1235{
1236 switch (option) {
1237 case useATLNotSet:
1238 break;
1239 case useATLStatic:
1240 return "Static";
1241 case useATLDynamic:
1242 return "Dynamic";
1243 }
1244 return QString();
1245}
1246
1247static inline QString toString(useOfMfc option)
1248{
1249 switch (option) {
1250 case useMfcStdWin:
1251 break;
1252 case useMfcStatic:
1253 return "Static";
1254 case useMfcDynamic:
1255 return "Dynamic";
1256 }
1257 return QString();
1258}
1259
1260static inline triState toTriState(browseInfoOption option)
1261{
1262 switch (option)
1263 {
1264 case brInfoNone:
1265 return _False;
1266 case brAllInfo:
1267 case brNoLocalSymbols:
1268 return _True;
1269 }
1270 return unset;
1271}
1272
1273static inline triState toTriState(preprocessOption option)
1274{
1275 switch (option)
1276 {
1277 case preprocessUnknown:
1278 break;
1279 case preprocessNo:
1280 return _False;
1281 case preprocessNoLineNumbers:
1282 case preprocessYes:
1283 return _True;
1284 }
1285 return unset;
1286}
1287
1288static inline triState toTriState(optFoldingType option)
1289{
1290 switch (option)
1291 {
1292 case optFoldingDefault:
1293 break;
1294 case optNoFolding:
1295 return _False;
1296 case optFolding:
1297 return _True;
1298 }
1299 return unset;
1300}
1301
1302static inline triState toTriState(addressAwarenessType option)
1303{
1304 switch (option)
1305 {
1306 case addrAwareDefault:
1307 return unset;
1308 case addrAwareNoLarge:
1309 return _False;
1310 case addrAwareLarge:
1311 return _True;
1312 }
1313 return unset;
1314}
1315
1316static inline triState toTriState(linkIncrementalType option)
1317{
1318 switch (option)
1319 {
1320 case linkIncrementalDefault:
1321 return unset;
1322 case linkIncrementalNo:
1323 return _False;
1324 case linkIncrementalYes:
1325 return _True;
1326 }
1327 return unset;
1328}
1329
1330static inline triState toTriState(linkProgressOption option)
1331{
1332 switch (option)
1333 {
1334 case linkProgressNotSet:
1335 return unset;
1336 case linkProgressAll:
1337 case linkProgressLibs:
1338 return _True;
1339 }
1340 return unset;
1341}
1342
1343static inline triState toTriState(optRefType option)
1344{
1345 switch (option)
1346 {
1347 case optReferencesDefault:
1348 return unset;
1349 case optNoReferences:
1350 return _False;
1351 case optReferences:
1352 return _True;
1353 }
1354 return unset;
1355}
1356
1357static inline triState toTriState(termSvrAwarenessType option)
1358{
1359 switch (option)
1360 {
1361 case termSvrAwareDefault:
1362 return unset;
1363 case termSvrAwareNo:
1364 return _False;
1365 case termSvrAwareYes:
1366 return _True;
1367 }
1368 return unset;
1369}
1370
1371static XmlOutput::xml_output fixedProgramDataBaseFileNameOutput(const VCCLCompilerTool &tool)
1372{
1373 if (tool.config->CompilerVersion >= NET2012
1374 && tool.DebugInformationFormat == debugDisabled
1375 && tool.ProgramDataBaseFileName.isEmpty()) {
1376 // Force the creation of an empty tag to work-around Visual Studio bug. See QTBUG-35570.
1377 return tagValue(tagName: _ProgramDataBaseFileName, value: tool.ProgramDataBaseFileName);
1378 }
1379 return attrTagS(name: _ProgramDataBaseFileName, v: tool.ProgramDataBaseFileName);
1380}
1381
1382void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
1383{
1384 xml
1385 << tag(name: _CLCompile)
1386 << attrTagX(name: _AdditionalIncludeDirectories, v: tool.AdditionalIncludeDirectories, s: ";")
1387 << attrTagX(name: _AdditionalOptions, v: tool.AdditionalOptions, s: " ")
1388 << attrTagX(name: _AdditionalUsingDirectories, v: tool.AdditionalUsingDirectories, s: ";")
1389 << attrTagS(name: _AssemblerListingLocation, v: tool.AssemblerListingLocation)
1390 << attrTagS(name: _AssemblerOutput, v: toString(option: tool.AssemblerOutput))
1391 << attrTagS(name: _BasicRuntimeChecks, v: toString(option: tool.BasicRuntimeChecks))
1392 << attrTagT(name: _BrowseInformation, v: toTriState(option: tool.BrowseInformation))
1393 << attrTagS(name: _BrowseInformationFile, v: tool.BrowseInformationFile)
1394 << attrTagT(name: _BufferSecurityCheck, v: tool.BufferSecurityCheck)
1395 << attrTagS(name: _CallingConvention, v: toString(option: tool.CallingConvention))
1396 << attrTagS(name: _CompileAs, v: toString(option: tool.CompileAs))
1397 << attrTagS(name: _CompileAsManaged, v: toString(option: tool.CompileAsManaged))
1398 << attrTagT(name: _CompileAsWinRT, v: tool.CompileAsWinRT)
1399 << attrTagT(name: _CreateHotpatchableImage, v: tool.CreateHotpatchableImage)
1400 << attrTagS(name: _DebugInformationFormat, v: toString(option: tool.DebugInformationFormat,
1401 compilerVersion: tool.config->CompilerVersion))
1402 << attrTagT(name: _DisableLanguageExtensions, v: tool.DisableLanguageExtensions)
1403 << attrTagX(name: _DisableSpecificWarnings, v: tool.DisableSpecificWarnings, s: ";")
1404 << attrTagS(name: _EnableEnhancedInstructionSet, v: toString(option: tool.EnableEnhancedInstructionSet))
1405 << attrTagT(name: _EnableFiberSafeOptimizations, v: tool.EnableFiberSafeOptimizations)
1406 << attrTagT(name: _EnablePREfast, v: tool.EnablePREfast)
1407 << attrTagS(name: _ErrorReporting, v: tool.ErrorReporting)
1408 << attrTagS(name: _ExceptionHandling, v: toString(option: tool.ExceptionHandling))
1409 << attrTagT(name: _ExpandAttributedSource, v: tool.ExpandAttributedSource)
1410 << attrTagS(name: _FavorSizeOrSpeed, v: toString(option: tool.FavorSizeOrSpeed))
1411 << attrTagT(name: _FloatingPointExceptions, v: tool.FloatingPointExceptions)
1412 << attrTagS(name: _FloatingPointModel, v: toString(option: tool.FloatingPointModel))
1413 << attrTagT(name: _ForceConformanceInForLoopScope, v: tool.ForceConformanceInForLoopScope)
1414 << attrTagX(name: _ForcedIncludeFiles, v: tool.ForcedIncludeFiles, s: ";")
1415 << attrTagX(name: _ForcedUsingFiles, v: tool.ForcedUsingFiles, s: ";")
1416 << attrTagT(name: _FunctionLevelLinking, v: tool.EnableFunctionLevelLinking)
1417 << attrTagT(name: _GenerateXMLDocumentationFiles, v: tool.GenerateXMLDocumentationFiles)
1418 << attrTagT(name: _IgnoreStandardIncludePath, v: tool.IgnoreStandardIncludePath)
1419 << attrTagS(name: _InlineFunctionExpansion, v: toString(option: tool.InlineFunctionExpansion))
1420 << attrTagT(name: _IntrinsicFunctions, v: tool.EnableIntrinsicFunctions)
1421 << attrTagT(name: _MinimalRebuild, v: tool.MinimalRebuild)
1422 << attrTagT(name: _MultiProcessorCompilation, v: tool.MultiProcessorCompilation)
1423 << attrTagS(name: _LanguageStandard, v: tool.LanguageStandard)
1424 << attrTagS(name: _LanguageStandard_C, v: tool.LanguageStandard_C)
1425 << attrTagS(name: _ObjectFileName, v: tool.ObjectFile)
1426 << attrTagT(name: _OmitDefaultLibName, v: tool.OmitDefaultLibName)
1427 << attrTagT(name: _OmitFramePointers, v: tool.OmitFramePointers)
1428 << attrTagT(name: _OpenMPSupport, v: tool.OpenMP)
1429 << attrTagS(name: _Optimization, v: toString(option: tool.Optimization))
1430 << attrTagS(name: _PrecompiledHeader, v: toString(option: tool.UsePrecompiledHeader))
1431 << attrTagS(name: _PrecompiledHeaderFile, v: tool.PrecompiledHeaderThrough)
1432 << attrTagS(name: _PrecompiledHeaderOutputFile, v: tool.PrecompiledHeaderFile)
1433 << attrTagT(name: _PreprocessKeepComments, v: tool.KeepComments)
1434 << attrTagX(name: _PreprocessorDefinitions, v: unquote(values: tool.PreprocessorDefinitions), s: ";")
1435 << attrTagS(name: _PreprocessOutputPath, v: tool.PreprocessOutputPath)
1436 << attrTagT(name: _PreprocessSuppressLineNumbers, v: tool.PreprocessSuppressLineNumbers)
1437 << attrTagT(name: _PreprocessToFile, v: toTriState(option: tool.GeneratePreprocessedFile))
1438 << fixedProgramDataBaseFileNameOutput(tool)
1439 << attrTagS(name: _ProcessorNumber, v: tool.MultiProcessorCompilationProcessorCount)
1440 << attrTagS(name: _RuntimeLibrary, v: toString(option: tool.RuntimeLibrary))
1441 << attrTagT(name: _RuntimeTypeInfo, v: tool.RuntimeTypeInfo)
1442 << attrTagT(name: _ShowIncludes, v: tool.ShowIncludes)
1443 << attrTagT(name: _SmallerTypeCheck, v: tool.SmallerTypeCheck)
1444 << attrTagT(name: _StringPooling, v: tool.StringPooling)
1445 << attrTagS(name: _StructMemberAlignment, v: toString(option: tool.StructMemberAlignment))
1446 << attrTagT(name: _SuppressStartupBanner, v: tool.SuppressStartupBanner)
1447 << attrTagX(name: _TreatSpecificWarningsAsErrors, v: tool.TreatSpecificWarningsAsErrors, s: ";")
1448 << attrTagT(name: _TreatWarningAsError, v: tool.WarnAsError)
1449 << attrTagT(name: _TreatWChar_tAsBuiltInType, v: tool.TreatWChar_tAsBuiltInType)
1450 << attrTagT(name: _UndefineAllPreprocessorDefinitions, v: tool.UndefineAllPreprocessorDefinitions)
1451 << attrTagX(name: _UndefinePreprocessorDefinitions, v: tool.UndefinePreprocessorDefinitions, s: ";")
1452 << attrTagT(name: _UseFullPaths, v: tool.DisplayFullPaths)
1453 << attrTagT(name: _UseUnicodeForAssemblerListing, v: tool.UseUnicodeForAssemblerListing)
1454 << attrTagS(name: _WarningLevel, v: toString(option: tool.WarningLevel))
1455 << attrTagT(name: _WholeProgramOptimization, v: tool.WholeProgramOptimization)
1456 << attrTagS(name: _XMLDocumentationFileName, v: tool.XMLDocumentationFileName)
1457 << closetag(toTag: _CLCompile);
1458}
1459
1460void VCXProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
1461{
1462 xml
1463 << tag(name: _Link)
1464 << attrTagX(name: _AdditionalDependencies, v: tool.AdditionalDependencies, s: ";")
1465 << attrTagX(name: _AdditionalLibraryDirectories, v: tool.AdditionalLibraryDirectories, s: ";")
1466 << attrTagX(name: _AdditionalManifestDependencies, v: tool.AdditionalManifestDependencies, s: ";")
1467 << attrTagX(name: _AdditionalOptions, v: tool.AdditionalOptions, s: " ")
1468 << attrTagX(name: _AddModuleNamesToAssembly, v: tool.AddModuleNamesToAssembly, s: ";")
1469 << attrTagT(name: _AllowIsolation, v: tool.AllowIsolation)
1470 << attrTagT(name: _AssemblyDebug, v: tool.AssemblyDebug)
1471 << attrTagX(name: _AssemblyLinkResource, v: tool.AssemblyLinkResource, s: ";")
1472 << attrTagS(name: _BaseAddress, v: tool.BaseAddress)
1473 << attrTagS(name: _CLRImageType, v: tool.CLRImageType)
1474 << attrTagS(name: _CLRSupportLastError, v: tool.CLRSupportLastError)
1475 << attrTagS(name: _CLRThreadAttribute, v: tool.CLRThreadAttribute)
1476 << attrTagT(name: _CLRUnmanagedCodeCheck, v: tool.CLRUnmanagedCodeCheck)
1477 << attrTagT(name: _DataExecutionPrevention, v: tool.DataExecutionPrevention)
1478 << attrTagX(name: _DelayLoadDLLs, v: tool.DelayLoadDLLs, s: ";")
1479 << attrTagT(name: _DelaySign, v: tool.DelaySign)
1480 << attrTagS(name: _EmbedManagedResourceFile, v: tool.LinkToManagedResourceFile)
1481 << attrTagT(name: _EnableCOMDATFolding, v: toTriState(option: tool.EnableCOMDATFolding))
1482 << attrTagT(name: _EnableUAC, v: tool.EnableUAC)
1483 << attrTagS(name: _EntryPointSymbol, v: tool.EntryPointSymbol)
1484 << attrTagX(name: _ForceSymbolReferences, v: tool.ForceSymbolReferences, s: ";")
1485 << attrTagS(name: _FunctionOrder, v: tool.FunctionOrder)
1486 << attrTagS(name: _GenerateDebugInformation, v: toString(genDebugInfo: tool.GenerateDebugInformation, option: tool.DebugInfoOption))
1487 << attrTagT(name: _GenerateManifest, v: tool.GenerateManifest)
1488 << attrTagT(name: _GenerateWindowsMetadata, v: tool.GenerateWindowsMetadata)
1489 << attrTagS(name: _WindowsMetadataFile, v: tool.GenerateWindowsMetadata == _True ? tool.WindowsMetadataFile : QString())
1490 << attrTagT(name: _GenerateMapFile, v: tool.GenerateMapFile)
1491 << attrTagL(name: _HeapCommitSize, v: tool.HeapCommitSize, /*ifNot*/ ifn: -1)
1492 << attrTagL(name: _HeapReserveSize, v: tool.HeapReserveSize, /*ifNot*/ ifn: -1)
1493 << attrTagT(name: _IgnoreAllDefaultLibraries, v: tool.IgnoreAllDefaultLibraries)
1494 << attrTagT(name: _IgnoreEmbeddedIDL, v: tool.IgnoreEmbeddedIDL)
1495 << attrTagT(name: _IgnoreImportLibrary, v: tool.IgnoreImportLibrary)
1496 << attrTagT(name: _ImageHasSafeExceptionHandlers, v: tool.ImageHasSafeExceptionHandlers)
1497 << attrTagX(name: _IgnoreSpecificDefaultLibraries, v: tool.IgnoreDefaultLibraryNames, s: ";")
1498 << attrTagS(name: _ImportLibrary, v: tool.ImportLibrary)
1499 << attrTagS(name: _KeyContainer, v: tool.KeyContainer)
1500 << attrTagS(name: _KeyFile, v: tool.KeyFile)
1501 << attrTagT(name: _LargeAddressAware, v: toTriState(option: tool.LargeAddressAware))
1502 << attrTagT(name: _LinkDLL, v: (tool.config->ConfigurationType == typeDynamicLibrary ? _True : unset))
1503 << attrTagS(name: _LinkErrorReporting, v: tool.LinkErrorReporting)
1504 << attrTagT(name: _LinkIncremental, v: toTriState(option: tool.LinkIncremental))
1505 << attrTagT(name: _LinkStatus, v: toTriState(option: tool.ShowProgress))
1506 << attrTagS(name: _LinkTimeCodeGeneration, v: toString(option: tool.LinkTimeCodeGeneration))
1507 << attrTagS(name: _ManifestFile, v: tool.ManifestFile)
1508 << attrTagT(name: _MapExports, v: tool.MapExports)
1509 << attrTagS(name: _MapFileName, v: tool.MapFileName)
1510 << attrTagS(name: _MergedIDLBaseFileName, v: tool.MergedIDLBaseFileName)
1511 << attrTagS(name: _MergeSections, v: tool.MergeSections)
1512 << attrTagS(name: _MidlCommandFile, v: tool.MidlCommandFile)
1513 << attrTagS(name: _ModuleDefinitionFile, v: tool.ModuleDefinitionFile)
1514 << attrTagT(name: _NoEntryPoint, v: tool.ResourceOnlyDLL)
1515 << attrTagT(name: _OptimizeReferences, v: toTriState(option: tool.OptimizeReferences))
1516 << attrTagS(name: _OutputFile, v: tool.OutputFile)
1517 << attrTagT(name: _PreventDllBinding, v: tool.PreventDllBinding)
1518 << attrTagS(name: _ProgramDatabaseFile, v: tool.ProgramDatabaseFile)
1519 << attrTagT(name: _RandomizedBaseAddress, v: tool.RandomizedBaseAddress)
1520 << attrTagT(name: _RegisterOutput, v: tool.RegisterOutput)
1521 << attrTagL(name: _SectionAlignment, v: tool.SectionAlignment, /*ifNot*/ ifn: -1)
1522 << attrTagT(name: _SetChecksum, v: tool.SetChecksum)
1523 << attrTagL(name: _StackCommitSize, v: tool.StackCommitSize, /*ifNot*/ ifn: -1)
1524 << attrTagL(name: _StackReserveSize, v: tool.StackReserveSize, /*ifNot*/ ifn: -1)
1525 << attrTagS(name: _StripPrivateSymbols, v: tool.StripPrivateSymbols)
1526 << attrTagS(name: _SubSystem, v: toString(option: tool.SubSystem))
1527// << attrTagT(_SupportNobindOfDelayLoadedDLL, tool.SupportNobindOfDelayLoadedDLL)
1528 << attrTagT(name: _SupportUnloadOfDelayLoadedDLL, v: tool.SupportUnloadOfDelayLoadedDLL)
1529 << attrTagT(name: _SuppressStartupBanner, v: tool.SuppressStartupBanner)
1530 << attrTagT(name: _SwapRunFromCD, v: tool.SwapRunFromCD)
1531 << attrTagT(name: _SwapRunFromNet, v: tool.SwapRunFromNet)
1532 << attrTagS(name: _TargetMachine, v: toString(option: tool.TargetMachine))
1533 << attrTagT(name: _TerminalServerAware, v: toTriState(option: tool.TerminalServerAware))
1534 << attrTagT(name: _TreatLinkerWarningAsErrors, v: tool.TreatWarningsAsErrors)
1535 << attrTagT(name: _TurnOffAssemblyGeneration, v: tool.TurnOffAssemblyGeneration)
1536 << attrTagS(name: _TypeLibraryFile, v: tool.TypeLibraryFile)
1537 << attrTagL(name: _TypeLibraryResourceID, v: tool.TypeLibraryResourceID, /*ifNot*/ ifn: 0)
1538 << attrTagS(name: _UACExecutionLevel, v: tool.UACExecutionLevel)
1539 << attrTagT(name: _UACUIAccess, v: tool.UACUIAccess)
1540 << attrTagS(name: _Version, v: tool.Version)
1541 << closetag(toTag: _Link);
1542}
1543
1544void VCXProjectWriter::write(XmlOutput &xml, const VCMIDLTool &tool)
1545{
1546 xml
1547 << tag(name: _Midl)
1548 << attrTagX(name: _AdditionalIncludeDirectories, v: tool.AdditionalIncludeDirectories, s: ";")
1549 << attrTagX(name: _AdditionalOptions, v: tool.AdditionalOptions, s: " ")
1550 << attrTagT(name: _ApplicationConfigurationMode, v: tool.ApplicationConfigurationMode)
1551 << attrTagS(name: _ClientStubFile, v: tool.ClientStubFile)
1552 << attrTagX(name: _CPreprocessOptions, v: tool.CPreprocessOptions, s: " ")
1553 << attrTagS(name: _DefaultCharType, v: toString(option: tool.DefaultCharType))
1554 << attrTagS(name: _DLLDataFileName, v: tool.DLLDataFileName)
1555 << attrTagS(name: _EnableErrorChecks, v: toString(option: tool.EnableErrorChecks))
1556 << attrTagT(name: _ErrorCheckAllocations, v: tool.ErrorCheckAllocations)
1557 << attrTagT(name: _ErrorCheckBounds, v: tool.ErrorCheckBounds)
1558 << attrTagT(name: _ErrorCheckEnumRange, v: tool.ErrorCheckEnumRange)
1559 << attrTagT(name: _ErrorCheckRefPointers, v: tool.ErrorCheckRefPointers)
1560 << attrTagT(name: _ErrorCheckStubData, v: tool.ErrorCheckStubData)
1561 << attrTagS(name: _GenerateClientFiles, v: tool.GenerateClientFiles)
1562 << attrTagS(name: _GenerateServerFiles, v: tool.GenerateServerFiles)
1563 << attrTagT(name: _GenerateStublessProxies, v: tool.GenerateStublessProxies)
1564 << attrTagT(name: _GenerateTypeLibrary, v: tool.GenerateTypeLibrary)
1565 << attrTagS(name: _HeaderFileName, v: tool.HeaderFileName)
1566 << attrTagT(name: _IgnoreStandardIncludePath, v: tool.IgnoreStandardIncludePath)
1567 << attrTagS(name: _InterfaceIdentifierFileName, v: tool.InterfaceIdentifierFileName)
1568 << attrTagL(name: _LocaleID, v: tool.LocaleID, /*ifNot*/ ifn: -1)
1569 << attrTagT(name: _MkTypLibCompatible, v: tool.MkTypLibCompatible)
1570 << attrTagS(name: _OutputDirectory, v: tool.OutputDirectory)
1571 << attrTagX(name: _PreprocessorDefinitions, v: tool.PreprocessorDefinitions, s: ";")
1572 << attrTagS(name: _ProxyFileName, v: tool.ProxyFileName)
1573 << attrTagS(name: _RedirectOutputAndErrors, v: tool.RedirectOutputAndErrors)
1574 << attrTagS(name: _ServerStubFile, v: tool.ServerStubFile)
1575 << attrTagS(name: _StructMemberAlignment, v: toString(option: tool.StructMemberAlignment))
1576 << attrTagT(name: _SuppressCompilerWarnings, v: tool.SuppressCompilerWarnings)
1577 << attrTagT(name: _SuppressStartupBanner, v: tool.SuppressStartupBanner)
1578 << attrTagS(name: _TargetEnvironment, v: toString(option: tool.TargetEnvironment))
1579 << attrTagS(name: _TypeLibFormat, v: tool.TypeLibFormat)
1580 << attrTagS(name: _TypeLibraryName, v: tool.TypeLibraryName)
1581 << attrTagX(name: _UndefinePreprocessorDefinitions, v: tool.UndefinePreprocessorDefinitions, s: ";")
1582 << attrTagT(name: _ValidateAllParameters, v: tool.ValidateAllParameters)
1583 << attrTagT(name: _WarnAsError, v: tool.WarnAsError)
1584 << attrTagS(name: _WarningLevel, v: toString(option: tool.WarningLevel))
1585 << closetag(toTag: _Midl);
1586}
1587
1588void VCXProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
1589{
1590 const QString condition = generateCondition(config: *tool.config);
1591
1592 if ( !tool.AdditionalDependencies.isEmpty() )
1593 {
1594 xml << tag(name: "AdditionalInputs")
1595 << attrTag(name: "Condition", value: condition)
1596 << valueTagDefX(v: tool.AdditionalDependencies, tagName: "AdditionalInputs", s: ";");
1597 }
1598
1599 if( !tool.CommandLine.isEmpty() )
1600 {
1601 xml << tag(name: "Command")
1602 << attrTag(name: "Condition", value: condition)
1603 << valueTag(value: commandLinesForOutput(commands: tool.CommandLine));
1604 }
1605
1606 if ( !tool.Description.isEmpty() )
1607 {
1608 xml << tag(name: "Message")
1609 << attrTag(name: "Condition", value: condition)
1610 << valueTag(value: tool.Description);
1611 }
1612
1613 if ( !tool.Outputs.isEmpty() )
1614 {
1615 xml << tag(name: "Outputs")
1616 << attrTag(name: "Condition", value: condition)
1617 << valueTagDefX(v: tool.Outputs, tagName: "Outputs", s: ";");
1618 }
1619}
1620
1621void VCXProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
1622{
1623 xml
1624 << tag(name: _Lib)
1625 << attrTagX(name: _AdditionalDependencies, v: tool.AdditionalDependencies, s: ";")
1626 << attrTagX(name: _AdditionalLibraryDirectories, v: tool.AdditionalLibraryDirectories, s: ";")
1627 << attrTagX(name: _AdditionalOptions, v: tool.AdditionalOptions, s: " ")
1628 << attrTagX(name: _ExportNamedFunctions, v: tool.ExportNamedFunctions, s: ";")
1629 << attrTagX(name: _ForceSymbolReferences, v: tool.ForceSymbolReferences, s: ";")
1630 << attrTagT(name: _IgnoreAllDefaultLibraries, v: tool.IgnoreAllDefaultLibraries)
1631 << attrTagX(name: _IgnoreSpecificDefaultLibraries, v: tool.IgnoreDefaultLibraryNames, s: ";")
1632 << attrTagS(name: _ModuleDefinitionFile, v: tool.ModuleDefinitionFile)
1633 << attrTagS(name: _OutputFile, v: tool.OutputFile)
1634 << attrTagT(name: _SuppressStartupBanner, v: tool.SuppressStartupBanner)
1635 << closetag(toTag: _Lib);
1636}
1637
1638void VCXProjectWriter::write(XmlOutput &xml, const VCResourceCompilerTool &tool)
1639{
1640 xml
1641 << tag(name: _ResourceCompile)
1642 << attrTagX(name: _AdditionalIncludeDirectories, v: tool.AdditionalIncludeDirectories, s: ";")
1643 << attrTagX(name: _AdditionalOptions, v: tool.AdditionalOptions, s: " ")
1644 << attrTagS(name: _Culture, v: toString(option: tool.Culture))
1645 << attrTagT(name: _IgnoreStandardIncludePath, v: tool.IgnoreStandardIncludePath)
1646 << attrTagX(name: _PreprocessorDefinitions, v: tool.PreprocessorDefinitions, s: ";")
1647 << attrTagS(name: _ResourceOutputFileName, v: tool.ResourceOutputFileName)
1648 << attrTagT(name: _ShowProgress, v: toTriState(option: tool.ShowProgress))
1649 << attrTagT(name: _SuppressStartupBanner, v: tool.SuppressStartupBanner)
1650 << closetag(toTag: _ResourceCompile);
1651}
1652
1653void VCXProjectWriter::write(XmlOutput &xml, const VCEventTool &tool)
1654{
1655 xml
1656 << tag(name: tool.EventName)
1657 << tag(name: _Command) << valueTag(value: commandLinesForOutput(commands: tool.CommandLine))
1658 << tag(name: _Message) << valueTag(value: tool.Description)
1659 << closetag(toTag: tool.EventName);
1660}
1661
1662void VCXProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
1663{
1664 Q_UNUSED(xml);
1665 Q_UNUSED(tool);
1666 // SmartDevice deployment not supported in VS 2010
1667}
1668
1669void VCXProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
1670{
1671 const QString name = QStringLiteral("WinDeployQt_") + tool.config->Name;
1672 xml << tag(name: "Target")
1673 << attrTag(name: _Name, value: name)
1674 << attrTag(name: "Condition", value: generateCondition(config: *tool.config))
1675 << attrTag(name: "Inputs", value: "$(OutDir)\\$(TargetName).exe")
1676 << attrTag(name: "Outputs", value: tool.Record)
1677 << tag(name: _Message)
1678 << attrTag(name: "Text", value: tool.CommandLine)
1679 << closetag()
1680 << tag(name: "Exec")
1681 << attrTag(name: "Command", value: tool.CommandLine)
1682 << closetag()
1683 << closetag()
1684 << tag(name: "Target")
1685 << attrTag(name: _Name, QStringLiteral("PopulateWinDeployQtItems_") + tool.config->Name)
1686 << attrTag(name: "Condition", value: generateCondition(config: *tool.config))
1687 << attrTag(name: "AfterTargets", value: "Link")
1688 << attrTag(name: "DependsOnTargets", value: name)
1689 << tag(name: "ReadLinesFromFile")
1690 << attrTag(name: "File", value: tool.Record)
1691 << tag(name: "Output")
1692 << attrTag(name: "TaskParameter", value: "Lines")
1693 << attrTag(name: "ItemName", value: "DeploymentItems")
1694 << closetag()
1695 << closetag()
1696 << tag(name: _ItemGroup)
1697 << tag(name: "None")
1698 << attrTag(name: "Include", value: "@(DeploymentItems)")
1699 << attrTagT(name: "DeploymentContent", v: _True)
1700 << closetag()
1701 << closetag()
1702 << closetag();
1703}
1704
1705void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
1706{
1707 xml << tag(name: "PropertyGroup")
1708 << attrTag(name: "Condition", value: generateCondition(config: tool))
1709 << attrTag(name: "Label", value: "Configuration")
1710 << attrTagS(name: _PlatformToolSet, v: tool.PlatformToolSet)
1711 << attrTagS(name: _OutputDirectory, v: tool.OutputDirectory)
1712 << attrTagT(name: _ATLMinimizesCRunTimeLibraryUsage, v: tool.ATLMinimizesCRunTimeLibraryUsage)
1713 << attrTagT(name: _BuildBrowserInformation, v: tool.BuildBrowserInformation)
1714 << attrTagS(name: _CharacterSet, v: toString(option: tool.CharacterSet))
1715 << attrTagS(name: _ConfigurationType, v: toString(option: tool.ConfigurationType))
1716 << attrTagS(name: _DeleteExtensionsOnClean, v: tool.DeleteExtensionsOnClean)
1717 << attrTagS(name: _ImportLibrary, v: tool.ImportLibrary)
1718 << attrTagS(name: _IntermediateDirectory, v: tool.IntermediateDirectory)
1719 << attrTagS(name: _PrimaryOutput, v: tool.PrimaryOutput)
1720 << attrTagS(name: _ProgramDatabase, v: tool.ProgramDatabase)
1721 << attrTagT(name: _RegisterOutput, v: tool.RegisterOutput)
1722 << attrTagS(name: _UseOfATL, v: toString(option: tool.UseOfATL))
1723 << attrTagS(name: _UseOfMfc, v: toString(option: tool.UseOfMfc))
1724 << attrTagT(name: _WholeProgramOptimization, v: tool.WholeProgramOptimization)
1725 << attrTagT(name: _EmbedManifest, v: tool.manifestTool.EmbedManifest)
1726 << closetag();
1727}
1728
1729void VCXProjectWriter::write(XmlOutput &xml, VCFilter &tool)
1730{
1731 Q_UNUSED(xml);
1732 Q_UNUSED(tool);
1733 // unused in this generator
1734}
1735
1736void VCXProjectWriter::addFilters(VCProject &project, XmlOutput &xmlFilter, const QString &filtername)
1737{
1738 bool added = false;
1739
1740 for (int i = 0; i < project.SingleProjects.size(); ++i) {
1741 const VCFilter filter = project.SingleProjects.at(i).filterByName(name: filtername);
1742 if(!filter.Files.isEmpty() && !added) {
1743 xmlFilter << tag(name: "Filter")
1744 << attrTag(name: "Include", value: filtername)
1745 << attrTagS(name: "UniqueIdentifier", v: filter.Guid)
1746 << attrTagS(name: "Extensions", v: filter.Filter)
1747 << attrTagT(name: "ParseFiles", v: filter.ParseFiles)
1748 << closetag();
1749 }
1750 }
1751}
1752
1753// outputs a given filter for all existing configurations of a project
1754void VCXProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filtername)
1755{
1756 QScopedPointer<XNode> root;
1757 if (project.SingleProjects.at(i: 0).flat_files)
1758 root.reset(other: new XFlatNode);
1759 else
1760 root.reset(other: new XTreeNode);
1761
1762 for (int i = 0; i < project.SingleProjects.size(); ++i) {
1763 const VCFilter filter = project.SingleProjects.at(i).filterByName(name: filtername);
1764 // Merge all files in this filter to root tree
1765 for (int x = 0; x < filter.Files.size(); ++x)
1766 root->addElement(file: filter.Files.at(i: x));
1767 }
1768
1769 if (!root->hasElements())
1770 return;
1771
1772 root->generateXML(xml, xmlFilter, tagName: "", tool&: project, filter: filtername); // output root tree
1773}
1774
1775static QString stringBeforeFirstBackslash(const QString &str)
1776{
1777 int idx = str.indexOf(c: QLatin1Char('\\'));
1778 return idx == -1 ? str : str.left(n: idx);
1779}
1780
1781// Output all configurations (by filtername) for a file (by info)
1782// A filters config output is in VCFilter.outputFileConfig()
1783void VCXProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter,
1784 const VCFilterFile &info, const QString &filtername)
1785{
1786 // In non-flat mode the filter names have directory suffixes, e.g. "Generated Files\subdir".
1787 const QString cleanFilterName = stringBeforeFirstBackslash(str: filtername);
1788
1789 // We need to check if the file has any custom build step.
1790 // If there is one then it has to be included with "CustomBuild Include"
1791 bool hasCustomBuildStep = false;
1792 QVarLengthArray<OutputFilterData> data(project.SingleProjects.size());
1793 for (int i = 0; i < project.SingleProjects.size(); ++i) {
1794 data[i].filter = project.SingleProjects.at(i).filterByName(name: cleanFilterName);
1795 if (!data[i].filter.Config) // only if the filter is not empty
1796 continue;
1797 VCFilter &filter = data[i].filter;
1798
1799 // Clearing each filter tool
1800 filter.useCustomBuildTool = false;
1801 filter.useCompilerTool = false;
1802 filter.CustomBuildTool = VCCustomBuildTool();
1803 filter.CustomBuildTool.config = filter.Config;
1804 filter.CompilerTool = VCCLCompilerTool();
1805 filter.CompilerTool.config = filter.Config;
1806
1807 VCFilterFile fileInFilter = filter.findFile(filePath: info.file, found: &data[i].inBuild);
1808 data[i].info = fileInFilter;
1809 data[i].inBuild &= !fileInFilter.excludeFromBuild;
1810 if (data[i].inBuild && filter.addExtraCompiler(info: fileInFilter))
1811 hasCustomBuildStep = true;
1812 }
1813
1814 bool fileAdded = false;
1815 for (int i = 0; i < project.SingleProjects.size(); ++i) {
1816 OutputFilterData *d = &data[i];
1817 if (!d->filter.Config) // only if the filter is not empty
1818 continue;
1819 if (outputFileConfig(d, xml, xmlFilter, filename: info.file, fullFilterName: filtername, fileAdded,
1820 hasCustomBuildStep)) {
1821 fileAdded = true;
1822 }
1823 }
1824
1825 if ( !fileAdded )
1826 outputFileConfig(xml, xmlFilter, fileName: info.file, filterName: filtername);
1827
1828 xml << closetag();
1829 xmlFilter << closetag();
1830}
1831
1832bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, XmlOutput &xmlFilter,
1833 const QString &filename, const QString &fullFilterName,
1834 bool fileAdded, bool hasCustomBuildStep)
1835{
1836 VCFilter &filter = d->filter;
1837 if (d->inBuild) {
1838 if (filter.Project->usePCH)
1839 filter.modifyPCHstage(str: filename);
1840 } else {
1841 // Excluded files uses an empty compiler stage
1842 if (d->info.excludeFromBuild)
1843 filter.useCompilerTool = true;
1844 }
1845
1846 // Actual XML output ----------------------------------
1847 if (hasCustomBuildStep || filter.useCustomBuildTool || filter.useCompilerTool
1848 || !d->inBuild || filter.Name.startsWith(s: "Deployment Files")) {
1849
1850 if (hasCustomBuildStep || filter.useCustomBuildTool)
1851 {
1852 if (!fileAdded) {
1853 fileAdded = true;
1854
1855 xmlFilter << tag(name: "CustomBuild")
1856 << attrTag(name: "Include", value: Option::fixPathToTargetOS(in: filename))
1857 << attrTagS(name: "Filter", v: fullFilterName);
1858
1859 xml << tag(name: "CustomBuild")
1860 << attrTag(name: "Include", value: Option::fixPathToTargetOS(in: filename));
1861
1862 if (filter.Name.startsWith(s: "Form Files")
1863 || filter.Name.startsWith(s: "Generated Files")
1864 || filter.Name.startsWith(s: "Resource Files")
1865 || filter.Name.startsWith(s: "Deployment Files"))
1866 xml << attrTagS(name: "FileType", v: "Document");
1867 }
1868
1869 filter.Project->projectWriter->write(xml, filter.CustomBuildTool);
1870 }
1871
1872 if (!fileAdded)
1873 {
1874 fileAdded = true;
1875 outputFileConfig(xml, xmlFilter, fileName: filename, filterName: fullFilterName);
1876 }
1877
1878 const QString condition = generateCondition(config: *filter.Config);
1879 if (!d->inBuild) {
1880 xml << tag(name: "ExcludedFromBuild")
1881 << attrTag(name: "Condition", value: condition)
1882 << valueTag(value: "true");
1883 }
1884
1885 if (filter.Name.startsWith(s: "Deployment Files") && d->inBuild) {
1886 xml << tag(name: "DeploymentContent")
1887 << attrTag(name: "Condition", value: condition)
1888 << valueTag(value: "true");
1889 }
1890
1891 if (filter.useCompilerTool) {
1892
1893 if ( !filter.CompilerTool.ForcedIncludeFiles.isEmpty() ) {
1894 xml << tag(name: "ForcedIncludeFiles")
1895 << attrTag(name: "Condition", value: condition)
1896 << valueTagX(v: filter.CompilerTool.ForcedIncludeFiles);
1897 }
1898
1899 if ( !filter.CompilerTool.PrecompiledHeaderThrough.isEmpty() ) {
1900 xml << tag(name: "PrecompiledHeaderFile")
1901 << attrTag(name: "Condition", value: condition)
1902 << valueTag(value: filter.CompilerTool.PrecompiledHeaderThrough);
1903 }
1904
1905 if (filter.CompilerTool.UsePrecompiledHeader != pchUnset) {
1906 xml << tag(name: "PrecompiledHeader")
1907 << attrTag(name: "Condition", value: condition)
1908 << valueTag(value: toString(option: filter.CompilerTool.UsePrecompiledHeader));
1909 }
1910 }
1911 }
1912
1913 return fileAdded;
1914}
1915
1916static bool isFileClCompatible(const QString &filePath)
1917{
1918 auto filePathEndsWith = [&filePath] (const QString &ext) {
1919 return filePath.endsWith(s: ext, cs: Qt::CaseInsensitive);
1920 };
1921 return std::any_of(first: Option::cpp_ext.cbegin(), last: Option::cpp_ext.cend(), pred: filePathEndsWith)
1922 || std::any_of(first: Option::c_ext.cbegin(), last: Option::c_ext.cend(), pred: filePathEndsWith);
1923}
1924
1925void VCXProjectWriter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter,
1926 const QString &filePath, const QString &filterName)
1927{
1928 const QString nativeFilePath = Option::fixPathToTargetOS(in: filePath);
1929 if (filterName.startsWith(s: "Source Files")) {
1930 xmlFilter << tag(name: "ClCompile")
1931 << attrTag(name: "Include", value: nativeFilePath)
1932 << attrTagS(name: "Filter", v: filterName);
1933 xml << tag(name: "ClCompile")
1934 << attrTag(name: "Include", value: nativeFilePath);
1935 } else if (filterName.startsWith(s: "Header Files")) {
1936 xmlFilter << tag(name: "ClInclude")
1937 << attrTag(name: "Include", value: nativeFilePath)
1938 << attrTagS(name: "Filter", v: filterName);
1939 xml << tag(name: "ClInclude")
1940 << attrTag(name: "Include", value: nativeFilePath);
1941 } else if (filterName.startsWith(s: "Generated Files") || filterName.startsWith(s: "Form Files")) {
1942 if (filePath.endsWith(s: ".h")) {
1943 xmlFilter << tag(name: "ClInclude")
1944 << attrTag(name: "Include", value: nativeFilePath)
1945 << attrTagS(name: "Filter", v: filterName);
1946 xml << tag(name: "ClInclude")
1947 << attrTag(name: "Include", value: nativeFilePath);
1948 } else if (isFileClCompatible(filePath)) {
1949 xmlFilter << tag(name: "ClCompile")
1950 << attrTag(name: "Include", value: nativeFilePath)
1951 << attrTagS(name: "Filter", v: filterName);
1952 xml << tag(name: "ClCompile")
1953 << attrTag(name: "Include", value: nativeFilePath);
1954 } else if (filePath.endsWith(s: ".res")) {
1955 xmlFilter << tag(name: "CustomBuild")
1956 << attrTag(name: "Include", value: nativeFilePath)
1957 << attrTagS(name: "Filter", v: filterName);
1958 xml << tag(name: "CustomBuild")
1959 << attrTag(name: "Include", value: nativeFilePath);
1960 } else {
1961 xmlFilter << tag(name: "CustomBuild")
1962 << attrTag(name: "Include", value: nativeFilePath)
1963 << attrTagS(name: "Filter", v: filterName);
1964 xml << tag(name: "CustomBuild")
1965 << attrTag(name: "Include", value: nativeFilePath);
1966 }
1967 } else if (filterName.startsWith(s: "Root Files")) {
1968 if (filePath.endsWith(s: ".rc")) {
1969 xmlFilter << tag(name: "ResourceCompile")
1970 << attrTag(name: "Include", value: nativeFilePath);
1971 xml << tag(name: "ResourceCompile")
1972 << attrTag(name: "Include", value: nativeFilePath);
1973 }
1974 } else {
1975 xmlFilter << tag(name: "None")
1976 << attrTag(name: "Include", value: nativeFilePath)
1977 << attrTagS(name: "Filter", v: filterName);
1978 xml << tag(name: "None")
1979 << attrTag(name: "Include", value: nativeFilePath);
1980 }
1981}
1982
1983QString VCXProjectWriter::generateCondition(const VCConfiguration &config)
1984{
1985 return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\'');
1986}
1987
1988XmlOutput::xml_output VCXProjectWriter::attrTagToolsVersion(const VCConfiguration &config)
1989{
1990 if (config.CompilerVersion >= NET2013)
1991 return noxml();
1992 return attrTag(name: "ToolsVersion", value: "4.0");
1993}
1994
1995QT_END_NAMESPACE
1996

source code of qtbase/qmake/generators/win32/msbuild_objectmodel.cpp