source: trunk/qmake/generators/win32/msvc_objectmodel.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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