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 "msvc_objectmodel.h"
30#include "msvc_vcproj.h"
31#include "msvc_vcxproj.h"
32
33#include <ioutils.h>
34
35#include <qscopedpointer.h>
36#include <qfileinfo.h>
37#include <qregularexpression.h>
38
39using namespace QMakeInternal;
40
41QT_BEGIN_NAMESPACE
42
43static DotNET vsVersionFromString(const char *versionString)
44{
45 struct VSVersionMapping
46 {
47 const char *str;
48 DotNET version;
49 };
50 static VSVersionMapping mapping[] = {
51 { "7.0", NET2002 },
52 { "7.1", NET2003 },
53 { "8.0", NET2005 },
54 { "9.0", NET2008 },
55 { "10.0", NET2010 },
56 { "11.0", NET2012 },
57 { "12.0", NET2013 },
58 { "14.0", NET2015 },
59 { "15.0", NET2017 },
60 { "16.0", NET2019 }
61 };
62 DotNET result = NETUnknown;
63 for (const auto entry : mapping) {
64 if (strcmp(entry.str, versionString) == 0)
65 return entry.version;
66 }
67 return result;
68}
69
70DotNET vsVersionFromString(const ProString &versionString)
71{
72 return vsVersionFromString(versionString.toLatin1().constData());
73}
74
75// XML Tags ---------------------------------------------------------
76const char _Configuration[] = "Configuration";
77const char _Configurations[] = "Configurations";
78const char q_File[] = "File";
79const char _FileConfiguration[] = "FileConfiguration";
80const char q_Files[] = "Files";
81const char _Filter[] = "Filter";
82const char _Globals[] = "Globals";
83const char _Platform[] = "Platform";
84const char _Platforms[] = "Platforms";
85const char _Tool[] = "Tool";
86const char _VisualStudioProject[] = "VisualStudioProject";
87
88// XML Properties ---------------------------------------------------
89const char _AddModuleNamesToAssembly[] = "AddModuleNamesToAssembly";
90const char _AdditionalDependencies[] = "AdditionalDependencies";
91const char _AdditionalFiles[] = "AdditionalFiles";
92const char _AdditionalIncludeDirectories[] = "AdditionalIncludeDirectories";
93const char _AdditionalLibraryDirectories[] = "AdditionalLibraryDirectories";
94const char _AdditionalOptions[] = "AdditionalOptions";
95const char _AdditionalUsingDirectories[] = "AdditionalUsingDirectories";
96const char _AssemblerListingLocation[] = "AssemblerListingLocation";
97const char _AssemblerOutput[] = "AssemblerOutput";
98const char _ATLMinimizesCRunTimeLibraryUsage[] = "ATLMinimizesCRunTimeLibraryUsage";
99const char _BaseAddress[] = "BaseAddress";
100const char _BasicRuntimeChecks[] = "BasicRuntimeChecks";
101const char _BrowseInformation[] = "BrowseInformation";
102const char _BrowseInformationFile[] = "BrowseInformationFile";
103const char _BufferSecurityCheck[] = "BufferSecurityCheck";
104const char _BuildBrowserInformation[] = "BuildBrowserInformation";
105const char _CPreprocessOptions[] = "CPreprocessOptions";
106const char _CallingConvention[] = "CallingConvention";
107const char _CharacterSet[] = "CharacterSet";
108const char _CommandLine[] = "CommandLine";
109const char _CompileAs[] = "CompileAs";
110const char _CompileAsManaged[] = "CompileAsManaged";
111const char _CompileOnly[] = "CompileOnly";
112const char _ConfigurationType[] = "ConfigurationType";
113const char _Culture[] = "Culture";
114const char _DLLDataFileName[] = "DLLDataFileName";
115const char _DataExecutionPrevention[] = "DataExecutionPrevention";
116const char _DebugInformationFormat[] = "DebugInformationFormat";
117const char _DefaultCharType[] = "DefaultCharType";
118const char _DelayLoadDLLs[] = "DelayLoadDLLs";
119const char _DeleteExtensionsOnClean[] = "DeleteExtensionsOnClean";
120const char _Description[] = "Description";
121const char _Detect64BitPortabilityProblems[] = "Detect64BitPortabilityProblems";
122const char _DisableLanguageExtensions[] = "DisableLanguageExtensions";
123const char _DisableSpecificWarnings[] = "DisableSpecificWarnings";
124const char _EmbedManifest[] = "EmbedManifest";
125const char _EnableCOMDATFolding[] = "EnableCOMDATFolding";
126const char _EnableErrorChecks[] = "EnableErrorChecks";
127const char _EnableEnhancedInstructionSet[] = "EnableEnhancedInstructionSet";
128const char _EnableFiberSafeOptimizations[] = "EnableFiberSafeOptimizations";
129const char _EnableFunctionLevelLinking[] = "EnableFunctionLevelLinking";
130const char _EnableIntrinsicFunctions[] = "EnableIntrinsicFunctions";
131const char _EntryPointSymbol[] = "EntryPointSymbol";
132const char _ErrorCheckAllocations[] = "ErrorCheckAllocations";
133const char _ErrorCheckBounds[] = "ErrorCheckBounds";
134const char _ErrorCheckEnumRange[] = "ErrorCheckEnumRange";
135const char _ErrorCheckRefPointers[] = "ErrorCheckRefPointers";
136const char _ErrorCheckStubData[] = "ErrorCheckStubData";
137const char _ExceptionHandling[] = "ExceptionHandling";
138const char _ExcludedFromBuild[] = "ExcludedFromBuild";
139const char _ExpandAttributedSource[] = "ExpandAttributedSource";
140const char _ExportNamedFunctions[] = "ExportNamedFunctions";
141const char _FavorSizeOrSpeed[] = "FavorSizeOrSpeed";
142const char _FloatingPointModel[] = "FloatingPointModel";
143const char _FloatingPointExceptions[] = "FloatingPointExceptions";
144const char _ForceConformanceInForLoopScope[] = "ForceConformanceInForLoopScope";
145const char _ForceSymbolReferences[] = "ForceSymbolReferences";
146const char _ForcedIncludeFiles[] = "ForcedIncludeFiles";
147const char _ForcedUsingFiles[] = "ForcedUsingFiles";
148const char _FullIncludePath[] = "FullIncludePath";
149const char _FunctionOrder[] = "FunctionOrder";
150const char _GenerateDebugInformation[] = "GenerateDebugInformation";
151const char _GenerateMapFile[] = "GenerateMapFile";
152const char _GeneratePreprocessedFile[] = "GeneratePreprocessedFile";
153const char _GenerateStublessProxies[] = "GenerateStublessProxies";
154const char _GenerateTypeLibrary[] = "GenerateTypeLibrary";
155const char _GlobalOptimizations[] = "GlobalOptimizations";
156const char _HeaderFileName[] = "HeaderFileName";
157const char _HeapCommitSize[] = "HeapCommitSize";
158const char _HeapReserveSize[] = "HeapReserveSize";
159const char _IgnoreAllDefaultLibraries[] = "IgnoreAllDefaultLibraries";
160const char _IgnoreDefaultLibraryNames[] = "IgnoreDefaultLibraryNames";
161const char _IgnoreEmbeddedIDL[] = "IgnoreEmbeddedIDL";
162const char _IgnoreImportLibrary[] = "IgnoreImportLibrary";
163const char _IgnoreStandardIncludePath[] = "IgnoreStandardIncludePath";
164const char _ImportLibrary[] = "ImportLibrary";
165const char _ImproveFloatingPointConsistency[] = "ImproveFloatingPointConsistency";
166const char _InlineFunctionExpansion[] = "InlineFunctionExpansion";
167const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
168const char _IntermediateDirectory[] = "IntermediateDirectory";
169const char _KeepComments[] = "KeepComments";
170const char _LargeAddressAware[] = "LargeAddressAware";
171const char _LinkDLL[] = "LinkDLL";
172const char _LinkIncremental[] = "LinkIncremental";
173const char _LinkTimeCodeGeneration[] = "LinkTimeCodeGeneration";
174const char _LinkToManagedResourceFile[] = "LinkToManagedResourceFile";
175const char _MapExports[] = "MapExports";
176const char _MapFileName[] = "MapFileName";
177const char _MapLines[] = "MapLines ";
178const char _MergeSections[] = "MergeSections";
179const char _MergedIDLBaseFileName[] = "MergedIDLBaseFileName";
180const char _MidlCommandFile[] = "MidlCommandFile";
181const char _MinimalRebuild[] = "MinimalRebuild";
182const char _MkTypLibCompatible[] = "MkTypLibCompatible";
183const char _ModuleDefinitionFile[] = "ModuleDefinitionFile";
184const char _Name[] = "Name";
185const char _ObjectFile[] = "ObjectFile";
186const char _OmitFramePointers[] = "OmitFramePointers";
187const char _OpenMP[] = "OpenMP";
188const char _Optimization[] = "Optimization ";
189const char _OptimizeForProcessor[] = "OptimizeForProcessor";
190const char _OptimizeForWindows98[] = "OptimizeForWindows98";
191const char _OptimizeForWindowsApplication[] = "OptimizeForWindowsApplication";
192const char _OptimizeReferences[] = "OptimizeReferences";
193const char _OutputDirectory[] = "OutputDirectory";
194const char _OutputFile[] = "OutputFile";
195const char _Outputs[] = "Outputs";
196const char _ParseFiles[] = "ParseFiles";
197const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile";
198const char _PrecompiledHeaderThrough[] = "PrecompiledHeaderThrough";
199const char _PreprocessorDefinitions[] = "PreprocessorDefinitions";
200const char _PrimaryOutput[] = "PrimaryOutput";
201const char _ProjectGUID[] = "ProjectGUID";
202const char _Keyword[] = "Keyword";
203const char _ProjectType[] = "ProjectType";
204const char _ProgramDatabase[] = "ProgramDatabase";
205const char _ProgramDataBaseFileName[] = "ProgramDataBaseFileName";
206const char _ProgramDatabaseFile[] = "ProgramDatabaseFile";
207const char _ProxyFileName[] = "ProxyFileName";
208const char _RandomizedBaseAddress[] = "RandomizedBaseAddress";
209const char _RedirectOutputAndErrors[] = "RedirectOutputAndErrors";
210const char _RegisterOutput[] = "RegisterOutput";
211const char _RelativePath[] = "RelativePath";
212const char _RemoteDirectory[] = "RemoteDirectory";
213const char _ResourceOnlyDLL[] = "ResourceOnlyDLL";
214const char _ResourceOutputFileName[] = "ResourceOutputFileName";
215const char _RuntimeLibrary[] = "RuntimeLibrary";
216const char _RuntimeTypeInfo[] = "RuntimeTypeInfo";
217const char _SccProjectName[] = "SccProjectName";
218const char _SccLocalPath[] = "SccLocalPath";
219const char _SetChecksum[] = "SetChecksum";
220const char _ShowIncludes[] = "ShowIncludes";
221const char _ShowProgress[] = "ShowProgress";
222const char _SmallerTypeCheck[] = "SmallerTypeCheck";
223const char _StackCommitSize[] = "StackCommitSize";
224const char _StackReserveSize[] = "StackReserveSize";
225const char _StringPooling[] = "StringPooling";
226const char _StripPrivateSymbols[] = "StripPrivateSymbols";
227const char _StructMemberAlignment[] = "StructMemberAlignment";
228const char _SubSystem[] = "SubSystem";
229const char _SupportUnloadOfDelayLoadedDLL[] = "SupportUnloadOfDelayLoadedDLL";
230const char _SuppressStartupBanner[] = "SuppressStartupBanner";
231const char _SwapRunFromCD[] = "SwapRunFromCD";
232const char _SwapRunFromNet[] = "SwapRunFromNet";
233const char _TargetEnvironment[] = "TargetEnvironment";
234const char _TargetMachine[] = "TargetMachine";
235const char _TerminalServerAware[] = "TerminalServerAware";
236const char _Path[] = "Path";
237const char _TreatWChar_tAsBuiltInType[] = "TreatWChar_tAsBuiltInType";
238const char _TurnOffAssemblyGeneration[] = "TurnOffAssemblyGeneration";
239const char _TypeLibraryFile[] = "TypeLibraryFile";
240const char _TypeLibraryName[] = "TypeLibraryName";
241const char _TypeLibraryResourceID[] = "TypeLibraryResourceID";
242const char _UndefineAllPreprocessorDefinitions[]= "UndefineAllPreprocessorDefinitions";
243const char _UndefinePreprocessorDefinitions[] = "UndefinePreprocessorDefinitions";
244const char _UniqueIdentifier[] = "UniqueIdentifier";
245const char _UseOfATL[] = "UseOfATL";
246const char _UseOfMfc[] = "UseOfMfc";
247const char _UsePrecompiledHeader[] = "UsePrecompiledHeader";
248const char _ValidateParameters[] = "ValidateParameters";
249const char _VCCLCompilerTool[] = "VCCLCompilerTool";
250const char _VCLibrarianTool[] = "VCLibrarianTool";
251const char _VCLinkerTool[] = "VCLinkerTool";
252const char _VCManifestTool[] = "VCManifestTool";
253const char _VCCustomBuildTool[] = "VCCustomBuildTool";
254const char _VCResourceCompilerTool[] = "VCResourceCompilerTool";
255const char _VCMIDLTool[] = "VCMIDLTool";
256const char _Version[] = "Version";
257const char _WarnAsError[] = "WarnAsError";
258const char _WarningLevel[] = "WarningLevel";
259const char _WholeProgramOptimization[] = "WholeProgramOptimization";
260const char _CompileForArchitecture[] = "CompileForArchitecture";
261const char _InterworkCalls[] = "InterworkCalls";
262const char _GenerateManifest[] = "GenerateManifest";
263
264// XmlOutput stream functions ------------------------------
265inline XmlOutput::xml_output attrT(const char *name, const triState v)
266{
267 if(v == unset)
268 return noxml();
269 return attr(name, (v == _True ? "true" : "false"));
270}
271
272inline XmlOutput::xml_output attrE(const char *name, int v)
273{
274 return attr(name, QString::number(v));
275}
276
277/*ifNot version*/
278inline XmlOutput::xml_output attrE(const char *name, int v, int ifn)
279{
280 if (v == ifn)
281 return noxml();
282 return attr(name, QString::number(v));
283}
284
285inline XmlOutput::xml_output attrL(const char *name, qint64 v)
286{
287 return attr(name, QString::number(v));
288}
289
290/*ifNot version*/
291inline XmlOutput::xml_output attrL(const char *name, qint64 v, qint64 ifn)
292{
293 if (v == ifn)
294 return noxml();
295 return attr(name, QString::number(v));
296}
297
298inline XmlOutput::xml_output attrS(const char *name, const QString &v)
299{
300 if(v.isEmpty())
301 return noxml();
302 return attr(name, v);
303}
304
305inline XmlOutput::xml_output attrX(const char *name, const QStringList &v, const char *s = ",")
306{
307 if(v.isEmpty())
308 return noxml();
309 return attr(name, v.join(s));
310}
311
312triState operator!(const triState &rhs)
313{
314 if (rhs == unset)
315 return rhs;
316 triState lhs = (rhs == _True ? _False : _True);
317 return lhs;
318}
319
320// VCToolBase -------------------------------------------------
321QStringList VCToolBase::fixCommandLine(const QString &input)
322{
323 // The splitting regexp is a bit bizarre for backwards compat reasons (why else ...).
324 return input.split(QRegularExpression(QLatin1String("(\n\t|\r\\\\h|\r\n)\\s*")));
325}
326
327static QString vcCommandSeparator()
328{
329 // MSVC transforms the build tree into a single batch file, simply pasting the contents
330 // of the custom commands into it, and putting an "if errorlevel goto" statement behind it.
331 // As we want every sub-command to be error-checked (as is done by makefile-based
332 // backends), we insert the checks ourselves, using the undocumented jump target.
333 static QString cmdSep =
334 QLatin1String("&#x000D;&#x000A;if errorlevel 1 goto VCReportError&#x000D;&#x000A;");
335 return cmdSep;
336}
337
338static void unknownOptionWarning(const char *tool, const char *option)
339{
340 static bool firstCall = true;
341 warn_msg(WarnLogic, "Could not parse %s option '%s'; added to AdditionalOptions.", tool, option);
342 if (firstCall) {
343 firstCall = false;
344 warn_msg(WarnLogic,
345 "You can suppress these warnings with CONFIG+=suppress_vcproj_warnings.");
346 }
347}
348
349
350// VCCLCompilerTool -------------------------------------------------
351VCCLCompilerTool::VCCLCompilerTool()
352 : AssemblerOutput(asmListingNone),
353 BasicRuntimeChecks(runtimeBasicCheckNone),
354 BrowseInformation(brInfoNone),
355 BufferSecurityCheck(unset),
356 CallingConvention(callConventionDefault),
357 CompileAs(compileAsDefault),
358 CompileAsManaged(managedDefault),
359 CompileAsWinRT(unset),
360 CompileOnly(unset),
361 DebugInformationFormat(debugDisabled),
362 Detect64BitPortabilityProblems(unset),
363 DisableLanguageExtensions(unset),
364 EnableEnhancedInstructionSet(archNotSet),
365 EnableFiberSafeOptimizations(unset),
366 EnableFunctionLevelLinking(unset),
367 EnableIntrinsicFunctions(unset),
368 ExceptionHandling(ehDefault),
369 ExpandAttributedSource(unset),
370 FavorSizeOrSpeed(favorNone),
371 FloatingPointModel(floatingPointNotSet),
372 FloatingPointExceptions(unset),
373 ForceConformanceInForLoopScope(unset),
374 GeneratePreprocessedFile(preprocessNo),
375 PreprocessSuppressLineNumbers(unset),
376 GlobalOptimizations(unset),
377 IgnoreStandardIncludePath(unset),
378 ImproveFloatingPointConsistency(unset),
379 InlineFunctionExpansion(expandDefault),
380 KeepComments(unset),
381 MinimalRebuild(unset),
382 OmitDefaultLibName(unset),
383 OmitFramePointers(unset),
384 OpenMP(unset),
385 Optimization(optimizeCustom),
386 OptimizeForProcessor(procOptimizeBlended),
387 OptimizeForWindowsApplication(unset),
388 ProgramDataBaseFileName(""),
389 RuntimeLibrary(rtMultiThreaded),
390 RuntimeTypeInfo(unset),
391 ShowIncludes(unset),
392 SmallerTypeCheck(unset),
393 StringPooling(unset),
394 StructMemberAlignment(alignNotSet),
395 SuppressStartupBanner(unset),
396 TreatWChar_tAsBuiltInType(unset),
397 TurnOffAssemblyGeneration(unset),
398 UndefineAllPreprocessorDefinitions(unset),
399 UsePrecompiledHeader(pchUnset),
400 UseUnicodeForAssemblerListing(unset),
401 WarnAsError(unset),
402 WarningLevel(warningLevel_0),
403 WholeProgramOptimization(unset),
404 CompileForArchitecture(archUnknown),
405 InterworkCalls(unset),
406 EnablePREfast(unset),
407 DisplayFullPaths(unset),
408 MultiProcessorCompilation(unset),
409 GenerateXMLDocumentationFiles(unset),
410 CreateHotpatchableImage(unset)
411{
412}
413
414/*
415 * Some values for the attribute UsePrecompiledHeader have changed from VS 2003 to VS 2005,
416 * see the following chart, so we need a function that transforms those values if we are
417 * using NET2005:
418 *
419 * Meaning 2003 2005
420 * -----------------------------------------
421 * Don't use PCH 0 0
422 * Create PCH (/Yc) 1 1
423 * Automatically generate (/YX) 2 (seems that it was removed)
424 * Use specific PCH (/Yu) 3 2
425 *
426 */
427inline XmlOutput::xml_output xformUsePrecompiledHeaderForNET2005(pchOption whatPch, DotNET compilerVersion)
428{
429 if (compilerVersion >= NET2005) {
430 if (whatPch == pchGenerateAuto) whatPch = (pchOption)0;
431 if (whatPch == pchUseUsingSpecific) whatPch = (pchOption)2;
432 }
433 return attrE(_UsePrecompiledHeader, whatPch, /*ifNot*/ pchUnset);
434}
435
436inline XmlOutput::xml_output xformExceptionHandlingNET2005(exceptionHandling eh, DotNET compilerVersion)
437{
438 if (eh == ehDefault)
439 return noxml();
440
441 if (compilerVersion >= NET2005)
442 return attrE(_ExceptionHandling, eh);
443
444 return attrS(_ExceptionHandling, (eh == ehNoSEH ? "true" : "false"));
445}
446
447bool VCCLCompilerTool::parseOption(const char* option)
448{
449 // skip index 0 ('/' or '-')
450 char first = option[1];
451 char second = option[2];
452 char third = option[3];
453 char fourth = option[4];
454 bool found = true;
455
456 switch (first) {
457 case '?':
458 case 'h':
459 if(second == 'o' && third == 't' && fourth == 'p') {
460 CreateHotpatchableImage = _True;
461 break;
462 }
463 qWarning("Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info");
464 found = false;
465 break;
466 case '@':
467 qWarning("Generator: Option '/@': MSVC.NET projects do not support the use of a response file");
468 found = false;
469 break;
470 case 'l':
471 qWarning("Generator: Option '/link': qmake generator does not support passing link options through the compiler tool");
472 found = false;
473 break;
474 case 'A':
475 if(second != 'I') {
476 found = false; break;
477 }
478 AdditionalUsingDirectories += option+3;
479 break;
480 case 'C':
481 KeepComments = _True;
482 break;
483 case 'D':
484 PreprocessorDefinitions += option+2;
485 break;
486 case 'E':
487 if(second == 'H') {
488 QByteArray opt(option + 2);
489 if (opt.contains('a') && !opt.contains('s') && !opt.contains('c'))
490 ExceptionHandling = ehSEH;
491 else if (!opt.contains('a') && opt.contains("s-") && opt.contains("c-"))
492 ExceptionHandling = ehNone;
493 else if (!opt.contains('a') && opt.contains('s') && opt.contains('c'))
494 ExceptionHandling = ehNoSEH;
495 else {
496 // ExceptionHandling must be false, or it will override
497 // with an /EHsc option
498 ExceptionHandling = ehNone;
499 AdditionalOptions += option;
500 }
501 if (config->CompilerVersion < NET2005
502 && ExceptionHandling == ehSEH) {
503 ExceptionHandling = ehNone;
504 AdditionalOptions += option;
505 }
506 break;
507 } else if (second == 'P') {
508 PreprocessSuppressLineNumbers = _True;
509 }
510 GeneratePreprocessedFile = preprocessYes;
511 break;
512 case 'F':
513 if(second <= '9' && second >= '0') {
514 AdditionalOptions += option;
515 break;
516 } else {
517 switch (second) {
518 case 'A':
519 if(third == 'c') {
520 AssemblerOutput = asmListingAsmMachine;
521 if(fourth == 's')
522 AssemblerOutput = asmListingAsmMachineSrc;
523 } else if(third == 's') {
524 AssemblerOutput = asmListingAsmSrc;
525 } else if (third == 'u') {
526 UseUnicodeForAssemblerListing = _True;
527 } else {
528 AssemblerOutput = asmListingAssemblyOnly;
529 }
530 break;
531 case 'C':
532 DisplayFullPaths = _True;
533 break;
534 case 'a':
535 AssemblerListingLocation = option+3;
536 break;
537 case 'I':
538 ForcedIncludeFiles += option+3;
539 break;
540 case 'i':
541 PreprocessOutputPath += option+3;
542 break;
543 case 'R':
544 BrowseInformation = brAllInfo;
545 BrowseInformationFile = option+3;
546 break;
547 case 'S':
548 if (config->CompilerVersion < NET2013)
549 found = false;
550 // Ignore this flag. Visual Studio 2013 takes care of this setting.
551 break;
552 case 'r':
553 BrowseInformation = brNoLocalSymbols;
554 BrowseInformationFile = option+3;
555 break;
556 case 'U':
557 ForcedUsingFiles += option+3;
558 break;
559 case 'd':
560 ProgramDataBaseFileName = option+3;
561 break;
562 case 'e':
563 OutputFile = option+3;
564 break;
565 case 'm':
566 AdditionalOptions += option;
567 break;
568 case 'o':
569 ObjectFile = option+3;
570 break;
571 case 'p':
572 PrecompiledHeaderFile = option+3;
573 break;
574 case 'x':
575 ExpandAttributedSource = _True;
576 break;
577 default:
578 found = false; break;
579 }
580 }
581 break;
582 case 'G':
583 switch (second) {
584 case '3':
585 case '4':
586 qWarning("Option '/G3' and '/G4' were phased out in Visual C++ 5.0");
587 found = false; break;
588 case '5':
589 OptimizeForProcessor = procOptimizePentium;
590 break;
591 case '6':
592 case 'B':
593 OptimizeForProcessor = procOptimizePentiumProAndAbove;
594 break;
595 case '7':
596 OptimizeForProcessor = procOptimizePentium4AndAbove;
597 break;
598 case 'A':
599 OptimizeForWindowsApplication = _True;
600 break;
601 case 'F':
602 StringPooling = _True;
603 break;
604 case 'H':
605 AdditionalOptions += option;
606 break;
607 case 'L':
608 WholeProgramOptimization = _True;
609 if(third == '-')
610 WholeProgramOptimization = _False;
611 break;
612 case 'R':
613 RuntimeTypeInfo = _True;
614 if(third == '-')
615 RuntimeTypeInfo = _False;
616 break;
617 case 'S':
618 BufferSecurityCheck = _True;
619 if(third == '-')
620 BufferSecurityCheck = _False;
621 break;
622 case 'T':
623 EnableFiberSafeOptimizations = _True;
624 break;
625 case 'X':
626 // Same as the /EHsc option, which is Exception Handling without SEH
627 ExceptionHandling = ehNoSEH;
628 if (third == '-')
629 ExceptionHandling = ehNone;
630 break;
631 case 'Z':
632 case 'e':
633 case 'h':
634 AdditionalOptions += option;
635 break;
636 case 'd':
637 CallingConvention = callConventionCDecl;
638 break;
639 case 'f':
640 StringPooling = _True;
641 AdditionalOptions += option;
642 break;
643 case 'm':
644 MinimalRebuild = _True;
645 if(third == '-')
646 MinimalRebuild = _False;
647 break;
648 case 'r':
649 CallingConvention = callConventionFastCall;
650 break;
651 case 's':
652 AdditionalOptions += option;
653 break;
654 case 'y':
655 EnableFunctionLevelLinking = _True;
656 break;
657 case 'z':
658 CallingConvention = callConventionStdCall;
659 break;
660 default:
661 found = false; break;
662 }
663 break;
664 case 'H':
665 AdditionalOptions += option;
666 break;
667 case 'I':
668 AdditionalIncludeDirectories += option+2;
669 break;
670 case 'J':
671 AdditionalOptions += option;
672 break;
673 case 'L':
674 if(second == 'D') {
675 AdditionalOptions += option;
676 break;
677 }
678 found = false; break;
679 case 'M':
680 if(second == 'D') {
681 RuntimeLibrary = rtMultiThreadedDLL;
682 if(third == 'd')
683 RuntimeLibrary = rtMultiThreadedDebugDLL;
684 break;
685 } else if(second == 'L') {
686 RuntimeLibrary = rtSingleThreaded;
687 if(third == 'd')
688 RuntimeLibrary = rtSingleThreadedDebug;
689 break;
690 } else if(second == 'T') {
691 RuntimeLibrary = rtMultiThreaded;
692 if(third == 'd')
693 RuntimeLibrary = rtMultiThreadedDebug;
694 break;
695 } else if (second == 'P') {
696 if (config->CompilerVersion >= NET2010) {
697 MultiProcessorCompilation = _True;
698 MultiProcessorCompilationProcessorCount = option+3;
699 } else if (config->CompilerVersion >= NET2005) {
700 AdditionalOptions += option;
701 } else {
702 warn_msg(WarnLogic, "/MP option is not supported in Visual C++ < 2005, ignoring.");
703 }
704 break;
705 }
706 found = false; break;
707 case 'O':
708 switch (second) {
709 case '1':
710 Optimization = optimizeMinSpace;
711 break;
712 case '2':
713 Optimization = optimizeMaxSpeed;
714 break;
715 case 'a':
716 AdditionalOptions += option;
717 break;
718 case 'b':
719 if(third == '0')
720 InlineFunctionExpansion = expandDisable;
721 else if(third == '1')
722 InlineFunctionExpansion = expandOnlyInline;
723 else if(third == '2')
724 InlineFunctionExpansion = expandAnySuitable;
725 else
726 found = false;
727 break;
728 case 'd':
729 Optimization = optimizeDisabled;
730 break;
731 case 'g':
732 GlobalOptimizations = _True;
733 break;
734 case 'i':
735 EnableIntrinsicFunctions = _True;
736 break;
737 case 'p':
738 ImproveFloatingPointConsistency = _True;
739 if(third == '-')
740 ImproveFloatingPointConsistency = _False;
741 break;
742 case 's':
743 FavorSizeOrSpeed = favorSize;
744 break;
745 case 't':
746 FavorSizeOrSpeed = favorSpeed;
747 break;
748 case 'w':
749 AdditionalOptions += option;
750 break;
751 case 'x':
752 Optimization = optimizeFull;
753 break;
754 case 'y':
755 OmitFramePointers = _True;
756 if(third == '-')
757 OmitFramePointers = _False;
758 break;
759 default:
760 found = false; break;
761 }
762 break;
763 case 'P':
764 GeneratePreprocessedFile = preprocessYes;
765 break;
766 case 'Q':
767 if(second == 'I') {
768 AdditionalOptions += option;
769 break;
770 } else if (second == 'R') {
771 QString opt = option + 3;
772 if (opt == "interwork-return") {
773 InterworkCalls = _True;
774 break;
775 } else if (opt == "arch4") {
776 CompileForArchitecture = archArmv4;
777 break;
778 } else if (opt == "arch5") {
779 CompileForArchitecture = archArmv5;
780 break;
781 } else if (opt == "arch4T") {
782 CompileForArchitecture = archArmv4T;
783 break;
784 } else if (opt == "arch5T") {
785 CompileForArchitecture = archArmv5T;
786 break;
787 }
788 } else if (second == 'M') {
789 QString opt = option + 3;
790 if (opt == "mips1") {
791 CompileForArchitecture = archMips1;
792 break;
793 }
794 else if (opt == "mips2") {
795 CompileForArchitecture = archMips2;
796 break;
797 }
798 else if (opt == "mips3") {
799 CompileForArchitecture = archMips3;
800 break;
801 }
802 else if (opt == "mips4") {
803 CompileForArchitecture = archMips4;
804 break;
805 }
806 else if (opt == "mips5") {
807 CompileForArchitecture = archMips5;
808 break;
809 }
810 else if (opt == "mips16") {
811 CompileForArchitecture = archMips16;
812 break;
813 }
814 else if (opt == "mips32") {
815 CompileForArchitecture = archMips32;
816 break;
817 }
818 else if (opt == "mips64") {
819 CompileForArchitecture = archMips64;
820 break;
821 }
822 }
823 found = false; break;
824 case 'R':
825 if(second == 'T' && third == 'C') {
826 int rtc = BasicRuntimeChecks;
827 for (size_t i = 4; option[i]; ++i) {
828 if (!parseRuntimeCheckOption(option[i], &rtc)) {
829 found = false;
830 break;
831 }
832 }
833 BasicRuntimeChecks = static_cast<basicRuntimeCheckOption>(rtc);
834 }
835 break;
836 case 'T':
837 if(second == 'C') {
838 CompileAs = compileAsC;
839 } else if(second == 'P') {
840 CompileAs = compileAsCPlusPlus;
841 } else {
842 qWarning("Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake");
843 found = false; break;
844 }
845 break;
846 case 'U':
847 UndefinePreprocessorDefinitions += option+2;
848 break;
849 case 'V':
850 AdditionalOptions += option;
851 break;
852 case 'W':
853 switch (second) {
854 case 'a':
855 case '4':
856 WarningLevel = warningLevel_4;
857 break;
858 case '3':
859 WarningLevel = warningLevel_3;
860 break;
861 case '2':
862 WarningLevel = warningLevel_2;
863 break;
864 case '1':
865 WarningLevel = warningLevel_1;
866 break;
867 case '0':
868 WarningLevel = warningLevel_0;
869 break;
870 case 'L':
871 AdditionalOptions += option;
872 break;
873 case 'X':
874 WarnAsError = _True;
875 break;
876 case 'p':
877 if(third == '6' && fourth == '4') {
878 if (config->CompilerVersion >= NET2010) {
879 // Deprecated for VS2010 but can be used under Additional Options.
880 AdditionalOptions += option;
881 } else {
882 Detect64BitPortabilityProblems = _True;
883 }
884 break;
885 }
886 // Fallthrough
887 default:
888 found = false; break;
889 }
890 break;
891 case 'X':
892 IgnoreStandardIncludePath = _True;
893 break;
894 case 'Y':
895 switch (second) {
896 case '\0':
897 case '-':
898 AdditionalOptions += option;
899 break;
900 case 'X':
901 UsePrecompiledHeader = pchGenerateAuto;
902 PrecompiledHeaderThrough = option+3;
903 break;
904 case 'c':
905 UsePrecompiledHeader = pchCreateUsingSpecific;
906 PrecompiledHeaderThrough = option+3;
907 break;
908 case 'd':
909 case 'l':
910 AdditionalOptions += option;
911 break;
912 case 'u':
913 UsePrecompiledHeader = pchUseUsingSpecific;
914 PrecompiledHeaderThrough = option+3;
915 break;
916 default:
917 found = false; break;
918 }
919 break;
920 case 'Z':
921 switch (second) {
922 case '7':
923 DebugInformationFormat = debugOldStyleInfo;
924 break;
925 case 'I':
926 DebugInformationFormat = debugEditAndContinue;
927 break;
928 case 'd':
929 DebugInformationFormat = debugLineInfoOnly;
930 break;
931 case 'i':
932 DebugInformationFormat = debugEnabled;
933 break;
934 case 'l':
935 OmitDefaultLibName = _True;
936 break;
937 case 'a':
938 DisableLanguageExtensions = _True;
939 break;
940 case 'e':
941 DisableLanguageExtensions = _False;
942 break;
943 case 'c':
944 if(third == ':') {
945 const char *c = option + 4;
946 // Go to the end of the option
947 while ( *c != '\0' && *c != ' ' && *c != '-')
948 ++c;
949 if(fourth == 'f')
950 ForceConformanceInForLoopScope = ((*c) == '-' ? _False : _True);
951 else if(fourth == 'w')
952 TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True);
953 else
954 AdditionalOptions += option;
955 } else {
956 found = false; break;
957 }
958 break;
959 case 'g':
960 case 'm':
961 case 's':
962 AdditionalOptions += option;
963 break;
964 case 'p':
965 switch (third)
966 {
967 case '\0':
968 case '1':
969 StructMemberAlignment = alignSingleByte;
970 if(fourth == '6')
971 StructMemberAlignment = alignSixteenBytes;
972 break;
973 case '2':
974 StructMemberAlignment = alignTwoBytes;
975 break;
976 case '4':
977 StructMemberAlignment = alignFourBytes;
978 break;
979 case '8':
980 StructMemberAlignment = alignEightBytes;
981 break;
982 default:
983 found = false; break;
984 }
985 break;
986 case 'W':
987 if (third == '-')
988 CompileAsWinRT = _False;
989 else
990 CompileAsWinRT = _True;
991 break;
992 default:
993 found = false; break;
994 }
995 break;
996 case 'a':
997 if (second == 'r' && third == 'c' && fourth == 'h') {
998 if (option[5] == ':') {
999 const char *o = option;
1000 if (o[6] == 'S' && o[7] == 'S' && o[8] == 'E') {
1001 EnableEnhancedInstructionSet = o[9] == '2' ? archSSE2 : archSSE;
1002 break;
1003 }
1004 }
1005 } else if (second == 'n' && third == 'a' && fourth == 'l') {
1006 EnablePREfast = _True;
1007 break;
1008 }
1009 found = false;
1010 break;
1011 case 'b': // see http://msdn2.microsoft.com/en-us/library/ms173499.aspx
1012 if (second == 'i' && third == 'g' && fourth == 'o') {
1013 const char *o = option;
1014 if (o[5] == 'b' && o[6] == 'j') {
1015 AdditionalOptions += option;
1016 break;
1017 }
1018 }
1019 found = false;
1020 break;
1021 case 'c':
1022 if(second == '\0') {
1023 CompileOnly = _True;
1024 } else if(second == 'l') {
1025 if (config->CompilerVersion < NET2005) {
1026 if(*(option+5) == 'n') {
1027 CompileAsManaged = managedAssemblyPure;
1028 TurnOffAssemblyGeneration = _True;
1029 } else if(*(option+5) == 'p') {
1030 CompileAsManaged = managedAssemblyPure;
1031 warn_msg(WarnLogic, "/clr:pure option only for .NET >= 2005, using /clr");
1032 } else if(*(option+5) == 's') {
1033 CompileAsManaged = managedAssemblyPure;
1034 warn_msg(WarnLogic, "/clr:safe option only for .NET >= 2005, using /clr");
1035 } else if(*(option+5) == 'o') {
1036 CompileAsManaged = managedAssemblyPure;
1037 warn_msg(WarnLogic, "/clr:oldSyntax option only for .NET >= 2005, using /clr");
1038 } else if(*(option+5) == 'i') {
1039 CompileAsManaged = managedAssemblyPure;
1040 warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl");
1041 } else {
1042 CompileAsManaged = managedAssemblyPure;
1043 }
1044 } else {
1045 if(*(option+5) == 'n') {
1046 CompileAsManaged = managedAssembly;
1047 TurnOffAssemblyGeneration = _True;
1048 } else if(*(option+5) == 'p') {
1049 CompileAsManaged = managedAssemblyPure;
1050 } else if(*(option+5) == 's') {
1051 CompileAsManaged = managedAssemblySafe;
1052 } else if(*(option+5) == 'o') {
1053 CompileAsManaged = managedAssemblyOldSyntax;
1054 } else if(*(option+5) == 'i') {
1055 CompileAsManaged = managedAssembly;
1056 warn_msg(WarnLogic, "initialAppDomain enum value unknown, using /crl default");
1057 } else {
1058 CompileAsManaged = managedAssembly;
1059 }
1060 }
1061 } else {
1062 found = false; break;
1063 }
1064 break;
1065 case 'd':
1066 if (second == 'r') {
1067 CompileAsManaged = managedAssembly;
1068 break;
1069 } else if (second != 'o' && third == 'c') {
1070 GenerateXMLDocumentationFiles = _True;
1071 XMLDocumentationFileName += option+4;
1072 break;
1073 }
1074 found = false;
1075 break;
1076 case 'e':
1077 if (second == 'r' && third == 'r' && fourth == 'o') {
1078 if (option[12] == ':') {
1079 if ( option[13] == 'n') {
1080 ErrorReporting = "None";
1081 } else if (option[13] == 'p') {
1082 ErrorReporting = "Prompt";
1083 } else if (option[13] == 'q') {
1084 ErrorReporting = "Queue";
1085 } else if (option[13] == 's') {
1086 ErrorReporting = "Send";
1087 } else {
1088 found = false;
1089 }
1090 break;
1091 }
1092 }
1093 found = false;
1094 break;
1095 case 'f':
1096 if(second == 'p' && third == ':') {
1097 // Go to the end of the option
1098 const char *c = option + 4;
1099 while (*c != '\0' && *c != ' ' && *c != '-')
1100 ++c;
1101 switch (fourth) {
1102 case 'e':
1103 FloatingPointExceptions = ((*c) == '-' ? _False : _True);
1104 break;
1105 case 'f':
1106 FloatingPointModel = floatingPointFast;
1107 break;
1108 case 'p':
1109 FloatingPointModel = floatingPointPrecise;
1110 break;
1111 case 's':
1112 FloatingPointModel = floatingPointStrict;
1113 break;
1114 default:
1115 found = false;
1116 break;
1117 }
1118 }
1119 break;
1120 case 'n':
1121 if(second == 'o' && third == 'B' && fourth == 'o') {
1122 AdditionalOptions += "/noBool";
1123 break;
1124 }
1125 if(second == 'o' && third == 'l' && fourth == 'o') {
1126 SuppressStartupBanner = _True;
1127 break;
1128 }
1129 found = false; break;
1130 case 'o':
1131 {
1132 const char *str = option + 2;
1133 const size_t len = strlen(str);
1134 if (len >= 5 && len <= 6 && strncmp(str, "penmp", 5) == 0) {
1135 if (len == 5) {
1136 OpenMP = _True;
1137 break;
1138 } else if (str[5] == '-') {
1139 OpenMP = _False;
1140 break;
1141 }
1142 }
1143 found = false; break;
1144 }
1145 case 's':
1146 if(second == 'h' && third == 'o' && fourth == 'w') {
1147 ShowIncludes = _True;
1148 break;
1149 }
1150 if (strlen(option) > 8 && second == 't' && third == 'd') {
1151 const QString version = option + 8;
1152 static const QStringList knownVersions = { "14", "17", "latest" };
1153 if (knownVersions.contains(version)) {
1154 LanguageStandard = "stdcpp" + version;
1155 break;
1156 }
1157 }
1158 found = false; break;
1159 case 'u':
1160 if (!second)
1161 UndefineAllPreprocessorDefinitions = _True;
1162 else if (strcmp(option + 2, "tf-8") == 0)
1163 AdditionalOptions += option;
1164 else
1165 found = false;
1166 break;
1167 case 'v':
1168 if(second == 'd' || second == 'm') {
1169 AdditionalOptions += option;
1170 break;
1171 }
1172 found = false; break;
1173 case 'w':
1174 switch (second) {
1175 case '\0':
1176 WarningLevel = warningLevel_0;
1177 break;
1178 case 'd':
1179 DisableSpecificWarnings += option+3;
1180 break;
1181 case 'e':
1182 if (config->CompilerVersion <= NET2008)
1183 AdditionalOptions += option;
1184 else
1185 TreatSpecificWarningsAsErrors += option + 3;
1186 break;
1187 default:
1188 AdditionalOptions += option;
1189 }
1190 break;
1191 default:
1192 AdditionalOptions += option;
1193 break;
1194 }
1195 if(!found) {
1196 if (!config->suppressUnknownOptionWarnings)
1197 unknownOptionWarning("Compiler", option);
1198 AdditionalOptions += option;
1199 }
1200 return true;
1201}
1202
1203bool VCCLCompilerTool::parseRuntimeCheckOption(char c, int *rtc)
1204{
1205 if (c == '1')
1206 *rtc = runtimeBasicCheckAll;
1207 else if (c == 'c')
1208 SmallerTypeCheck = _True;
1209 else if (c == 's')
1210 *rtc |= runtimeCheckStackFrame;
1211 else if (c == 'u')
1212 *rtc |= runtimeCheckUninitVariables;
1213 else
1214 return false;
1215 return true;
1216}
1217
1218// VCLinkerTool -----------------------------------------------------
1219VCLinkerTool::VCLinkerTool()
1220 : DataExecutionPrevention(unset),
1221 EnableCOMDATFolding(optFoldingDefault),
1222 GenerateDebugInformation(unset),
1223 DebugInfoOption(linkerDebugOptionNone),
1224 GenerateMapFile(unset),
1225 HeapCommitSize(-1),
1226 HeapReserveSize(-1),
1227 IgnoreAllDefaultLibraries(unset),
1228 IgnoreEmbeddedIDL(unset),
1229 IgnoreImportLibrary(_True),
1230 ImageHasSafeExceptionHandlers(unset),
1231 LargeAddressAware(addrAwareDefault),
1232 LinkDLL(unset),
1233 LinkIncremental(linkIncrementalDefault),
1234 LinkTimeCodeGeneration(optLTCGDefault),
1235 MapExports(unset),
1236 MapLines(unset),
1237 OptimizeForWindows98(optWin98Default),
1238 OptimizeReferences(optReferencesDefault),
1239 RandomizedBaseAddress(unset),
1240 RegisterOutput(unset),
1241 ResourceOnlyDLL(unset),
1242 SetChecksum(unset),
1243 ShowProgress(linkProgressNotSet),
1244 StackCommitSize(-1),
1245 StackReserveSize(-1),
1246 SubSystem(subSystemNotSet),
1247 SupportUnloadOfDelayLoadedDLL(unset),
1248 SuppressStartupBanner(unset),
1249 SwapRunFromCD(unset),
1250 SwapRunFromNet(unset),
1251 TargetMachine(machineNotSet),
1252 TerminalServerAware(termSvrAwareDefault),
1253 TreatWarningsAsErrors(unset),
1254 TurnOffAssemblyGeneration(unset),
1255 TypeLibraryResourceID(0),
1256 GenerateManifest(unset),
1257 EnableUAC(unset),
1258 UACUIAccess(unset),
1259 SectionAlignment(-1),
1260 PreventDllBinding(unset),
1261 AllowIsolation(unset),
1262 AssemblyDebug(unset),
1263 CLRUnmanagedCodeCheck(unset),
1264 DelaySign(unset),
1265 GenerateWindowsMetadata(unset)
1266{
1267}
1268
1269// Hashing routine to do fast option lookups ----
1270// Slightly rewritten to stop on ':' ',' and '\0'
1271// Original routine in qtranslator.cpp ----------
1272static uint elfHash(const char* name)
1273{
1274 const uchar *k;
1275 uint h = 0;
1276 uint g;
1277
1278 if(name) {
1279 k = (const uchar *) name;
1280 while((*k) &&
1281 (*k)!= ':' &&
1282 (*k)!=',' &&
1283 (*k)!=' ') {
1284 h = (h << 4) + *k++;
1285 if((g = (h & 0xf0000000)) != 0)
1286 h ^= g >> 24;
1287 h &= ~g;
1288 }
1289 }
1290 if(!h)
1291 h = 1;
1292 return h;
1293}
1294
1295//#define USE_DISPLAY_HASH
1296#ifdef USE_DISPLAY_HASH
1297static void displayHash(const char* str)
1298{
1299 printf("case 0x%07x: // %s\n break;\n", elfHash(str), str);
1300}
1301#endif
1302
1303bool VCLinkerTool::parseOption(const char* option)
1304{
1305#ifdef USE_DISPLAY_HASH
1306 // Main options
1307 displayHash("/ALIGN"); displayHash("/ALLOWBIND"); displayHash("/ASSEMBLYMODULE");
1308 displayHash("/ASSEMBLYRESOURCE"); displayHash("/BASE"); displayHash("/DEBUG");
1309 displayHash("/DEF"); displayHash("/DEFAULTLIB"); displayHash("/DELAY");
1310 displayHash("/DELAYLOAD"); displayHash("/DLL"); displayHash("/DRIVER");
1311 displayHash("/ENTRY"); displayHash("/EXETYPE"); displayHash("/EXPORT");
1312 displayHash("/FIXED"); displayHash("/FORCE"); displayHash("/HEAP");
1313 displayHash("/IDLOUT"); displayHash("/IGNORE"); displayHash("/IGNOREIDL"); displayHash("/IMPLIB");
1314 displayHash("/INCLUDE"); displayHash("/INCREMENTAL"); displayHash("/LARGEADDRESSAWARE");
1315 displayHash("/LIBPATH"); displayHash("/LTCG"); displayHash("/MACHINE");
1316 displayHash("/MAP"); displayHash("/MAPINFO"); displayHash("/MERGE");
1317 displayHash("/MIDL"); displayHash("/NOASSEMBLY"); displayHash("/NODEFAULTLIB");
1318 displayHash("/NOENTRY"); displayHash("/NOLOGO"); displayHash("/OPT");
1319 displayHash("/ORDER"); displayHash("/OUT"); displayHash("/PDB");
1320 displayHash("/PDBSTRIPPED"); displayHash("/RELEASE"); displayHash("/SECTION");
1321 displayHash("/STACK"); displayHash("/STUB"); displayHash("/SUBSYSTEM");
1322 displayHash("/SWAPRUN"); displayHash("/TLBID"); displayHash("/TLBOUT");
1323 displayHash("/TSAWARE"); displayHash("/VERBOSE"); displayHash("/VERSION");
1324 displayHash("/VXD"); displayHash("/WS "); displayHash("/libpath");
1325 displayHash("/WINMD"); displayHash("/WINMDFILE:");
1326
1327#endif
1328#ifdef USE_DISPLAY_HASH
1329 // Sub options
1330 displayHash("UNLOAD"); displayHash("NOBIND"); displayHash("no"); displayHash("NOSTATUS"); displayHash("STATUS");
1331 displayHash("AM33"); displayHash("ARM"); displayHash("CEE"); displayHash("EBC"); displayHash("IA64"); displayHash("X86"); displayHash("X64"); displayHash("M32R");
1332 displayHash("MIPS"); displayHash("MIPS16"); displayHash("MIPSFPU"); displayHash("MIPSFPU16"); displayHash("MIPSR41XX"); displayHash("PPC");
1333 displayHash("SH3"); displayHash("SH3DSP"); displayHash("SH4"); displayHash("SH5"); displayHash("THUMB"); displayHash("TRICORE"); displayHash("EXPORTS");
1334 displayHash("LINES"); displayHash("REF"); displayHash("NOREF"); displayHash("ICF"); displayHash("WIN98"); displayHash("NOWIN98");
1335 displayHash("CONSOLE"); displayHash("EFI_APPLICATION"); displayHash("EFI_BOOT_SERVICE_DRIVER"); displayHash("EFI_ROM"); displayHash("EFI_RUNTIME_DRIVER"); displayHash("NATIVE");
1336 displayHash("POSIX"); displayHash("WINDOWS"); displayHash("WINDOWSCE"); displayHash("NET"); displayHash("CD"); displayHash("NO");
1337#endif
1338 bool found = true;
1339 const uint optionHash = elfHash(option);
1340 if (config->CompilerVersion < NET2010) {
1341 switch (optionHash) {
1342 case 0x3360dbe: // /ALIGN[:number]
1343 case 0x1485c34: // /ALLOWBIND[:NO]
1344 case 0x33aec94: // /FIXED[:NO]
1345 case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#]
1346 case 0x0348992: // /STUB:filename
1347 AdditionalOptions += option;
1348 return true;
1349 }
1350 }
1351
1352 switch (optionHash) {
1353 case 0x6b21972: // /DEFAULTLIB:library
1354 case 0x396ea92: // /DRIVER[:UPONLY | :WDM]
1355 case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386]
1356 case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
1357 case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED]
1358 case 0x3dc3455: // /IGNORE:number,number,number,number ### NOTE: This one is undocumented, but it is even used by Microsoft.
1359 // In recent versions of the Microsoft linker they have disabled this undocumented feature.
1360 case 0x0034bc4: // /VXD
1361 AdditionalOptions += option;
1362 break;
1363 case 0x3360dbe: // /ALIGN[:number]
1364 SectionAlignment = QString(option+7).toLongLong();
1365 break;
1366 case 0x1485c34: // /ALLOWBIND[:NO]
1367 if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N'))
1368 PreventDllBinding = _False;
1369 else
1370 PreventDllBinding = _True;
1371 break;
1372 case 0x312011e: // /ALLOWISOLATION[:NO]
1373 if(*(option+15) == ':' && (*(option+16) == 'n' || *(option+16) == 'N'))
1374 AllowIsolation = _False;
1375 else
1376 AllowIsolation = _True;
1377 break;
1378 case 0x679c075: // /ASSEMBLYMODULE:filename
1379 AddModuleNamesToAssembly += option+15;
1380 break;
1381 case 0x75f35f7: // /ASSEMBLYDEBUG[:DISABLE]
1382 if(*(option+14) == ':' && (*(option+15) == 'D'))
1383 AssemblyDebug = _False;
1384 else
1385 AssemblyDebug = _True;
1386 break;
1387 case 0x43294a5: // /ASSEMBLYLINKRESOURCE:filename
1388 AssemblyLinkResource += option+22;
1389 break;
1390 case 0x062d065: // /ASSEMBLYRESOURCE:filename
1391 LinkToManagedResourceFile = option+18;
1392 break;
1393 case 0x0336675: // /BASE:{address | @filename,key}
1394 // Do we need to do a manual lookup when '@filename,key'?
1395 // Seems BaseAddress only can contain the location...
1396 // We don't use it in Qt, so keep it simple for now
1397 BaseAddress = option+6;
1398 break;
1399 case 0x63bf065: // /CLRIMAGETYPE:{IJW|PURE|SAFE}
1400 if(*(option+14) == 'I')
1401 CLRImageType = "ForceIJWImage";
1402 else if(*(option+14) == 'P')
1403 CLRImageType = "ForcePureILImage";
1404 else if(*(option+14) == 'S')
1405 CLRImageType = "ForceSafeILImage";
1406 break;
1407 case 0x5f2a6a2: // /CLRSUPPORTLASTERROR{:NO | SYSTEMDLL}
1408 if(*(option+20) == ':') {
1409 if(*(option+21) == 'N') {
1410 CLRSupportLastError = "Disabled";
1411 } else if(*(option+21) == 'S') {
1412 CLRSupportLastError = "SystemDlls";
1413 }
1414 } else {
1415 CLRSupportLastError = "Enabled";
1416 }
1417 break;
1418 case 0xc7984f5: // /CLRTHREADATTRIBUTE:{STA|MTA|NONE}
1419 if(*(option+20) == 'N')
1420 CLRThreadAttribute = "DefaultThreadingAttribute";
1421 else if(*(option+20) == 'M')
1422 CLRThreadAttribute = "MTAThreadingAttribute";
1423 else if(*(option+20) == 'S')
1424 CLRThreadAttribute = "STAThreadingAttribute";
1425 break;
1426 case 0xa8c637b: // /CLRUNMANAGEDCODECHECK[:NO]
1427 if(*(option+23) == 'N')
1428 CLRUnmanagedCodeCheck = _False;
1429 else
1430 CLRUnmanagedCodeCheck = _True;
1431 break;
1432 case 0x62d9e94: // /MANIFEST[:NO]
1433 if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n')))
1434 GenerateManifest = _False;
1435 else
1436 GenerateManifest = _True;
1437 break;
1438 case 0x34be314: // /WINMD[:NO]
1439 if ((*(option+6) == ':' && (*(option+7) == 'N' || *(option+7) == 'n')))
1440 GenerateWindowsMetadata = _False;
1441 else
1442 GenerateWindowsMetadata = _True;
1443 break;
1444 case 0x31be7e5: // /WINMDFILE:filename
1445 WindowsMetadataFile = option+11;
1446 break;
1447 case 0x8b64559: // /MANIFESTDEPENDENCY:manifest_dependency
1448 AdditionalManifestDependencies += option+20;
1449 break;
1450 case 0xe9e8195: // /MANIFESTFILE:filename
1451 ManifestFile = option+14;
1452 break;
1453 case 0x9e9fb83: // /MANIFESTUAC http://msdn.microsoft.com/en-us/library/bb384691%28VS.100%29.aspx
1454 if ((*(option+12) == ':' && (*(option+13) == 'N' || *(option+13) == 'n')))
1455 EnableUAC = _False;
1456 else if((*(option+12) == ':' && (*(option+13) == 'l' || *(option+14) == 'e'))) { // level
1457 if(*(option+20) == 'a')
1458 UACExecutionLevel = "AsInvoker";
1459 else if(*(option+20) == 'h')
1460 UACExecutionLevel = "HighestAvailable";
1461 else if(*(option+20) == 'r')
1462 UACExecutionLevel = "RequireAdministrator";
1463 } else if((*(option+12) == ':' && (*(option+13) == 'u' || *(option+14) == 'i'))) { // uiAccess
1464 if(*(option+22) == 't')
1465 UACUIAccess = _True;
1466 else
1467 UACUIAccess = _False;
1468 } else if((*(option+12) == ':' && (*(option+13) == 'f' || *(option+14) == 'r'))) { // fragment
1469 AdditionalOptions += option;
1470 }else
1471 EnableUAC = _True;
1472 break;
1473 case 0x3389797: // /DEBUG[:FASTLINK]
1474 GenerateDebugInformation = _True;
1475 if (config->CompilerVersion >= NET2015 && strcmp(option + 7, "FASTLINK") == 0)
1476 DebugInfoOption = linkerDebugOptionFastLink;
1477 break;
1478 case 0x0033896: // /DEF:filename
1479 ModuleDefinitionFile = option+5;
1480 break;
1481 case 0x338a069: // /DELAY:{UNLOAD | NOBIND}
1482 // MS documentation does not specify what to do with
1483 // this option, so we'll put it in AdditionalOptions
1484 AdditionalOptions += option;
1485 break;
1486 case 0x06f4bf4: // /DELAYLOAD:dllname
1487 DelayLoadDLLs += option+11;
1488 break;
1489 case 0x06d451e: // /DELAYSIGN[:NO]
1490 if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N'))
1491 DelaySign = _False;
1492 else
1493 DelaySign = _True;
1494 break;
1495 case 0x003390c: // /DLL
1496 // This option is not used for vcproj files
1497 break;
1498 case 0x2ee8415: // /DYNAMICBASE[:NO]
1499 if(*(option+12) == ':' && (*(option+13) == 'n' || *(option+13) == 'N'))
1500 RandomizedBaseAddress = _False;
1501 else
1502 RandomizedBaseAddress = _True;
1503 break;
1504 case 0x33a3979: // /ENTRY:function
1505 EntryPointSymbol = option+7;
1506 break;
1507 case 0x4504334: // /ERRORREPORT:[ NONE | PROMPT | QUEUE | SEND ]
1508 if(*(option+12) == ':' ) {
1509 if(*(option+13) == 'N')
1510 LinkErrorReporting = "NoErrorReport";
1511 else if(*(option+13) == 'P')
1512 LinkErrorReporting = "PromptImmediately";
1513 else if(*(option+13) == 'Q')
1514 LinkErrorReporting = "QueueForNextLogin";
1515 else if(*(option+13) == 'S')
1516 LinkErrorReporting = "SendErrorReport";
1517 }
1518 break;
1519 case 0x033c960: // /HEAP:reserve[,commit]
1520 {
1521 QStringList both = QString(option+6).split(",");
1522 HeapReserveSize = both[0].toLongLong();
1523 if(both.count() == 2)
1524 HeapCommitSize = both[1].toLongLong();
1525 }
1526 break;
1527 case 0x3d91494: // /IDLOUT:[path\]filename
1528 MergedIDLBaseFileName = option+8;
1529 break;
1530 case 0x345a04c: // /IGNOREIDL
1531 IgnoreEmbeddedIDL = _True;
1532 break;
1533 case 0x3e250e2: // /IMPLIB:filename
1534 ImportLibrary = option+8;
1535 break;
1536 case 0xe281ab5: // /INCLUDE:symbol
1537 ForceSymbolReferences += option+9;
1538 break;
1539 case 0xb28103c: // /INCREMENTAL[:no]
1540 if(*(option+12) == ':' &&
1541 (*(option+13) == 'n' || *(option+13) == 'N'))
1542 LinkIncremental = linkIncrementalNo;
1543 else
1544 LinkIncremental = linkIncrementalYes;
1545 break;
1546 case 0x07f1ab2: // /KEYCONTAINER:name
1547 KeyContainer = option+14;
1548 break;
1549 case 0xfadaf35: // /KEYFILE:filename
1550 KeyFile = option+9;
1551 break;
1552 case 0x26e4675: // /LARGEADDRESSAWARE[:no]
1553 if(*(option+18) == ':' &&
1554 *(option+19) == 'n')
1555 LargeAddressAware = addrAwareNoLarge;
1556 else
1557 LargeAddressAware = addrAwareLarge;
1558 break;
1559 case 0x2f96bc8: // /libpath:dir
1560 case 0x0d745c8: // /LIBPATH:dir
1561 AdditionalLibraryDirectories += option+9;
1562 break;
1563 case 0x0341877: // /LTCG[:NOSTATUS|:STATUS]
1564 config->WholeProgramOptimization = _True;
1565 if (config->CompilerVersion >= NET2005) {
1566 LinkTimeCodeGeneration = optLTCGEnabled;
1567 if(*(option+5) == ':') {
1568 const char* str = option+6;
1569 if (*str == 'S')
1570 ShowProgress = linkProgressAll;
1571 else if (qstricmp(str, "pginstrument") == 0)
1572 LinkTimeCodeGeneration = optLTCGInstrument;
1573 else if (qstricmp(str, "pgoptimize") == 0)
1574 LinkTimeCodeGeneration = optLTCGOptimize;
1575 else if (qstricmp(str, "pgupdate") == 0)
1576 LinkTimeCodeGeneration = optLTCGUpdate;
1577 }
1578 } else {
1579 AdditionalOptions.append(option);
1580 }
1581 break;
1582 case 0x379ED25:
1583 case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
1584 switch (elfHash(option+9)) {
1585 // Very limited documentation on all options but X86,
1586 case 0x0005bb6: // X86
1587 TargetMachine = machineX86;
1588 break;
1589 case 0x0005b94: // X64
1590 TargetMachine = machineX64;
1591 break;
1592 // so we put the others in AdditionalOptions...
1593 case 0x0046063: // AM33
1594 case 0x000466d: // ARM
1595 case 0x0004795: // CEE
1596 case 0x0004963: // EBC
1597 case 0x004d494: // IA64
1598 case 0x0050672: // M32R
1599 case 0x0051e53: // MIPS
1600 case 0x51e5646: // MIPS16
1601 case 0x1e57b05: // MIPSFPU
1602 case 0x57b09a6: // MIPSFPU16
1603 case 0x5852738: // MIPSR41XX
1604 case 0x0005543: // PPC
1605 case 0x00057b3: // SH3
1606 case 0x57b7980: // SH3DSP
1607 case 0x00057b4: // SH4
1608 case 0x00057b5: // SH5
1609 case 0x058da12: // THUMB
1610 case 0x96d8435: // TRICORE
1611 default:
1612 AdditionalOptions += option;
1613 break;
1614 }
1615 break;
1616 case 0x0034160: // /MAP[:filename]
1617 GenerateMapFile = _True;
1618 if (option[4] == ':')
1619 MapFileName = option+5;
1620 break;
1621 case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
1622 if(*(option+9) == 'E')
1623 MapExports = _True;
1624 else if(*(option+9) == 'L')
1625 MapLines = _True;
1626 break;
1627 case 0x341a6b5: // /MERGE:from=to
1628 if (MergeSections.isEmpty()) {
1629 MergeSections = option+7;
1630 } else {
1631 // vcxproj files / the VS property editor do not support multiple MergeSections entries.
1632 // Add them as additional options.
1633 AdditionalOptions += option;
1634 }
1635 break;
1636 case 0x0341d8c: // /MIDL:@file
1637 MidlCommandFile = option+7;
1638 break;
1639 case 0x84e2679: // /NOASSEMBLY
1640 TurnOffAssemblyGeneration = _True;
1641 break;
1642 case 0x2b21942: // /NODEFAULTLIB[:library]
1643 if(*(option+13) == '\0')
1644 IgnoreAllDefaultLibraries = _True;
1645 else
1646 IgnoreDefaultLibraryNames += option+14;
1647 break;
1648 case 0x33a3a39: // /NOENTRY
1649 ResourceOnlyDLL = _True;
1650 break;
1651 case 0x434138f: // /NOLOGO
1652 SuppressStartupBanner = _True;
1653 break;
1654 case 0xc841054: // /NXCOMPAT[:NO]
1655 if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n')))
1656 DataExecutionPrevention = _False;
1657 else
1658 DataExecutionPrevention = _True;
1659 break;
1660 case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98}
1661 {
1662 char third = *(option+7);
1663 switch (third) {
1664 case 'F': // REF
1665 if(*(option+5) == 'R') {
1666 OptimizeReferences = optReferences;
1667 } else { // ICF[=iterations]
1668 EnableCOMDATFolding = optFolding;
1669 // [=iterations] case is not documented
1670 }
1671 break;
1672 case 'R': // NOREF
1673 OptimizeReferences = optNoReferences;
1674 break;
1675 case 'I': // NOICF
1676 EnableCOMDATFolding = optNoFolding;
1677 break;
1678 case 'N': // WIN98
1679 OptimizeForWindows98 = optWin98Yes;
1680 break;
1681 case 'W': // NOWIN98
1682 OptimizeForWindows98 = optWin98No;
1683 break;
1684 default:
1685 found = false;
1686 }
1687 }
1688 break;
1689 case 0x34468a2: // /ORDER:@filename
1690 FunctionOrder = option+8;
1691 break;
1692 case 0x00344a4: // /OUT:filename
1693 OutputFile = option+5;
1694 break;
1695 case 0x0034482: // /PDB:filename
1696 ProgramDatabaseFile = option+5;
1697 break;
1698 case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name
1699 StripPrivateSymbols = option+13;
1700 break;
1701 case 0x6a09535: // /RELEASE
1702 SetChecksum = _True;
1703 break;
1704 case 0x348857b: // /STACK:reserve[,commit]
1705 {
1706 QStringList both = QString(option+7).split(",");
1707 StackReserveSize = both[0].toLongLong();
1708 if(both.count() == 2)
1709 StackCommitSize = both[1].toLongLong();
1710 }
1711 break;
1712 case 0x75AA4D8: // /SAFESEH:{NO}
1713 if (config->CompilerVersion >= NET2010)
1714 ImageHasSafeExceptionHandlers = (option[8] == ':') ? _False : _True;
1715 else
1716 AdditionalOptions += option;
1717 break;
1718 case 0x9B3C00D:
1719 case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
1720 {
1721 // Split up in subsystem, and version number
1722 QStringList both = QString(option+11).split(",");
1723 switch (elfHash(both[0].toLatin1().constData())) {
1724 case 0x8438445: // CONSOLE
1725 SubSystem = subSystemConsole;
1726 break;
1727 case 0xbe29493: // WINDOWS
1728 SubSystem = subSystemWindows;
1729 break;
1730 // The following are undocumented, so add them to AdditionalOptions
1731 case 0x240949e: // EFI_APPLICATION
1732 case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
1733 case 0x9af477d: // EFI_ROM
1734 case 0xd34df42: // EFI_RUNTIME_DRIVER
1735 case 0x5268ea5: // NATIVE
1736 case 0x05547e8: // POSIX
1737 case 0x2949c95: // WINDOWSCE
1738 case 0x4B69795: // windowsce
1739 AdditionalOptions += option;
1740 break;
1741 default:
1742 found = false;
1743 }
1744 }
1745 break;
1746 case 0x8b654de: // /SWAPRUN:{NET | CD}
1747 if(*(option+9) == 'N')
1748 SwapRunFromNet = _True;
1749 else if(*(option+9) == 'C')
1750 SwapRunFromCD = _True;
1751 else
1752 found = false;
1753 break;
1754 case 0x34906d4: // /TLBID:id
1755 TypeLibraryResourceID = QString(option+7).toLongLong();
1756 break;
1757 case 0x4907494: // /TLBOUT:[path\]filename
1758 TypeLibraryFile = option+8;
1759 break;
1760 case 0x976b525: // /TSAWARE[:NO]
1761 if(*(option+8) == ':')
1762 TerminalServerAware = termSvrAwareNo;
1763 else
1764 TerminalServerAware = termSvrAwareYes;
1765 break;
1766 case 0xaa67735: // /VERBOSE[:lib]
1767 if(*(option+9) == ':') {
1768 ShowProgress = linkProgressLibs;
1769 AdditionalOptions += option;
1770 } else {
1771 ShowProgress = linkProgressAll;
1772 }
1773 break;
1774 case 0xaa77f7e: // /VERSION:major[.minor]
1775 Version = option+9;
1776 break;
1777 case 0x0034c50: // /WS[:NO]
1778 if (config->CompilerVersion >= NET2010) {
1779 if(*(option+3) == ':')
1780 TreatWarningsAsErrors = _False;
1781 else
1782 TreatWarningsAsErrors = _True;
1783 } else {
1784 AdditionalOptions += option;
1785 }
1786 break;
1787 default:
1788 AdditionalOptions += option;
1789 break;
1790 }
1791 if(!found) {
1792 if (!config->suppressUnknownOptionWarnings)
1793 unknownOptionWarning("Linker", option);
1794 AdditionalOptions += option;
1795 }
1796 return found;
1797}
1798
1799// VCManifestTool ---------------------------------------------------
1800VCManifestTool::VCManifestTool()
1801 : EmbedManifest(unset)
1802{
1803}
1804
1805bool VCManifestTool::parseOption(const char *option)
1806{
1807 Q_UNUSED(option);
1808 // ### implement if we introduce QMAKE_MT_FLAGS
1809 return false;
1810}
1811
1812// VCMIDLTool -------------------------------------------------------
1813VCMIDLTool::VCMIDLTool()
1814 : DefaultCharType(midlCharUnsigned),
1815 EnableErrorChecks(midlDisableAll),
1816 ErrorCheckAllocations(unset),
1817 ErrorCheckBounds(unset),
1818 ErrorCheckEnumRange(unset),
1819 ErrorCheckRefPointers(unset),
1820 ErrorCheckStubData(unset),
1821 GenerateStublessProxies(unset),
1822 GenerateTypeLibrary(unset),
1823 IgnoreStandardIncludePath(unset),
1824 MkTypLibCompatible(unset),
1825 StructMemberAlignment(midlAlignNotSet),
1826 SuppressStartupBanner(unset),
1827 TargetEnvironment(midlTargetNotSet),
1828 ValidateParameters(unset),
1829 WarnAsError(unset),
1830 WarningLevel(midlWarningLevel_0),
1831 ApplicationConfigurationMode(unset),
1832 ValidateAllParameters(unset),
1833 SuppressCompilerWarnings(unset),
1834 LocaleID(-1)
1835{
1836}
1837
1838bool VCMIDLTool::parseOption(const char* option)
1839{
1840#ifdef USE_DISPLAY_HASH
1841 displayHash("/D name[=def]"); displayHash("/I directory-list"); displayHash("/Oi");
1842 displayHash("/Oic"); displayHash("/Oicf"); displayHash("/Oif"); displayHash("/Os");
1843 displayHash("/U name"); displayHash("/WX"); displayHash("/W{0|1|2|3|4}");
1844 displayHash("/Zp {N}"); displayHash("/Zs"); displayHash("/acf filename");
1845 displayHash("/align {N}"); displayHash("/app_config"); displayHash("/c_ext");
1846 displayHash("/char ascii7"); displayHash("/char signed"); displayHash("/char unsigned");
1847 displayHash("/client none"); displayHash("/client stub"); displayHash("/confirm");
1848 displayHash("/cpp_cmd cmd_line"); displayHash("/cpp_opt options");
1849 displayHash("/cstub filename"); displayHash("/dlldata filename"); displayHash("/env win32");
1850 displayHash("/env win64"); displayHash("/error all"); displayHash("/error allocation");
1851 displayHash("/error bounds_check"); displayHash("/error enum"); displayHash("/error none");
1852 displayHash("/error ref"); displayHash("/error stub_data"); displayHash("/h filename");
1853 displayHash("/header filename"); displayHash("/iid filename"); displayHash("/lcid");
1854 displayHash("/mktyplib203"); displayHash("/ms_ext"); displayHash("/ms_union");
1855 displayHash("/msc_ver <nnnn>"); displayHash("/newtlb"); displayHash("/no_cpp");
1856 displayHash("/no_def_idir"); displayHash("/no_default_epv"); displayHash("/no_format_opt");
1857 displayHash("/no_warn"); displayHash("/nocpp"); displayHash("/nologo"); displayHash("/notlb");
1858 displayHash("/o filename"); displayHash("/oldnames"); displayHash("/oldtlb");
1859 displayHash("/osf"); displayHash("/out directory"); displayHash("/pack {N}");
1860 displayHash("/prefix all"); displayHash("/prefix client"); displayHash("/prefix server");
1861 displayHash("/prefix switch"); displayHash("/protocol all"); displayHash("/protocol dce");
1862 displayHash("/protocol ndr64"); displayHash("/proxy filename"); displayHash("/robust");
1863 displayHash("/rpcss"); displayHash("/savePP"); displayHash("/server none");
1864 displayHash("/server stub"); displayHash("/sstub filename"); displayHash("/syntax_check");
1865 displayHash("/target {system}"); displayHash("/tlb filename"); displayHash("/use_epv");
1866 displayHash("/win32"); displayHash("/win64");
1867#endif
1868 bool found = true;
1869 int offset = 0;
1870
1871 const uint optionHash = elfHash(option);
1872
1873 if (config->CompilerVersion < NET2010) {
1874 switch (optionHash) {
1875 case 0x5b1cb97: // /app_config
1876 case 0x5a2fc64: // /client {none|stub}
1877 case 0x35aabb2: // /cstub filename
1878 case 0x64ceb12: // /newtlb
1879 case 0x556dbee: // /no_warn
1880 case 0x662bb12: // /oldtlb
1881 case 0x69c9cf2: // /server {none|stub}
1882 case 0x36aabb2: // /sstub filename
1883 AdditionalOptions += option;
1884 return true;
1885 }
1886 }
1887
1888 switch(optionHash) {
1889 case 0x0000334: // /D name[=def]
1890 PreprocessorDefinitions += option+3;
1891 break;
1892 case 0x0000339: // /I directory-list
1893 AdditionalIncludeDirectories += option+3;
1894 break;
1895 case 0x0345f96: // /Oicf
1896 case 0x00345f6: // /Oif
1897 GenerateStublessProxies = _True;
1898 break;
1899 case 0x0000345: // /U name
1900 UndefinePreprocessorDefinitions += option+3;
1901 break;
1902 case 0x00034c8: // /WX
1903 WarnAsError = _True;
1904 break;
1905 case 0x3582fde: // /align {N}
1906 offset = 3;
1907 Q_FALLTHROUGH();
1908 case 0x0003510: // /Zp {N}
1909 switch (*(option+offset+4)) {
1910 case '1':
1911 StructMemberAlignment = (*(option+offset+5) == '\0') ? midlAlignSingleByte : midlAlignSixteenBytes;
1912 break;
1913 case '2':
1914 StructMemberAlignment = midlAlignTwoBytes;
1915 break;
1916 case '4':
1917 StructMemberAlignment = midlAlignFourBytes;
1918 break;
1919 case '8':
1920 StructMemberAlignment = midlAlignEightBytes;
1921 break;
1922 default:
1923 found = false;
1924 }
1925 break;
1926 case 0x5b1cb97: // /app_config
1927 ApplicationConfigurationMode = _True;
1928 break;
1929 case 0x0359e82: // /char {ascii7|signed|unsigned}
1930 switch(*(option+6)) {
1931 case 'a':
1932 DefaultCharType = midlCharAscii7;
1933 break;
1934 case 's':
1935 DefaultCharType = midlCharSigned;
1936 break;
1937 case 'u':
1938 DefaultCharType = midlCharUnsigned;
1939 break;
1940 default:
1941 found = false;
1942 }
1943 break;
1944 case 0x5a2fc64: // /client {none|stub}
1945 if(*(option+8) == 's')
1946 GenerateClientFiles = "Stub";
1947 else
1948 GenerateClientFiles = "None";
1949 break;
1950 case 0xa766524: // /cpp_opt options
1951 CPreprocessOptions += option+9;
1952 break;
1953 case 0x35aabb2: // /cstub filename
1954 ClientStubFile = option+7;
1955 break;
1956 case 0xb32abf1: // /dlldata filename
1957 DLLDataFileName = option + 9;
1958 break;
1959 case 0x0035c56: // /env {win32|win64}
1960 TargetEnvironment = (*(option+8) == '6') ? midlTargetWin64 : midlTargetWin32;
1961 break;
1962 case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data}
1963 EnableErrorChecks = midlEnableCustom;
1964 switch (*(option+7)) {
1965 case 'a':
1966 if(*(option+10) == '\0')
1967 EnableErrorChecks = midlEnableAll;
1968 else
1969 ErrorCheckAllocations = _True;
1970 break;
1971 case 'b':
1972 ErrorCheckBounds = _True;
1973 break;
1974 case 'e':
1975 ErrorCheckEnumRange = _True;
1976 break;
1977 case 'n':
1978 EnableErrorChecks = midlDisableAll;
1979 break;
1980 case 'r':
1981 ErrorCheckRefPointers = _True;
1982 break;
1983 case 's':
1984 ErrorCheckStubData = _True;
1985 break;
1986 default:
1987 found = false;
1988 }
1989 break;
1990 case 0x5eb7af2: // /header filename
1991 offset = 5;
1992 Q_FALLTHROUGH();
1993 case 0x0000358: // /h filename
1994 HeaderFileName = option + offset + 3;
1995 break;
1996 case 0x0035ff4: // /iid filename
1997 InterfaceIdentifierFileName = option+5;
1998 break;
1999 case 0x64b7933: // /mktyplib203
2000 MkTypLibCompatible = _True;
2001 break;
2002 case 0x64ceb12: // /newtlb
2003 TypeLibFormat = "NewFormat";
2004 break;
2005 case 0x8e0b0a2: // /no_def_idir
2006 IgnoreStandardIncludePath = _True;
2007 break;
2008 case 0x65635ef: // /nologo
2009 SuppressStartupBanner = _True;
2010 break;
2011 case 0x695e9f4: // /no_robust
2012 ValidateAllParameters = _False;
2013 break;
2014 case 0x3656b22: // /notlb
2015 GenerateTypeLibrary = _True;
2016 break;
2017 case 0x556dbee: // /no_warn
2018 SuppressCompilerWarnings = _True;
2019 break;
2020 case 0x000035f: // /o filename
2021 RedirectOutputAndErrors = option+3;
2022 break;
2023 case 0x662bb12: // /oldtlb
2024 TypeLibFormat = "OldFormat";
2025 break;
2026 case 0x00366c4: // /out directory
2027 OutputDirectory = option+5;
2028 break;
2029 case 0x36796f9: // /proxy filename
2030 ProxyFileName = option+7;
2031 break;
2032 case 0x6959c94: // /robust
2033 ValidateParameters = _True;
2034 break;
2035 case 0x6a88df4: // /target {system}
2036 if(*(option+11) == '6')
2037 TargetEnvironment = midlTargetWin64;
2038 else
2039 TargetEnvironment = midlTargetWin32;
2040 break;
2041 case 0x69c9cf2: // /server {none|stub}
2042 if(*(option+8) == 's')
2043 GenerateServerFiles = "Stub";
2044 else
2045 GenerateServerFiles = "None";
2046 break;
2047 case 0x36aabb2: // /sstub filename
2048 ServerStubFile = option+7;
2049 break;
2050 case 0x0036b22: // /tlb filename
2051 TypeLibraryName = option+5;
2052 break;
2053 case 0x36e0162: // /win32
2054 TargetEnvironment = midlTargetWin32;
2055 break;
2056 case 0x36e0194: // /win64
2057 TargetEnvironment = midlTargetWin64;
2058 break;
2059 case 0x0003459: // /Oi
2060 case 0x00345f3: // /Oic
2061 case 0x0003463: // /Os
2062 case 0x0003513: // /Zs
2063 case 0x0035796: // /acf filename
2064 case 0x3595cf4: // /c_ext
2065 case 0xa64d3dd: // /confirm
2066 case 0xa765b64: // /cpp_cmd cmd_line
2067 case 0x03629f4: // /lcid
2068 case 0x6495cc4: // /ms_ext
2069 case 0x96c7a1e: // /ms_union
2070 case 0x4996fa2: // /msc_ver <nnnn>
2071 case 0x6555a40: // /no_cpp
2072 case 0xf64d6a6: // /no_default_epv
2073 case 0x6dd9384: // /no_format_opt
2074 case 0x3655a70: // /nocpp
2075 case 0x2b455a3: // /oldnames
2076 case 0x0036696: // /osf
2077 case 0x036679b: // /pack {N}
2078 case 0x678bd38: // /prefix {all|client|server|switch}
2079 case 0x96b702c: // /protocol {all|dce|ndr64}
2080 case 0x3696aa3: // /rpcss
2081 case 0x698ca60: // /savePP
2082 case 0xce9b12b: // /syntax_check
2083 case 0xc9b5f16: // /use_epv
2084 AdditionalOptions += option;
2085 break;
2086 default:
2087 // /W{0|1|2|3|4} case
2088 if(*(option+1) == 'W') {
2089 switch (*(option+2)) {
2090 case '0':
2091 WarningLevel = midlWarningLevel_0;
2092 break;
2093 case '1':
2094 WarningLevel = midlWarningLevel_1;
2095 break;
2096 case '2':
2097 WarningLevel = midlWarningLevel_2;
2098 break;
2099 case '3':
2100 WarningLevel = midlWarningLevel_3;
2101 break;
2102 case '4':
2103 WarningLevel = midlWarningLevel_4;
2104 break;
2105 default:
2106 found = false;
2107 }
2108 }
2109 break;
2110 }
2111 if(!found)
2112 warn_msg(WarnLogic, "Could not parse MIDL option: %s", option);
2113 return true;
2114}
2115
2116// VCLibrarianTool --------------------------------------------------
2117VCLibrarianTool::VCLibrarianTool()
2118 : IgnoreAllDefaultLibraries(unset),
2119 SuppressStartupBanner(_True)
2120{
2121}
2122
2123// VCCustomBuildTool ------------------------------------------------
2124VCCustomBuildTool::VCCustomBuildTool()
2125{
2126 ToolName = "VCCustomBuildTool";
2127}
2128
2129// VCResourceCompilerTool -------------------------------------------
2130VCResourceCompilerTool::VCResourceCompilerTool()
2131 : Culture(rcUseDefault),
2132 IgnoreStandardIncludePath(unset),
2133 ShowProgress(linkProgressNotSet),
2134 SuppressStartupBanner(unset)
2135{
2136}
2137
2138// VCDeploymentTool --------------------------------------------
2139VCDeploymentTool::VCDeploymentTool()
2140 : RegisterOutput(registerNo)
2141{
2142 DeploymentTag = "DeploymentTool";
2143 RemoteDirectory = "";
2144}
2145
2146VCEventTool::VCEventTool(const QString &eventName)
2147 : ExcludedFromBuild(unset)
2148{
2149 EventName = eventName;
2150 ToolName = "VC";
2151 ToolName += eventName;
2152 ToolName += "Tool";
2153}
2154
2155// VCPostBuildEventTool ---------------------------------------------
2156VCPostBuildEventTool::VCPostBuildEventTool()
2157 : VCEventTool("PostBuildEvent")
2158{
2159}
2160
2161// VCPreBuildEventTool ----------------------------------------------
2162VCPreBuildEventTool::VCPreBuildEventTool()
2163 : VCEventTool("PreBuildEvent")
2164{
2165}
2166
2167// VCPreLinkEventTool -----------------------------------------------
2168VCPreLinkEventTool::VCPreLinkEventTool()
2169 : VCEventTool("PreLinkEvent")
2170{
2171}
2172
2173// VCConfiguration --------------------------------------------------
2174
2175VCConfiguration::VCConfiguration()
2176 : ATLMinimizesCRunTimeLibraryUsage(unset),
2177 BuildBrowserInformation(unset),
2178 CharacterSet(charSetNotSet),
2179 ConfigurationType(typeApplication),
2180 RegisterOutput(unset),
2181 UseOfATL(useATLNotSet),
2182 UseOfMfc(useMfcStdWin),
2183 WholeProgramOptimization(unset)
2184{
2185 compiler.config = this;
2186 linker.config = this;
2187 idl.config = this;
2188}
2189
2190// VCFilter ---------------------------------------------------------
2191VCFilter::VCFilter()
2192 : ParseFiles(unset),
2193 Config(nullptr)
2194{
2195 useCustomBuildTool = false;
2196 useCompilerTool = false;
2197}
2198
2199void VCFilter::addFile(const QString& filename)
2200{
2201 Files += VCFilterFile(filename);
2202}
2203
2204void VCFilter::addFile(const VCFilterFile& fileInfo)
2205{
2206 Files += VCFilterFile(fileInfo);
2207}
2208
2209void VCFilter::addFiles(const QStringList& fileList)
2210{
2211 for (int i = 0; i < fileList.count(); ++i)
2212 addFile(fileList.at(i));
2213}
2214
2215void VCFilter::addFiles(const ProStringList& fileList)
2216{
2217 for (int i = 0; i < fileList.count(); ++i)
2218 addFile(fileList.at(i).toQString());
2219}
2220
2221void VCFilter::modifyPCHstage(QString str)
2222{
2223 const bool isHFile = (str == Project->precompH);
2224 const bool pchThroughSourceFile = !Project->precompSource.isEmpty();
2225 if (isHFile && pchThroughSourceFile && Project->autogenPrecompSource) {
2226 useCustomBuildTool = true;
2227 QString toFile(Project->precompSource);
2228 CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ...";
2229 CustomBuildTool.Outputs += toFile;
2230
2231 QStringList lines;
2232 CustomBuildTool.CommandLine +=
2233 "echo /*-------------------------------------------------------------------- >" + toFile;
2234 lines << "* Precompiled header source file used by Visual Studio.NET to generate";
2235 lines << "* the .pch file.";
2236 lines << "*";
2237 lines << "* Due to issues with the dependencies checker within the IDE, it";
2238 lines << "* sometimes fails to recompile the PCH file, if we force the IDE to";
2239 lines << "* create the PCH file directly from the header file.";
2240 lines << "*";
2241 lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was";
2242 lines << "* specified, and is used as the common stdafx.cpp. The file is only";
2243 lines << QLatin1String("* generated when creating ")
2244 + (Config->CompilerVersion < NET2010 ? ".vcproj" : ".vcxproj")
2245 + " project files, and is not used for";
2246 lines << "* command line compilations by nmake.";
2247 lines << "*";
2248 lines << "* WARNING: All changes made in this file will be lost.";
2249 lines << "--------------------------------------------------------------------*/";
2250 lines << "#include \"" + Project->precompHFilename + "\"";
2251 for (const QString &line : qAsConst(lines))
2252 CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile;
2253 return;
2254 }
2255
2256 useCompilerTool = true;
2257 const bool isPrecompSource = pchThroughSourceFile && (str == Project->precompSource);
2258 if (isPrecompSource) {
2259 CompilerTool.UsePrecompiledHeader = pchCreateUsingSpecific;
2260 if (Project->autogenPrecompSource)
2261 CompilerTool.PrecompiledHeaderThrough = Project->precompHFilename;
2262 CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)");
2263 return;
2264 }
2265
2266 bool isCFile = false;
2267 for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) {
2268 if (str.endsWith(*it)) {
2269 isCFile = true;
2270 break;
2271 }
2272 }
2273
2274 bool pchCompatible = (isCFile == Project->pchIsCFile);
2275 if (!pchCompatible) {
2276 CompilerTool.UsePrecompiledHeader = pchNone;
2277 CompilerTool.PrecompiledHeaderThrough = QLatin1String("$(NOINHERIT)");
2278 CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)");
2279 }
2280}
2281
2282VCFilterFile VCFilter::findFile(const QString &filePath, bool *found) const
2283{
2284 for (int i = 0; i < Files.count(); ++i) {
2285 const VCFilterFile &f = Files.at(i);
2286 if (f.file == filePath) {
2287 *found = true;
2288 return f;
2289 }
2290 }
2291 *found = false;
2292 return VCFilterFile();
2293}
2294
2295bool VCFilter::addExtraCompiler(const VCFilterFile &info)
2296{
2297 const QStringList &extraCompilers = Project->extraCompilerSources.value(info.file);
2298 if (extraCompilers.isEmpty())
2299 return false;
2300
2301 QString inFile = info.file;
2302
2303 // is the extracompiler rule on a file with a built in compiler?
2304 const QString objectMappedFile = Project->extraCompilerOutputs.value(inFile);
2305 bool hasBuiltIn = false;
2306 if (!objectMappedFile.isEmpty()) {
2307 hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile);
2308
2309 // Remove the fake file suffix we've added initially to generate correct command lines.
2310 inFile.chop(Project->customBuildToolFilterFileSuffix.length());
2311
2312// qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' ')));
2313 }
2314
2315 CustomBuildTool.AdditionalDependencies.clear();
2316 CustomBuildTool.CommandLine.clear();
2317 CustomBuildTool.Description.clear();
2318 CustomBuildTool.Outputs.clear();
2319 CustomBuildTool.ToolPath.clear();
2320 CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
2321
2322 for (int x = 0; x < extraCompilers.count(); ++x) {
2323 const QString &extraCompilerName = extraCompilers.at(x);
2324
2325 if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn)
2326 continue;
2327
2328 // All information about the extra compiler
2329 QString tmp_out = Project->project->first(ProKey(extraCompilerName + ".output")).toQString();
2330 QString tmp_cmd = Project->project->values(ProKey(extraCompilerName + ".commands")).join(' ');
2331 QString tmp_cmd_name = Project->project->values(ProKey(extraCompilerName + ".name")).join(' ');
2332 QStringList tmp_dep = Project->project->values(ProKey(extraCompilerName + ".depends")).toQStringList();
2333 QString tmp_dep_cmd = Project->project->values(ProKey(extraCompilerName + ".depend_command")).join(' ');
2334 const ProStringList &configs = Project->project->values(ProKey(extraCompilerName + ".CONFIG"));
2335 bool combined = configs.indexOf("combine") != -1;
2336
2337 QString cmd, cmd_name, out;
2338 QStringList deps, inputs;
2339 // Variabel replacement of output name
2340 out = Option::fixPathToTargetOS(Project->replaceExtraCompilerVariables(
2341 tmp_out, inFile, QString(), MakefileGenerator::NoShell), false);
2342
2343 // If file has built-in compiler, we've swapped the input and output of
2344 // the command, as we in Visual Studio cannot have a Custom Buildstep on
2345 // a file which uses a built-in compiler. We would in this case only get
2346 // the result from the extra compiler. If 'hasBuiltIn' is true, we know
2347 // that we're actually on the _output_file_ of the result, and we
2348 // therefore swap inFile and out below, since the extra-compiler still
2349 // must see it as the original way. If the result also has a built-in
2350 // compiler, too bad..
2351 if (hasBuiltIn) {
2352 out = inFile;
2353 inFile = objectMappedFile;
2354 }
2355
2356 // Dependency for the output
2357 if (!tmp_dep.isEmpty())
2358 deps = tmp_dep;
2359 if (!tmp_dep_cmd.isEmpty()) {
2360 Project->callExtraCompilerDependCommand(extraCompilerName, tmp_dep_cmd,
2361 inFile, out,
2362 true, // dep_lines
2363 &deps,
2364 configs.contains("dep_existing_only"),
2365 true /* checkCommandAvailability */);
2366 }
2367 for (int i = 0; i < deps.count(); ++i)
2368 deps[i] = Option::fixPathToTargetOS(
2369 Project->replaceExtraCompilerVariables(
2370 deps.at(i), inFile, out, MakefileGenerator::NoShell),
2371 false);
2372 // Command for file
2373 if (combined) {
2374 // Add dependencies for each file
2375 const ProStringList &tmp_in = Project->project->values(ProKey(extraCompilerName + ".input"));
2376 for (int a = 0; a < tmp_in.count(); ++a) {
2377 const ProStringList &files = Project->project->values(tmp_in.at(a).toKey());
2378 for (int b = 0; b < files.count(); ++b) {
2379 QString file = files.at(b).toQString();
2380 deps += Project->findDependencies(file);
2381 inputs += Option::fixPathToTargetOS(file, false);
2382 }
2383 }
2384 deps = inputs + deps; // input files themselves too..
2385
2386 // Replace variables for command w/all input files
2387 cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
2388 inputs,
2389 QStringList(out),
2390 MakefileGenerator::TargetShell);
2391 } else {
2392 deps.prepend(inFile); // input file itself too..
2393 cmd = Project->replaceExtraCompilerVariables(tmp_cmd,
2394 inFile,
2395 out,
2396 MakefileGenerator::TargetShell);
2397 }
2398 // Name for command
2399 if (!tmp_cmd_name.isEmpty()) {
2400 cmd_name = Project->replaceExtraCompilerVariables(
2401 tmp_cmd_name, inFile, out, MakefileGenerator::NoShell);
2402 } else {
2403 int space = cmd.indexOf(' ');
2404 if (space != -1)
2405 cmd_name = cmd.left(space);
2406 else
2407 cmd_name = cmd;
2408 }
2409
2410 // Fixify paths
2411 for (int i = 0; i < deps.count(); ++i)
2412 deps[i] = Option::fixPathToTargetOS(deps[i], false);
2413
2414
2415 // Output in info.additionalFile -----------
2416 if (!CustomBuildTool.Description.isEmpty())
2417 CustomBuildTool.Description += ", ";
2418 CustomBuildTool.Description += cmd_name;
2419 CustomBuildTool.CommandLine += VCToolBase::fixCommandLine(cmd.trimmed());
2420 int space = cmd.indexOf(' ');
2421 QFileInfo finf(cmd.left(space));
2422 if (CustomBuildTool.ToolPath.isEmpty())
2423 CustomBuildTool.ToolPath += Option::fixPathToTargetOS(finf.path());
2424 CustomBuildTool.Outputs += out;
2425
2426 deps += CustomBuildTool.AdditionalDependencies;
2427 // Make sure that all deps are only once
2428 QStringList uniqDeps;
2429 for (int c = 0; c < deps.count(); ++c) {
2430 QString aDep = deps.at(c);
2431 if (!aDep.isEmpty())
2432 uniqDeps << aDep;
2433 }
2434 uniqDeps.removeDuplicates();
2435 CustomBuildTool.AdditionalDependencies = uniqDeps;
2436 }
2437
2438 // Ensure that none of the output files are also dependencies. Or else, the custom buildstep
2439 // will be rebuild every time, even if nothing has changed.
2440 for (const QString &output : qAsConst(CustomBuildTool.Outputs))
2441 CustomBuildTool.AdditionalDependencies.removeAll(output);
2442
2443 useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty();
2444 return useCustomBuildTool;
2445}
2446
2447// VCProjectSingleConfig --------------------------------------------
2448const VCFilter &VCProjectSingleConfig::filterByName(const QString &name) const
2449{
2450 if (name == "Root Files")
2451 return RootFiles;
2452 if (name == "Source Files")
2453 return SourceFiles;
2454 if (name == "Header Files")
2455 return HeaderFiles;
2456 if (name == "Generated Files")
2457 return GeneratedFiles;
2458 if (name == "LexYacc Files")
2459 return LexYaccFiles;
2460 if (name == "Translation Files")
2461 return TranslationFiles;
2462 if (name == "Form Files")
2463 return FormFiles;
2464 if (name == "Resource Files")
2465 return ResourceFiles;
2466 if (name == "Deployment Files")
2467 return DeploymentFiles;
2468 if (name == "Distribution Files")
2469 return DistributionFiles;
2470 return filterForExtraCompiler(name);
2471}
2472
2473const VCFilter &VCProjectSingleConfig::filterForExtraCompiler(const QString &compilerName) const
2474{
2475 for (int i = 0; i < ExtraCompilersFiles.count(); ++i)
2476 if (ExtraCompilersFiles.at(i).Name == compilerName)
2477 return ExtraCompilersFiles.at(i);
2478
2479 static VCFilter nullFilter;
2480 return nullFilter;
2481}
2482
2483// Tree file generation ---------------------------------------------
2484void TreeNode::generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter) {
2485 if (children.size()) {
2486 // Filter
2487 ChildrenMap::ConstIterator it, end = children.constEnd();
2488 if (!tagName.isEmpty()) {
2489 xml << tag("Filter")
2490 << attr("Name", tagName)
2491 << attr("Filter", "");
2492 }
2493 // First round, do nested filters
2494 for (it = children.constBegin(); it != end; ++it)
2495 if ((*it)->children.size())
2496 (*it)->generateXML(xml, it.key(), tool, filter);
2497 // Second round, do leafs
2498 for (it = children.constBegin(); it != end; ++it)
2499 if (!(*it)->children.size())
2500 (*it)->generateXML(xml, it.key(), tool, filter);
2501
2502 if (!tagName.isEmpty())
2503 xml << closetag("Filter");
2504 } else {
2505 // Leaf
2506 VCProjectWriter::outputFileConfigs(tool, xml, info, filter);
2507 }
2508}
2509
2510// Flat file generation ---------------------------------------------
2511void FlatNode::generateXML(XmlOutput &xml, const QString &/*tagName*/, VCProject &tool, const QString &filter) {
2512 if (children.size()) {
2513 ChildrenMapFlat::ConstIterator it = children.constBegin();
2514 ChildrenMapFlat::ConstIterator end = children.constEnd();
2515 for (; it != end; ++it) {
2516 VCProjectWriter::outputFileConfigs(tool, xml, (*it), filter);
2517 }
2518 }
2519}
2520
2521void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
2522{
2523 xml << decl("1.0", "Windows-1252")
2524 << tag(_VisualStudioProject)
2525 << attrS(_ProjectType, "Visual C++")
2526 << attrS(_Version, tool.Version)
2527 << attrS(_Name, tool.Name)
2528 << attrS(_ProjectGUID, tool.ProjectGUID)
2529 << attrS(_Keyword, tool.Keyword)
2530 << attrS(_SccProjectName, tool.SccProjectName)
2531 << attrS(_SccLocalPath, tool.SccLocalPath)
2532 << tag(_Platforms)
2533 << tag(_Platform)
2534 << attrS(_Name, tool.PlatformName)
2535 << closetag(_Platforms)
2536 << tag(_Configurations);
2537 write(xml, tool.Configuration);
2538 xml << closetag(_Configurations)
2539 << tag(q_Files);
2540 // Add this configuration into a multi-config project, since that's where we have the flat/tree
2541 // XML output functionality
2542 VCProject tempProj;
2543 tempProj.SingleProjects += tool;
2544 outputFilter(tempProj, xml, "Source Files");
2545 outputFilter(tempProj, xml, "Header Files");
2546 outputFilter(tempProj, xml, "Generated Files");
2547 outputFilter(tempProj, xml, "LexYacc Files");
2548 outputFilter(tempProj, xml, "Translation Files");
2549 outputFilter(tempProj, xml, "Form Files");
2550 outputFilter(tempProj, xml, "Resource Files");
2551 outputFilter(tempProj, xml, "Deployment Files");
2552 outputFilter(tempProj, xml, "Distribution Files");
2553
2554 QSet<QString> extraCompilersInProject;
2555 for (int i = 0; i < tool.ExtraCompilersFiles.count(); ++i) {
2556 const QString &compilerName = tool.ExtraCompilersFiles.at(i).Name;
2557 if (!extraCompilersInProject.contains(compilerName)) {
2558 extraCompilersInProject += compilerName;
2559 tempProj.ExtraCompilers += compilerName;
2560 }
2561 }
2562
2563 for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) {
2564 outputFilter(tempProj, xml, tempProj.ExtraCompilers.at(x));
2565 }
2566 outputFilter(tempProj, xml, "Root Files");
2567 xml << closetag(q_Files)
2568 << tag(_Globals)
2569 << data(); // No "/>" end tag
2570}
2571
2572void VCProjectWriter::write(XmlOutput &xml, VCProject &tool)
2573{
2574 if (tool.SingleProjects.count() == 0) {
2575 warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output");
2576 return;
2577 }
2578
2579 xml << decl("1.0", "Windows-1252")
2580 << tag(_VisualStudioProject)
2581 << attrS(_ProjectType, "Visual C++")
2582 << attrS(_Version, tool.Version)
2583 << attrS(_Name, tool.Name)
2584 << attrS(_ProjectGUID, tool.ProjectGUID)
2585 << attrS(_Keyword, tool.Keyword)
2586 << attrS(_SccProjectName, tool.SccProjectName)
2587 << attrS(_SccLocalPath, tool.SccLocalPath)
2588 << tag(_Platforms)
2589 << tag(_Platform)
2590 << attrS(_Name, tool.PlatformName)
2591 << closetag(_Platforms)
2592 << tag(_Configurations);
2593 // Output each configuration
2594 for (int i = 0; i < tool.SingleProjects.count(); ++i)
2595 write(xml, tool.SingleProjects.at(i).Configuration);
2596 xml << closetag(_Configurations)
2597 << tag(q_Files);
2598 outputFilter(tool, xml, "Source Files");
2599 outputFilter(tool, xml, "Header Files");
2600 outputFilter(tool, xml, "Generated Files");
2601 outputFilter(tool, xml, "LexYacc Files");
2602 outputFilter(tool, xml, "Translation Files");
2603 outputFilter(tool, xml, "Form Files");
2604 outputFilter(tool, xml, "Resource Files");
2605 outputFilter(tool, xml, "Deployment Files");
2606 outputFilter(tool, xml, "Distribution Files");
2607 for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
2608 outputFilter(tool, xml, tool.ExtraCompilers.at(x));
2609 }
2610 outputFilter(tool, xml, "Root Files");
2611 xml << closetag(q_Files)
2612 << tag(_Globals)
2613 << data(); // No "/>" end tag
2614}
2615
2616void VCProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
2617{
2618 xml << tag(_Tool)
2619 << attrS(_Name, _VCCLCompilerTool)
2620 << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2621 << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2622 << attrX(_AdditionalUsingDirectories, tool.AdditionalUsingDirectories)
2623 << attrS(_AssemblerListingLocation, tool.AssemblerListingLocation)
2624 << attrE(_AssemblerOutput, tool.AssemblerOutput, /*ifNot*/ asmListingNone)
2625 << attrE(_BasicRuntimeChecks, tool.BasicRuntimeChecks, /*ifNot*/ runtimeBasicCheckNone)
2626 << attrE(_BrowseInformation, tool.BrowseInformation, /*ifNot*/ brInfoNone)
2627 << attrS(_BrowseInformationFile, tool.BrowseInformationFile)
2628 << attrT(_BufferSecurityCheck, tool.BufferSecurityCheck)
2629 << attrE(_CallingConvention, tool.CallingConvention, /*ifNot*/ callConventionDefault)
2630 << attrE(_CompileAs, tool.CompileAs, compileAsDefault)
2631 << attrE(_CompileAsManaged, tool.CompileAsManaged, /*ifNot*/ managedDefault)
2632 << attrT(_CompileOnly, tool.CompileOnly)
2633 << attrE(_DebugInformationFormat, tool.DebugInformationFormat, /*ifNot*/ debugUnknown)
2634 << attrT(_Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems)
2635 << attrT(_DisableLanguageExtensions, tool.DisableLanguageExtensions)
2636 << attrX(_DisableSpecificWarnings, tool.DisableSpecificWarnings)
2637 << attrE(_EnableEnhancedInstructionSet, tool.EnableEnhancedInstructionSet, /*ifnot*/ archNotSet)
2638 << attrT(_EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations)
2639 << attrT(_EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking)
2640 << attrT(_EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions)
2641 << xformExceptionHandlingNET2005(tool.ExceptionHandling, tool.config->CompilerVersion)
2642 << attrT(_ExpandAttributedSource, tool.ExpandAttributedSource)
2643 << attrE(_FavorSizeOrSpeed, tool.FavorSizeOrSpeed, /*ifNot*/ favorNone)
2644
2645 << attrE(_FloatingPointModel, tool.FloatingPointModel, /*ifNot*/ floatingPointNotSet)
2646 << attrT(_FloatingPointExceptions, tool.FloatingPointExceptions)
2647
2648 << attrT(_ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope)
2649 << attrX(_ForcedIncludeFiles, tool.ForcedIncludeFiles)
2650 << attrX(_ForcedUsingFiles, tool.ForcedUsingFiles)
2651 << attrE(_GeneratePreprocessedFile, tool.GeneratePreprocessedFile, /*ifNot*/ preprocessUnknown)
2652 << attrT(_GlobalOptimizations, tool.GlobalOptimizations)
2653 << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2654 << attrT(_ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency)
2655 << attrE(_InlineFunctionExpansion, tool.InlineFunctionExpansion, /*ifNot*/ expandDefault)
2656 << attrT(_KeepComments, tool.KeepComments)
2657 << attrT(_MinimalRebuild, tool.MinimalRebuild)
2658 << attrS(_ObjectFile, tool.ObjectFile)
2659 << attrT(_OmitFramePointers, tool.OmitFramePointers)
2660 << attrT(_OpenMP, tool.OpenMP)
2661 << attrE(_Optimization, tool.Optimization, /*ifNot*/ optimizeDefault)
2662 << attrE(_OptimizeForProcessor, tool.OptimizeForProcessor, /*ifNot*/ procOptimizeBlended)
2663 << attrT(_OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication)
2664 << attrS(_OutputFile, tool.OutputFile)
2665 << attrS(_PrecompiledHeaderFile, tool.PrecompiledHeaderFile)
2666 << attrS(_PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough)
2667 << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2668 << (tool.ProgramDataBaseFileName.isNull() ? noxml() : attr(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName))
2669 << attrE(_RuntimeLibrary, tool.RuntimeLibrary, /*ifNot*/ rtUnknown)
2670 << attrT(_RuntimeTypeInfo, tool.RuntimeTypeInfo)
2671 << attrT(_ShowIncludes, tool.ShowIncludes)
2672 << attrT(_SmallerTypeCheck, tool.SmallerTypeCheck)
2673 << attrT(_StringPooling, tool.StringPooling)
2674 << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ alignNotSet)
2675 << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2676 << attrT(_TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType)
2677 << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
2678 << attrT(_UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions)
2679 << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
2680 << xformUsePrecompiledHeaderForNET2005(tool.UsePrecompiledHeader, tool.config->CompilerVersion)
2681 << attrT(_WarnAsError, tool.WarnAsError)
2682 << attrE(_WarningLevel, tool.WarningLevel, /*ifNot*/ warningLevelUnknown)
2683 << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization)
2684 << attrE(_CompileForArchitecture, tool.CompileForArchitecture, /*ifNot*/ archUnknown)
2685 << attrT(_InterworkCalls, tool.InterworkCalls)
2686
2687 << closetag(_Tool);
2688}
2689
2690void VCProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
2691{
2692 xml << tag(_Tool)
2693 << attrS(_Name, _VCLinkerTool)
2694 << attrX(_AdditionalDependencies, tool.AdditionalDependencies, " ")
2695 << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
2696 << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2697 << attrX(_AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly)
2698 << attrS(_BaseAddress, tool.BaseAddress)
2699 << attrT(_DataExecutionPrevention, tool.DataExecutionPrevention)
2700 << attrX(_DelayLoadDLLs, tool.DelayLoadDLLs)
2701 << attrE(_EnableCOMDATFolding, tool.EnableCOMDATFolding, /*ifNot*/ optFoldingDefault)
2702 << attrS(_EntryPointSymbol, tool.EntryPointSymbol)
2703 << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
2704 << attrS(_FunctionOrder, tool.FunctionOrder)
2705 << attrT(_GenerateDebugInformation, tool.GenerateDebugInformation)
2706 << attrT(_GenerateMapFile, tool.GenerateMapFile)
2707 << attrL(_HeapCommitSize, tool.HeapCommitSize, /*ifNot*/ -1)
2708 << attrL(_HeapReserveSize, tool.HeapReserveSize, /*ifNot*/ -1)
2709 << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
2710 << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
2711 << attrT(_IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL)
2712 << attrT(_IgnoreImportLibrary, tool.IgnoreImportLibrary)
2713 << attrS(_ImportLibrary, tool.ImportLibrary)
2714 << attrE(_LargeAddressAware, tool.LargeAddressAware, /*ifNot*/ addrAwareDefault)
2715 << attrT(_LinkDLL, tool.LinkDLL)
2716 << attrE(_LinkIncremental, tool.LinkIncremental, /*ifNot*/ linkIncrementalDefault)
2717 << attrE(_LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration)
2718 << attrS(_LinkToManagedResourceFile, tool.LinkToManagedResourceFile)
2719 << attrT(_MapExports, tool.MapExports)
2720 << attrS(_MapFileName, tool.MapFileName)
2721 << attrT(_MapLines, tool.MapLines)
2722 << attrS(_MergedIDLBaseFileName, tool.MergedIDLBaseFileName)
2723 << attrS(_MergeSections, tool.MergeSections)
2724 << attrS(_MidlCommandFile, tool.MidlCommandFile)
2725 << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
2726 << attrE(_OptimizeForWindows98, tool.OptimizeForWindows98, /*ifNot*/ optWin98Default)
2727 << attrE(_OptimizeReferences, tool.OptimizeReferences, /*ifNot*/ optReferencesDefault)
2728 << attrS(_OutputFile, tool.OutputFile)
2729 << attr(_ProgramDatabaseFile, tool.ProgramDatabaseFile)
2730 << attrT(_RandomizedBaseAddress, tool.RandomizedBaseAddress)
2731 << attrT(_RegisterOutput, tool.RegisterOutput)
2732 << attrT(_ResourceOnlyDLL, tool.ResourceOnlyDLL)
2733 << attrT(_SetChecksum, tool.SetChecksum)
2734 << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
2735 << attrL(_StackCommitSize, tool.StackCommitSize, /*ifNot*/ -1)
2736 << attrL(_StackReserveSize, tool.StackReserveSize, /*ifNot*/ -1)
2737 << attrS(_StripPrivateSymbols, tool.StripPrivateSymbols)
2738 << attrE(_SubSystem, tool.SubSystem)
2739 << attrT(_SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL)
2740 << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2741 << attrT(_SwapRunFromCD, tool.SwapRunFromCD)
2742 << attrT(_SwapRunFromNet, tool.SwapRunFromNet)
2743 << attrE(_TargetMachine, tool.TargetMachine, /*ifNot*/ machineNotSet)
2744 << attrE(_TerminalServerAware, tool.TerminalServerAware, /*ifNot*/ termSvrAwareDefault)
2745 << attrT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration)
2746 << attrS(_TypeLibraryFile, tool.TypeLibraryFile)
2747 << attrL(_TypeLibraryResourceID, tool.TypeLibraryResourceID, /*ifNot*/ rcUseDefault)
2748 << attrS(_Version, tool.Version)
2749 << attrT(_GenerateManifest, tool.GenerateManifest)
2750 << closetag(_Tool);
2751}
2752
2753void VCProjectWriter::write(XmlOutput &xml, const VCManifestTool &tool)
2754{
2755 xml << tag(_Tool)
2756 << attrS(_Name, _VCManifestTool)
2757 << attrT(_EmbedManifest, tool.EmbedManifest)
2758 << closetag(_Tool);
2759}
2760
2761void VCProjectWriter::write(XmlOutput &xml, const VCMIDLTool &tool)
2762{
2763 xml << tag(_Tool)
2764 << attrS(_Name, _VCMIDLTool)
2765 << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2766 << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2767 << attrX(_CPreprocessOptions, tool.CPreprocessOptions)
2768 << attrE(_DefaultCharType, tool.DefaultCharType)
2769 << attrS(_DLLDataFileName, tool.DLLDataFileName)
2770 << attrE(_EnableErrorChecks, tool.EnableErrorChecks)
2771 << attrT(_ErrorCheckAllocations, tool.ErrorCheckAllocations)
2772 << attrT(_ErrorCheckBounds, tool.ErrorCheckBounds)
2773 << attrT(_ErrorCheckEnumRange, tool.ErrorCheckEnumRange)
2774 << attrT(_ErrorCheckRefPointers, tool.ErrorCheckRefPointers)
2775 << attrT(_ErrorCheckStubData, tool.ErrorCheckStubData)
2776 << attrX(_FullIncludePath, tool.FullIncludePath)
2777 << attrT(_GenerateStublessProxies, tool.GenerateStublessProxies)
2778 << attrT(_GenerateTypeLibrary, tool.GenerateTypeLibrary)
2779 << attrS(_HeaderFileName, tool.HeaderFileName)
2780 << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2781 << attrS(_InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName)
2782 << attrT(_MkTypLibCompatible, tool.MkTypLibCompatible)
2783 << attrS(_OutputDirectory, tool.OutputDirectory)
2784 << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2785 << attrS(_ProxyFileName, tool.ProxyFileName)
2786 << attrS(_RedirectOutputAndErrors, tool.RedirectOutputAndErrors)
2787 << attrE(_StructMemberAlignment, tool.StructMemberAlignment, /*ifNot*/ midlAlignNotSet)
2788 << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2789 << attrE(_TargetEnvironment, tool.TargetEnvironment, /*ifNot*/ midlTargetNotSet)
2790 << attrS(_TypeLibraryName, tool.TypeLibraryName)
2791 << attrX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions)
2792 << attrT(_ValidateParameters, tool.ValidateParameters)
2793 << attrT(_WarnAsError, tool.WarnAsError)
2794 << attrE(_WarningLevel, tool.WarningLevel)
2795 << closetag(_Tool);
2796}
2797
2798void VCProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
2799{
2800 xml << tag(_Tool)
2801 << attrS(_Name, tool.ToolName)
2802 << attrX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
2803 << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
2804 << attrS(_Description, tool.Description)
2805 << attrX(_Outputs, tool.Outputs, ";")
2806 << attrS(_Path, tool.ToolPath)
2807 << closetag(_Tool);
2808}
2809
2810void VCProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
2811{
2812 xml
2813 << tag(_Tool)
2814 << attrS(_Name, _VCLibrarianTool)
2815 << attrX(_AdditionalDependencies, tool.AdditionalDependencies)
2816 << attrX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories)
2817 << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2818 << attrX(_ExportNamedFunctions, tool.ExportNamedFunctions)
2819 << attrX(_ForceSymbolReferences, tool.ForceSymbolReferences)
2820 << attrT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
2821 << attrX(_IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames)
2822 << attrS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
2823 << attrS(_OutputFile, tool.OutputFile)
2824 << attrT(_SuppressStartupBanner, tool.SuppressStartupBanner)
2825 << closetag(_Tool);
2826}
2827
2828void VCProjectWriter::write(XmlOutput &xml, const VCResourceCompilerTool &tool)
2829{
2830 xml
2831 << tag(_Tool)
2832 << attrS(_Name, _VCResourceCompilerTool)
2833 << attrS(_Path, tool.ToolPath)
2834 << attrX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories)
2835 << attrX(_AdditionalOptions, tool.AdditionalOptions, " ")
2836 << attrE(_Culture, tool.Culture, /*ifNot*/ rcUseDefault)
2837 << attrX(_FullIncludePath, tool.FullIncludePath)
2838 << attrT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
2839 << attrX(_PreprocessorDefinitions, tool.PreprocessorDefinitions)
2840 << attrS(_ResourceOutputFileName, tool.ResourceOutputFileName)
2841 << attrE(_ShowProgress, tool.ShowProgress, /*ifNot*/ linkProgressNotSet)
2842 << closetag(_Tool);
2843}
2844
2845void VCProjectWriter::write(XmlOutput &xml, const VCEventTool &tool)
2846{
2847 xml
2848 << tag(_Tool)
2849 << attrS(_Name, tool.ToolName)
2850 << attrS(_Path, tool.ToolPath)
2851 << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
2852 << attrS(_Description, tool.Description)
2853 << attrT(_ExcludedFromBuild, tool.ExcludedFromBuild)
2854 << closetag(_Tool);
2855}
2856
2857void VCProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
2858{
2859 if (tool.AdditionalFiles.isEmpty())
2860 return;
2861 xml << tag(tool.DeploymentTag)
2862 << attrS(_RemoteDirectory, tool.RemoteDirectory)
2863 << attrE(_RegisterOutput, tool.RegisterOutput)
2864 << attrS(_AdditionalFiles, tool.AdditionalFiles)
2865 << closetag(tool.DeploymentTag);
2866}
2867
2868void VCProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
2869{
2870 Q_UNUSED(xml);
2871 Q_UNUSED(tool);
2872}
2873
2874void VCProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
2875{
2876 xml << tag(_Configuration)
2877 << attrS(_Name, tool.Name)
2878 << attrS(_OutputDirectory, tool.OutputDirectory)
2879 << attrT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
2880 << attrT(_BuildBrowserInformation, tool.BuildBrowserInformation)
2881 << attrE(_CharacterSet, tool.CharacterSet, /*ifNot*/ charSetNotSet)
2882 << attrE(_ConfigurationType, tool.ConfigurationType)
2883 << attrS(_DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean)
2884 << attrS(_ImportLibrary, tool.ImportLibrary)
2885 << attrS(_IntermediateDirectory, tool.IntermediateDirectory)
2886 << attrS(_PrimaryOutput, tool.PrimaryOutput)
2887 << attrS(_ProgramDatabase, tool.ProgramDatabase)
2888 << attrT(_RegisterOutput, tool.RegisterOutput)
2889 << attrE(_UseOfATL, tool.UseOfATL, /*ifNot*/ useATLNotSet)
2890 << attrE(_UseOfMfc, tool.UseOfMfc)
2891 << attrT(_WholeProgramOptimization, tool.WholeProgramOptimization);
2892 write(xml, tool.compiler);
2893 if (tool.ConfigurationType == typeStaticLibrary)
2894 write(xml, tool.librarian);
2895 else
2896 write(xml, tool.linker);
2897 write(xml, tool.manifestTool);
2898 write(xml, tool.idl);
2899 write(xml, tool.postBuild);
2900 write(xml, tool.preBuild);
2901 write(xml, tool.preLink);
2902 write(xml, tool.resource);
2903 write(xml, tool.deployment);
2904 xml << closetag(_Configuration);
2905}
2906
2907void VCProjectWriter::write(XmlOutput &xml, VCFilter &tool)
2908{
2909 if(!tool.Files.count())
2910 return;
2911
2912 if (!tool.Name.isEmpty()) {
2913 xml << tag(_Filter)
2914 << attrS(_Name, tool.Name)
2915 << attrS(_Filter, tool.Filter)
2916 << attrS(_UniqueIdentifier, tool.Guid)
2917 << attrT(_ParseFiles, tool.ParseFiles);
2918 }
2919 for (int i = 0; i < tool.Files.count(); ++i) {
2920 const VCFilterFile &info = tool.Files.at(i);
2921 xml << tag(q_File)
2922 << attrS(_RelativePath, Option::fixPathToTargetOS(info.file))
2923 << data(); // In case no custom builds, to avoid "/>" endings
2924 outputFileConfig(tool, xml, tool.Files.at(i).file);
2925 xml << closetag(q_File);
2926 }
2927 if (!tool.Name.isEmpty())
2928 xml << closetag(_Filter);
2929}
2930
2931// outputs a given filter for all existing configurations of a project
2932void VCProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, const QString &filtername)
2933{
2934 QScopedPointer<Node> root;
2935 if (project.SingleProjects.at(0).flat_files)
2936 root.reset(new FlatNode);
2937 else
2938 root.reset(new TreeNode);
2939
2940 QString name, extfilter, guid;
2941 triState parse = unset;
2942
2943 for (int i = 0; i < project.SingleProjects.count(); ++i) {
2944 const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername);
2945
2946 // Merge all files in this filter to root tree
2947 for (int x = 0; x < filter.Files.count(); ++x)
2948 root->addElement(filter.Files.at(x));
2949
2950 // Save filter setting from first filter. Next filters
2951 // may differ but we cannot handle that. (ex. extfilter)
2952 if (name.isEmpty()) {
2953 name = filter.Name;
2954 extfilter = filter.Filter;
2955 parse = filter.ParseFiles;
2956 guid = filter.Guid;
2957 }
2958 }
2959
2960 if (!root->hasElements())
2961 return;
2962
2963 // Actual XML output ----------------------------------
2964 if (!name.isEmpty()) {
2965 xml << tag(_Filter)
2966 << attrS(_Name, name)
2967 << attrS(_Filter, extfilter)
2968 << attrS(_UniqueIdentifier, guid)
2969 << attrT(_ParseFiles, parse);
2970 }
2971 root->generateXML(xml, "", project, filtername); // output root tree
2972 if (!name.isEmpty())
2973 xml << closetag(_Filter);
2974}
2975
2976// Output all configurations (by filtername) for a file (by info)
2977// A filters config output is in VCFilter.outputFileConfig()
2978void VCProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, const VCFilterFile &info, const QString &filtername)
2979{
2980 xml << tag(q_File)
2981 << attrS(_RelativePath, Option::fixPathToTargetOS(info.file));
2982 for (int i = 0; i < project.SingleProjects.count(); ++i) {
2983 VCFilter filter = project.SingleProjects.at(i).filterByName(filtername);
2984 if (filter.Config) // only if the filter is not empty
2985 outputFileConfig(filter, xml, info.file);
2986 }
2987 xml << closetag(q_File);
2988}
2989
2990void VCProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, const QString &filename)
2991{
2992 // Clearing each filter tool
2993 filter.useCustomBuildTool = false;
2994 filter.useCompilerTool = false;
2995 filter.CustomBuildTool = VCCustomBuildTool();
2996 filter.CompilerTool = VCCLCompilerTool();
2997
2998 // Unset some default options
2999 filter.CustomBuildTool.config = filter.Config;
3000 filter.CompilerTool.BufferSecurityCheck = unset;
3001 filter.CompilerTool.DebugInformationFormat = debugUnknown;
3002 filter.CompilerTool.ExceptionHandling = ehDefault;
3003 filter.CompilerTool.GeneratePreprocessedFile = preprocessUnknown;
3004 filter.CompilerTool.Optimization = optimizeDefault;
3005 filter.CompilerTool.ProgramDataBaseFileName.clear();
3006 filter.CompilerTool.RuntimeLibrary = rtUnknown;
3007 filter.CompilerTool.WarningLevel = warningLevelUnknown;
3008 filter.CompilerTool.config = filter.Config;
3009
3010 bool inBuild;
3011 VCFilterFile info = filter.findFile(filename, &inBuild);
3012 inBuild &= !info.excludeFromBuild;
3013
3014 if (inBuild) {
3015 filter.addExtraCompiler(info);
3016 if(filter.Project->usePCH)
3017 filter.modifyPCHstage(info.file);
3018 } else {
3019 // Excluded files uses an empty compiler stage
3020 if(info.excludeFromBuild)
3021 filter.useCompilerTool = true;
3022 }
3023
3024 // Actual XML output ----------------------------------
3025 if (filter.useCustomBuildTool || filter.useCompilerTool || !inBuild) {
3026 xml << tag(_FileConfiguration)
3027 << attr(_Name, filter.Config->Name)
3028 << (!inBuild ? attrS(_ExcludedFromBuild, "true") : noxml());
3029 if (filter.useCustomBuildTool)
3030 filter.Project->projectWriter->write(xml, filter.CustomBuildTool);
3031 if (filter.useCompilerTool)
3032 filter.Project->projectWriter->write(xml, filter.CompilerTool);
3033 xml << closetag(_FileConfiguration);
3034 }
3035}
3036
3037QT_END_NAMESPACE
3038