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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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