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