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