diff options
author | Martin Petersson <martin.petersson@nokia.com> | 2010-03-03 17:18:09 (GMT) |
---|---|---|
committer | Marius Storm-Olsen <marius.storm-olsen@nokia.com> | 2010-04-21 10:31:11 (GMT) |
commit | cd601ef53385962c4affdb2020cfcb415d117bc1 (patch) | |
tree | f49d98fea77c3a9dd4319f005f220ec53a5cf90b /qmake | |
parent | 69c4893008ccd4f89bf190c6ca930363b9d65efc (diff) | |
download | Qt-cd601ef53385962c4affdb2020cfcb415d117bc1.zip Qt-cd601ef53385962c4affdb2020cfcb415d117bc1.tar.gz Qt-cd601ef53385962c4affdb2020cfcb415d117bc1.tar.bz2 |
Add support for MSBuild, which is the project format for MSVC 2010
Reviewed-by: Marius SO
Diffstat (limited to 'qmake')
-rw-r--r-- | qmake/Makefile.win32 | 14 | ||||
-rw-r--r-- | qmake/generators/metamakefile.cpp | 7 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.cpp | 3317 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.h | 708 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.cpp | 1 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.h | 5 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 15 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.h | 5 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcxproj.cpp | 851 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcxproj.h | 100 | ||||
-rw-r--r-- | qmake/generators/xmloutput.cpp | 42 | ||||
-rw-r--r-- | qmake/generators/xmloutput.h | 34 | ||||
-rw-r--r-- | qmake/qmake.pro | 3 |
13 files changed, 5090 insertions, 12 deletions
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 63156b3..956fa9c 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -1,4 +1,4 @@ -!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-icc" +!IF "$(QMAKESPEC)" == "win32-msvc" || "$(QMAKESPEC)" == "win32-msvc.net" || "$(QMAKESPEC)" == "win32-msvc2002" || "$(QMAKESPEC)" == "win32-msvc2003" || "$(QMAKESPEC)" == "win32-msvc2005" || "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-icc" !if "$(SOURCE_PATH)" == "" SOURCE_PATH = .. @@ -75,8 +75,8 @@ ADDCLEAN = qmake.tds OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw_make.obj \ option.obj winmakefile.obj projectgenerator.obj property.obj meta.obj \ makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ - borland_bmake.obj msvc_nmake.obj msvc_vcproj.obj \ - msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ + borland_bmake.obj msvc_nmake.obj msvc_vcproj.obj msvc_vcxproj.obj \ + msvc_objectmodel.obj msbuild_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ symmake_abld.obj symmake_sbsv2.obj symbiancommon.obj registry.obj epocroot.obj !IFDEF QMAKE_OPENSOURCE_EDITION @@ -194,7 +194,9 @@ clean:: -del borland_bmake.obj -del msvc_nmake.obj -del msvc_vcproj.obj + -del msvc_vcxproj.obj -del msvc_objectmodel.obj + -del msbuild_objectmodel.obj -del symmake.obj -del symmake_abld.obj -del symmake_sbsv2.obj @@ -383,9 +385,15 @@ msvc_nmake.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp msvc_vcproj.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp +msvc_vcxproj.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcxproj.cpp + $(CXX) $(CXXFLAGS) generators/win32/msvc_vcxproj.cpp + msvc_objectmodel.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_objectmodel.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp +msbuild_objectmodel.obj: $(SOURCE_PATH)/qmake/generators/win32/msbuild_objectmodel.cpp + $(CXX) $(CXXFLAGS) generators/win32/msbuild_objectmodel.cpp + symmake.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake.cpp diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index c42a837..f42a489 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -443,6 +443,7 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "msvc_nmake.h" #include "borland_bmake.h" #include "msvc_vcproj.h" +#include "msvc_vcxproj.h" #include "symmake_abld.h" #include "symmake_sbsv2.h" #include "symbian_makefile.h" @@ -473,6 +474,12 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new VcprojGenerator; else mkfile = new NmakeMakefileGenerator; + } else if(gen == "MSBUILD") { + // Visual Studio >= v11.0 + if(proj->first("TEMPLATE").indexOf(QRegExp("^vc.*")) != -1 || proj->first("TEMPLATE").indexOf(QRegExp("^ce.*")) != -1) + mkfile = new VcxprojGenerator; + else + mkfile = new NmakeMakefileGenerator; } else if(gen == "BMAKE") { mkfile = new BorlandMakefileGenerator; } else if(gen == "SYMBIAN_ABLD") { diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp new file mode 100644 index 0000000..f459885 --- /dev/null +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -0,0 +1,3317 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "msvc_objectmodel.h" +#include "msbuild_objectmodel.h" +#include "msvc_vcproj.h" +#include "msvc_vcxproj.h" +#include <qstringlist.h> +#include <qfileinfo.h> + +QT_BEGIN_NAMESPACE + +// XML Tags --------------------------------------------------------- +const char _CLCompile[] = "ClCompile"; +const char _Configuration[] = "Configuration"; +const char _Configurations[] = "Configurations"; +const char q_File[] = "File"; +const char _FileConfiguration[] = "FileConfiguration"; +const char q_Files[] = "Files"; +const char _Filter[] = "Filter"; +const char _Globals[] = "Globals"; +const char _ItemGroup[] = "ItemGroup"; +const char _Link[] = "Link"; +const char _Midl[] = "Midl"; +const char _Platform[] = "Platform"; +const char _Platforms[] = "Platforms"; +const char _ResourceCompile[] = "ResourceCompile"; +const char _Tool[] = "Tool"; +const char _VisualStudioProject[] = "VisualStudioProject"; + +// XML Properties --------------------------------------------------- +const char _AddModuleNamesToAssembly[] = "AddModuleNamesToAssembly"; +const char _AdditionalDependencies[] = "AdditionalDependencies"; +const char _AdditionalFiles[] = "AdditionalFiles"; +const char _AdditionalIncludeDirectories[] = "AdditionalIncludeDirectories"; +const char _AdditionalLibraryDirectories[] = "AdditionalLibraryDirectories"; +const char _AdditionalManifestDependencies[] = "AdditionalManifestDependencies"; +const char _AdditionalOptions[] = "AdditionalOptions"; +const char _AdditionalUsingDirectories[] = "AdditionalUsingDirectories"; +const char _AllowIsolation[] = "AllowIsolation"; +const char _AlwaysAppend[] = "AlwaysAppend"; +const char _ApplicationConfigurationMode[] = "ApplicationConfigurationMode"; +const char _AssemblerListingLocation[] = "AssemblerListingLocation"; +const char _AssemblerOutput[] = "AssemblerOutput"; +const char _AssemblyDebug[] = "AssemblyDebug"; +const char _AssemblyLinkResource[] = "AssemblyLinkResource"; +const char _ATLMinimizesCRunTimeLibraryUsage[] = "ATLMinimizesCRunTimeLibraryUsage"; +const char _BaseAddress[] = "BaseAddress"; +const char _BasicRuntimeChecks[] = "BasicRuntimeChecks"; +const char _BrowseInformation[] = "BrowseInformation"; +const char _BrowseInformationFile[] = "BrowseInformationFile"; +const char _BufferSecurityCheck[] = "BufferSecurityCheck"; +const char _BuildBrowserInformation[] = "BuildBrowserInformation"; +const char _CallingConvention[] = "CallingConvention"; +const char _CharacterSet[] = "CharacterSet"; +const char _ClientStubFile[] = "ClientStubFile"; +const char _CLRImageType[] = "CLRImageType"; +const char _CLRSupportLastError[] = "CLRSupportLastError"; +const char _CLRThreadAttribute[] = "CLRThreadAttribute"; +const char _CLRUnmanagedCodeCheck[] = "CLRUnmanagedCodeCheck"; +const char _Command[] = "Command"; +const char _CommandLine[] = "CommandLine"; +const char _CompileAs[] = "CompileAs"; +const char _CompileAsManaged[] = "CompileAsManaged"; +const char _CompileForArchitecture[] = "CompileForArchitecture"; +const char _CompileOnly[] = "CompileOnly"; +const char _ConfigurationType[] = "ConfigurationType"; +const char _CPreprocessOptions[] = "CPreprocessOptions"; +const char _CreateHotpatchableImage[] = "CreateHotpatchableImage"; +const char _CreateHotPatchableImage[] = "CreateHotPatchableImage"; +const char _Culture[] = "Culture"; +const char _DataExecutionPrevention[] = "DataExecutionPrevention"; +const char _DebugInformationFormat[] = "DebugInformationFormat"; +const char _DefaultCharIsUnsigned[] = "DefaultCharIsUnsigned"; +const char _DefaultCharType[] = "DefaultCharType"; +const char _DelayLoadDLLs[] = "DelayLoadDLLs"; +const char _DelaySign[] = "DelaySign"; +const char _DeleteExtensionsOnClean[] = "DeleteExtensionsOnClean"; +const char _Description[] = "Description"; +const char _Detect64BitPortabilityProblems[] = "Detect64BitPortabilityProblems"; +const char _DisableLanguageExtensions[] = "DisableLanguageExtensions"; +const char _DisableSpecificWarnings[] = "DisableSpecificWarnings"; +const char _DisplayLibrary[] = "DisplayLibrary"; +const char _DLLDataFileName[] = "DLLDataFileName"; +const char _Driver[] = "Driver"; +const char _EmbedManagedResourceFile[] = "EmbedManagedResourceFile"; +const char _EnableCOMDATFolding[] = "EnableCOMDATFolding"; +const char _EnableUAC[] = "EnableUAC"; +const char _EnableErrorChecks[] = "EnableErrorChecks"; +const char _EnableEnhancedInstructionSet[] = "EnableEnhancedInstructionSet"; +const char _EnableFiberSafeOptimizations[] = "EnableFiberSafeOptimizations"; +const char _EnableFunctionLevelLinking[] = "EnableFunctionLevelLinking"; +const char _EnableIntrinsicFunctions[] = "EnableIntrinsicFunctions"; +const char _EnablePREfast[] = "EnablePREfast"; +const char _EntryPointSymbol[] = "EntryPointSymbol"; +const char _ErrorCheckAllocations[] = "ErrorCheckAllocations"; +const char _ErrorCheckBounds[] = "ErrorCheckBounds"; +const char _ErrorCheckEnumRange[] = "ErrorCheckEnumRange"; +const char _ErrorCheckRefPointers[] = "ErrorCheckRefPointers"; +const char _ErrorCheckStubData[] = "ErrorCheckStubData"; +const char _ErrorReporting[] = "ErrorReporting"; +const char _ExceptionHandling[] = "ExceptionHandling"; +const char _ExcludedFromBuild[] = "ExcludedFromBuild"; +const char _ExpandAttributedSource[] = "ExpandAttributedSource"; +const char _ExportNamedFunctions[] = "ExportNamedFunctions"; +const char _FavorSizeOrSpeed[] = "FavorSizeOrSpeed"; +const char _FixedBaseAddress[] = "FixedBaseAddress"; +const char _FloatingPointModel[] = "FloatingPointModel"; +const char _FloatingPointExceptions[] = "FloatingPointExceptions"; +const char _ForceConformanceInForLoopScope[] = "ForceConformanceInForLoopScope"; +const char _ForceFileOutput[] = "ForceFileOutput"; +const char _ForceSymbolReferences[] = "ForceSymbolReferences"; +const char _ForcedIncludeFiles[] = "ForcedIncludeFiles"; +const char _ForcedUsingFiles[] = "ForcedUsingFiles"; +const char _FullIncludePath[] = "FullIncludePath"; +const char _FunctionLevelLinking[] = "FunctionLevelLinking"; +const char _FunctionOrder[] = "FunctionOrder"; +const char _GenerateClientFiles[] = "GenerateClientFiles"; +const char _GenerateDebugInformation[] = "GenerateDebugInformation"; +const char _GenerateManifest[] = "GenerateManifest"; +const char _GenerateMapFile[] = "GenerateMapFile"; +const char _GeneratePreprocessedFile[] = "GeneratePreprocessedFile"; +const char _GenerateServerFiles[] = "GenerateServerFiles"; +const char _GenerateStublessProxies[] = "GenerateStublessProxies"; +const char _GenerateTypeLibrary[] = "GenerateTypeLibrary"; +const char _GenerateXMLDocumentationFiles[] = "GenerateXMLDocumentationFiles"; +const char _GlobalOptimizations[] = "GlobalOptimizations"; +const char _HeaderFileName[] = "HeaderFileName"; +const char _HeapCommitSize[] = "HeapCommitSize"; +const char _HeapReserveSize[] = "HeapReserveSize"; +const char _IgnoreAllDefaultLibraries[] = "IgnoreAllDefaultLibraries"; +const char _IgnoreDefaultLibraryNames[] = "IgnoreDefaultLibraryNames"; +const char _IgnoreEmbeddedIDL[] = "IgnoreEmbeddedIDL"; +const char _IgnoreImportLibrary[] = "IgnoreImportLibrary"; +const char _IgnoreSpecificDefaultLibraries[] = "IgnoreSpecificDefaultLibraries"; +const char _IgnoreStandardIncludePath[] = "IgnoreStandardIncludePath"; +const char _ImageHasSafeExceptionHandlers[] = "ImageHasSafeExceptionHandlers"; +const char _ImportLibrary[] = "ImportLibrary"; +const char _ImproveFloatingPointConsistency[] = "ImproveFloatingPointConsistency"; +const char _InlineFunctionExpansion[] = "InlineFunctionExpansion"; +const char _IntrinsicFunctions[] = "IntrinsicFunctions"; +const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName"; +const char _IntermediateDirectory[] = "IntermediateDirectory"; +const char _InterworkCalls[] = "InterworkCalls"; +const char _KeyContainer[] = "KeyContainer"; +const char _KeyFile[] = "KeyFile"; +const char _Keyword[] = "Keyword"; +const char _KeepComments[] = "KeepComments"; +const char _LargeAddressAware[] = "LargeAddressAware"; +const char _LinkDLL[] = "LinkDLL"; +const char _LinkErrorReporting[] = "LinkErrorReporting"; +const char _LinkIncremental[] = "LinkIncremental"; +const char _LinkStatus[] = "LinkStatus"; +const char _LinkTimeCodeGeneration[] = "LinkTimeCodeGeneration"; +const char _LinkToManagedResourceFile[] = "LinkToManagedResourceFile"; +const char _LocaleID[] = "LocaleID"; +const char _ManifestFile[] = "ManifestFile"; +const char _MapExports[] = "MapExports"; +const char _MapFileName[] = "MapFileName"; +const char _MapLines[] = "MapLines "; +const char _MergedIDLBaseFileName[] = "MergedIDLBaseFileName"; +const char _MergeSections[] = "MergeSections"; +const char _Message[] = "Message"; +const char _MidlCommandFile[] = "MidlCommandFile"; +const char _MinimalRebuild[] = "MinimalRebuild"; +const char _MkTypLibCompatible[] = "MkTypLibCompatible"; +const char _ModuleDefinitionFile[] = "ModuleDefinitionFile"; +const char _MSDOSStubFileName[] = "MSDOSStubFileName"; +const char _MultiProcessorCompilation[] = "MultiProcessorCompilation"; +const char _Name[] = "Name"; +const char _NoEntryPoint[] = "NoEntryPoint"; +const char _NullTerminateStrings[] = "NullTerminateStrings"; +const char _ObjectFile[] = "ObjectFile"; +const char _ObjectFiles[] = "ObjectFiles"; +const char _ObjectFileName[] = "ObjectFileName"; +const char _OmitDefaultLibName[] = "OmitDefaultLibName"; +const char _OmitFramePointers[] = "OmitFramePointers"; +const char _OpenMP[] = "OpenMP"; +const char _OpenMPSupport[] = "OpenMPSupport"; +const char _Optimization[] = "Optimization"; +const char _OptimizeForProcessor[] = "OptimizeForProcessor"; +const char _OptimizeForWindows98[] = "OptimizeForWindows98"; +const char _OptimizeForWindowsApplication[] = "OptimizeForWindowsApplication"; +const char _OptimizeReferences[] = "OptimizeReferences"; +const char _OutputDirectory[] = "OutputDirectory"; +const char _OutputFile[] = "OutputFile"; +const char _Outputs[] = "Outputs"; +const char _ParseFiles[] = "ParseFiles"; +const char _Path[] = "Path"; +const char _PrecompiledHeader[] = "PrecompiledHeader"; +const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile"; +const char _PrecompiledHeaderOutputFile[] = "PrecompiledHeaderOutputFile"; +const char _PrecompiledHeaderThrough[] = "PrecompiledHeaderThrough"; +const char _PreprocessorDefinitions[] = "PreprocessorDefinitions"; +const char _PreprocessKeepComments[] = "PreprocessKeepComments"; +const char _PreprocessOutputPath[] = "PreprocessOutputPath"; +const char _PreprocessSuppressLineNumbers[] = "PreprocessSuppressLineNumbers"; +const char _PreprocessToFile[] = "PreprocessToFile"; +const char _PreventDllBinding[] = "PreventDllBinding"; +const char _PrimaryOutput[] = "PrimaryOutput"; +const char _Profile[] = "Profile"; +const char _ProfileGuidedDatabase[] = "ProfileGuidedDatabase"; +const char _ProjectGUID[] = "ProjectGUID"; +const char _ProcessorNumber[] = "ProcessorNumber"; +const char _ProjectType[] = "ProjectType"; +const char _ProgramDatabase[] = "ProgramDatabase"; +const char _ProgramDataBaseFileName[] = "ProgramDataBaseFileName"; +const char _ProgramDatabaseFile[] = "ProgramDatabaseFile"; +const char _ProxyFileName[] = "ProxyFileName"; +const char _RandomizedBaseAddress[] = "RandomizedBaseAddress"; +const char _RedirectOutputAndErrors[] = "RedirectOutputAndErrors"; +const char _RegisterOutput[] = "RegisterOutput"; +const char _RelativePath[] = "RelativePath"; +const char _RemoteDirectory[] = "RemoteDirectory"; +const char _RemoveObjects[] = "RemoveObjects"; +const char _ResourceOnlyDLL[] = "ResourceOnlyDLL"; +const char _ResourceOutputFileName[] = "ResourceOutputFileName"; +const char _RuntimeLibrary[] = "RuntimeLibrary"; +const char _RuntimeTypeInfo[] = "RuntimeTypeInfo"; +const char _SccProjectName[] = "SccProjectName"; +const char _SccLocalPath[] = "SccLocalPath"; +const char _SectionAlignment[] = "SectionAlignment"; +const char _ServerStubFile[] = "ServerStubFile"; +const char _SetChecksum[] = "SetChecksum"; +const char _ShowIncludes[] = "ShowIncludes"; +const char _ShowProgress[] = "ShowProgress"; +const char _SmallerTypeCheck[] = "SmallerTypeCheck"; +const char _SpecifySectionAttributes[] = "SpecifySectionAttributes"; +const char _StackCommitSize[] = "StackCommitSize"; +const char _StackReserveSize[] = "StackReserveSize"; +const char _StringPooling[] = "StringPooling"; +const char _StripPrivateSymbols[] = "StripPrivateSymbols"; +const char _StructMemberAlignment[] = "StructMemberAlignment"; +const char _SubSystem[] = "SubSystem"; +const char _SupportNobindOfDelayLoadedDLL[] = "SupportNobindOfDelayLoadedDLL"; +const char _SupportUnloadOfDelayLoadedDLL[] = "SupportUnloadOfDelayLoadedDLL"; +const char _SuppressCompilerWarnings[] = "SuppressCompilerWarnings"; +const char _SuppressStartupBanner[] = "SuppressStartupBanner"; +const char _SwapRunFromCD[] = "SwapRunFromCD"; +const char _SwapRunFromNet[] = "SwapRunFromNet"; +const char _TargetEnvironment[] = "TargetEnvironment"; +const char _TargetMachine[] = "TargetMachine"; +const char _TerminalServerAware[] = "TerminalServerAware"; +const char _TrackerLogDirectory[] = "TrackerLogDirectory"; +const char _TreatLibWarningAsErrors[] = "TreatLibWarningAsErrors"; +const char _TreatLinkerWarningAsErrors[] = "TreatLinkerWarningAsErrors"; +const char _TreatSpecificWarningsAsErrors[] = "TreatSpecificWarningsAsErrors"; +const char _TreatWarningAsError[] = "TreatWarningAsError"; +const char _TreatWChar_tAsBuiltInType[] = "TreatWChar_tAsBuiltInType"; +const char _TurnOffAssemblyGeneration[] = "TurnOffAssemblyGeneration"; +const char _TypeLibFormat[] = "TypeLibFormat"; +const char _TypeLibraryFile[] = "TypeLibraryFile"; +const char _TypeLibraryName[] = "TypeLibraryName"; +const char _TypeLibraryResourceID[] = "TypeLibraryResourceID"; +const char _UACExecutionLevel[] = "UACExecutionLevel"; +const char _UACUIAccess[] = "UACUIAccess"; +const char _UndefineAllPreprocessorDefinitions[]= "UndefineAllPreprocessorDefinitions"; +const char _UndefinePreprocessorDefinitions[] = "UndefinePreprocessorDefinitions"; +const char _UniqueIdentifier[] = "UniqueIdentifier"; +const char _UseFullPaths[] = "UseFullPaths"; +const char _UseOfATL[] = "UseOfATL"; +const char _UseOfMfc[] = "UseOfMfc"; +const char _UsePrecompiledHeader[] = "UsePrecompiledHeader"; +const char _UseUnicodeForAssemblerListing[] = "UseUnicodeForAssemblerListing"; +const char _ValidateAllParameters[] = "ValidateAllParameters"; +const char _VCCLCompilerTool[] = "VCCLCompilerTool"; +const char _VCLibrarianTool[] = "VCLibrarianTool"; +const char _VCLinkerTool[] = "VCLinkerTool"; +const char _VCCustomBuildTool[] = "VCCustomBuildTool"; +const char _VCResourceCompilerTool[] = "VCResourceCompilerTool"; +const char _VCMIDLTool[] = "VCMIDLTool"; +const char _Verbose[] = "Verbose"; +const char _Version[] = "Version"; +const char _WarnAsError[] = "WarnAsError"; +const char _WarningLevel[] = "WarningLevel"; +const char _WholeProgramOptimization[] = "WholeProgramOptimization"; +const char _XMLDocumentationFileName[] = "XMLDocumentationFileName"; + + +// XmlOutput stream functions ------------------------------ +inline XmlOutput::xml_output attrTagT(const char *name, const triState v) +{ + if(v == unset) + return noxml(); + return tagValue(name, (v == _True ? "true" : "false")); +} + +inline XmlOutput::xml_output attrTagL(const char *name, qint64 v) +{ + return tagValue(name, QString::number(v)); +} + +/*ifNot version*/ +inline XmlOutput::xml_output attrTagL(const char *name, qint64 v, qint64 ifn) +{ + if (v == ifn) + return noxml(); + return tagValue(name, QString::number(v)); +} + +inline XmlOutput::xml_output attrTagS(const char *name, const QString &v) +{ + if(v.isEmpty()) + return noxml(); + return tagValue(name, v); +} + + +inline XmlOutput::xml_output attrTagX(const char *name, const QStringList &v, const char *s = ",") +{ + if(v.isEmpty()) + return noxml(); + QStringList temp = v; + temp.append(QString("%(%1)").arg(name)); + return tagValue(name, temp.join(s)); +} + +inline XmlOutput::xml_output valueTagX(const QStringList &v, const char *s = " ") +{ + if(v.isEmpty()) + return noxml(); + return valueTag(v.join(s)); +} + +inline XmlOutput::xml_output valueTagDefX(const QStringList &v, const QString &tagName, const char *s = " ") +{ + if(v.isEmpty()) + return noxml(); + QStringList temp = v; + temp.append(QString("%(%1)").arg(tagName)); + return valueTag(temp.join(s)); +} + +inline XmlOutput::xml_output valueTagT( const triState v) +{ + if(v == unset) + return noxml(); + return valueTag(v == _True ? "true" : "false"); +} + + +// VCXCLCompilerTool ------------------------------------------------- +VCXCLCompilerTool::VCXCLCompilerTool() + : BrowseInformation(_False), + BufferSecurityCheck(_False), + CreateHotpatchableImage(unset), + DisableLanguageExtensions(unset), + EnableFiberSafeOptimizations(unset), + EnablePREfast(unset), + ExpandAttributedSource(unset), + FloatingPointExceptions(unset), + ForceConformanceInForLoopScope(unset), + FunctionLevelLinking(unset), + GenerateXMLDocumentationFiles(unset), + IgnoreStandardIncludePath(unset), + IntrinsicFunctions(unset), + MinimalRebuild(unset), + MultiProcessorCompilation(unset), + OmitDefaultLibName(unset), + OmitFramePointers(unset), + OpenMPSupport(unset), + PreprocessKeepComments(unset), + PreprocessSuppressLineNumbers(unset), + RuntimeTypeInfo(unset), + ShowIncludes(unset), + SmallerTypeCheck(unset), + StringPooling(unset), + SuppressStartupBanner(unset), + TreatWarningAsError(unset), + TreatWChar_tAsBuiltInType(unset), + UndefineAllPreprocessorDefinitions(unset), + UseFullPaths(unset), + UseUnicodeForAssemblerListing(unset), + WholeProgramOptimization(unset) +{ +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXCLCompilerTool &tool) +{ + return xml + << tag(_CLCompile) + << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";") + << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ") + << attrTagX(_AdditionalUsingDirectories, tool.AdditionalUsingDirectories, ";") + << attrTagS(_AlwaysAppend, tool.AlwaysAppend) + << attrTagS(_AssemblerListingLocation, tool.AssemblerListingLocation) + << attrTagS(_AssemblerOutput, tool.AssemblerOutput) + << attrTagS(_BasicRuntimeChecks, tool.BasicRuntimeChecks) + << attrTagT(_BrowseInformation, tool.BrowseInformation) + << attrTagS(_BrowseInformationFile, tool.BrowseInformationFile) + << attrTagT(_BufferSecurityCheck, tool.BufferSecurityCheck) + << attrTagS(_CallingConvention, tool.CallingConvention) + << attrTagS(_CompileAs, tool.CompileAs) + << attrTagS(_CompileAsManaged, tool.CompileAsManaged) + << attrTagT(_CreateHotpatchableImage, tool.CreateHotpatchableImage) + << attrTagS(_DebugInformationFormat, tool.DebugInformationFormat) + << attrTagT(_DisableLanguageExtensions, tool.DisableLanguageExtensions) + << attrTagX(_DisableSpecificWarnings, tool.DisableSpecificWarnings, ";") + << attrTagS(_EnableEnhancedInstructionSet, tool.EnableEnhancedInstructionSet) + << attrTagT(_EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations) + << attrTagT(_EnablePREfast, tool.EnablePREfast) + << attrTagS(_ErrorReporting, tool.ErrorReporting) + << attrTagS(_ExceptionHandling, tool.ExceptionHandling) + << attrTagT(_ExpandAttributedSource, tool.ExpandAttributedSource) + << attrTagS(_FavorSizeOrSpeed, tool.FavorSizeOrSpeed) + << attrTagT(_FloatingPointExceptions, tool.FloatingPointExceptions) + << attrTagS(_FloatingPointModel, tool.FloatingPointModel) + << attrTagT(_ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope) + << attrTagX(_ForcedIncludeFiles, tool.ForcedIncludeFiles, ";") + << attrTagX(_ForcedUsingFiles, tool.ForcedUsingFiles, ";") + << attrTagT(_FunctionLevelLinking, tool.FunctionLevelLinking) + << attrTagT(_GenerateXMLDocumentationFiles, tool.GenerateXMLDocumentationFiles) + << attrTagT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath) + << attrTagS(_InlineFunctionExpansion, tool.InlineFunctionExpansion) + << attrTagT(_IntrinsicFunctions, tool.IntrinsicFunctions) + << attrTagT(_MinimalRebuild, tool.MinimalRebuild) + << attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation) + << attrTagS(_ObjectFileName, tool.ObjectFileName) + << attrTagX(_ObjectFiles, tool.ObjectFiles, ";") + << attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName) + << attrTagT(_OmitFramePointers, tool.OmitFramePointers) + << attrTagT(_OpenMPSupport, tool.OpenMPSupport) + << attrTagS(_Optimization, tool.Optimization) + << attrTagS(_PrecompiledHeader, tool.PrecompiledHeader) + << attrTagS(_PrecompiledHeaderFile, tool.PrecompiledHeaderFile) + << attrTagS(_PrecompiledHeaderOutputFile, tool.PrecompiledHeaderOutputFile) + << attrTagT(_PreprocessKeepComments, tool.PreprocessKeepComments) + << attrTagX(_PreprocessorDefinitions, tool.PreprocessorDefinitions, ";") + << attrTagS(_PreprocessOutputPath, tool.PreprocessOutputPath) + << attrTagT(_PreprocessSuppressLineNumbers, tool.PreprocessSuppressLineNumbers) + << attrTagT(_PreprocessToFile, tool.PreprocessToFile) + << attrTagS(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName) + << attrTagS(_ProcessorNumber, tool.ProcessorNumber) + << attrTagS(_RuntimeLibrary, tool.RuntimeLibrary) + << attrTagT(_RuntimeTypeInfo, tool.RuntimeTypeInfo) + << attrTagT(_ShowIncludes, tool.ShowIncludes) + << attrTagT(_SmallerTypeCheck, tool.SmallerTypeCheck) + << attrTagT(_StringPooling, tool.StringPooling) + << attrTagS(_StructMemberAlignment, tool.StructMemberAlignment) + << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner) + << attrTagS(_TreatSpecificWarningsAsErrors, tool.TreatSpecificWarningsAsErrors) + << attrTagT(_TreatWarningAsError, tool.TreatWarningAsError) + << attrTagT(_TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType) + << attrTagT(_UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions) + << attrTagX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions, ";") + << attrTagT(_UseFullPaths, tool.UseFullPaths) + << attrTagT(_UseUnicodeForAssemblerListing, tool.UseUnicodeForAssemblerListing) + << attrTagS(_WarningLevel, tool.WarningLevel) + << attrTagT(_WholeProgramOptimization, tool.WholeProgramOptimization) + << attrTagS(_XMLDocumentationFileName, tool.XMLDocumentationFileName) + << closetag(_CLCompile); +} + +bool VCXCLCompilerTool::parseOption(const char* option) +{ + // skip index 0 ('/' or '-') + char first = option[1]; + char second = option[2]; + char third = option[3]; + char fourth = option[4]; + bool found = true; + + switch (first) { + case '?': + qWarning("Generator: Option '/?' : MSVC.NET projects do not support outputting help info"); + found = false; + break; + case '@': + qWarning("Generator: Option '/@': MSVC.NET projects do not support the use of a response file"); + found = false; + break; + case 'l': + qWarning("Generator: Option '/link': qmake generator does not support passing link options through the compiler tool"); + found = false; + break; + case 'A': + if(second != 'I') { + found = false; + break; + } + AdditionalUsingDirectories += option+3; + break; + case 'C': + PreprocessKeepComments = _True; + break; + case 'D': + PreprocessorDefinitions += option+2; + break; + case 'E': + if(second == 'H') { + QString opt(option); + if (opt.endsWith("EHa")) + ExceptionHandling = "Async"; + else if (opt.endsWith("EHsc")) + ExceptionHandling = "Sync"; + else if (opt.endsWith("EHs")) + ExceptionHandling = "SyncCThrow"; + else { + ExceptionHandling = "false"; + } + break; + }else if(second == 'P') { + PreprocessSuppressLineNumbers = _True; + } + found = false; + break; + case 'F': + if(second <= '9' && second >= '0') { + AdditionalOptions += option; + break; + } else { + switch (second) { + case 'A': + if(third == 'c') { + AssemblerOutput = "AssemblyAndMachineCode"; + if(fourth == 's') + AssemblerOutput = "All"; + } else if(third == 's') { + AssemblerOutput = "AssemblyAndSourceCode"; + } else if(third == 'u') { + UseUnicodeForAssemblerListing = _True; + } else { + AssemblerOutput = "AssemblyCode"; + } + break; + case 'a': + AssemblerListingLocation = option+3; + break; + case 'C': + UseFullPaths = _True; + break; + case 'd': + ProgramDataBaseFileName += option+3; + case 'I': + ForcedIncludeFiles += option+3; + break; + case 'i': + PreprocessOutputPath += option+3; + break; + case 'm': + AdditionalOptions += option; + break; + case 'R': + BrowseInformation = _True; + BrowseInformationFile = option+3; + break; + case 'r': + BrowseInformation = _True; + BrowseInformationFile = option+3; + break; + case 'U': + ForcedUsingFiles += option+3; + break; + case 'o': + ObjectFileName = option+3; + break; + case 'p': + PrecompiledHeaderOutputFile = option+3; + break; + case 'x': + ExpandAttributedSource = _True; + break; + default: + found = false; + break; + } + } + break; + case 'G': + switch (second) { + case 'F': + StringPooling = _True; + break; + case 'L': + WholeProgramOptimization = _True; + if(third == '-') + WholeProgramOptimization = _False; + break; + case 'R': + RuntimeTypeInfo = _True; + if(third == '-') + RuntimeTypeInfo = _False; + break; + case 'S': + BufferSecurityCheck = _True; + if(third == '-') + BufferSecurityCheck = _False; + break; + case 'T': + EnableFiberSafeOptimizations = _True; + break; + case 'd': + CallingConvention = "Cdecl"; + break; + case 'm': + MinimalRebuild = _True; + if(third == '-') + MinimalRebuild = _False; + break; + case 'r': + CallingConvention = "FastCall"; + break; + case 'y': + FunctionLevelLinking = _True; + break; + case 'z': + CallingConvention = "StdCall"; + break; + default: + found = false; + break; + } + break; + case 'H': + AdditionalOptions += option; + break; + case 'I': + AdditionalIncludeDirectories += option+2; + break; + case 'L': + if(second == 'D') { + AdditionalOptions += option; + break; + } + found = false; + break; + case 'M': + if(second == 'D') { + RuntimeLibrary = "MultiThreadedDLL"; + if(third == 'd') + RuntimeLibrary = "MultiThreadedDebugDLL"; + break; + } else if(second == 'P') { + MultiProcessorCompilation = _True; + ProcessorNumber = option+3; + break; + } else if(second == 'T') { + RuntimeLibrary = "MultiThreaded"; + if(third == 'd') + RuntimeLibrary = "MultiThreadedDebug"; + break; + } + found = false; + break; + case 'O': + switch (second) { + case '1': + Optimization = "MinSpace"; + break; + case '2': + Optimization = "MaxSpeed"; + break; + case 'b': + if(third == '0') + InlineFunctionExpansion = "Disabled"; + else if(third == '1') + InlineFunctionExpansion = "OnlyExplicitInline"; + else if(third == '2') + InlineFunctionExpansion = "AnySuitable"; + else + found = false; + break; + case 'd': + Optimization = "Disabled"; + break; + case 'i': + IntrinsicFunctions = _True; + break; + case 'p': + if(third == 'e') + OpenMPSupport = _True; + else + found = false; + break; + case 's': + FavorSizeOrSpeed = "Size"; + break; + case 't': + FavorSizeOrSpeed = "Speed"; + break; + case 'x': + Optimization = "Full"; + break; + case 'y': + OmitFramePointers = _True; + if(third == '-') + OmitFramePointers = _False; + break; + default: + found = false; + break; + } + break; + case 'P': + PreprocessToFile = _True; + break; + case 'Q': + if(second == 'I') { + AdditionalOptions += option; + break; + } + found = false; + break; + case 'R': + if(second == 'T' && third == 'C') { + if(fourth == '1') + BasicRuntimeChecks = "EnableFastChecks"; + else if(fourth == 'c') + SmallerTypeCheck = _True; + else if(fourth == 's') + BasicRuntimeChecks = "StackFrameRuntimeCheck"; + else if(fourth == 'u') + BasicRuntimeChecks = "UninitializedLocalUsageCheck"; + else + found = false; break; + } + break; + case 'T': + if(second == 'C') { + CompileAs = "CompileAsC"; + } else if(second == 'P') { + CompileAs = "CompileAsCpp"; + } else { + qWarning("Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake"); + found = false; break; + } + break; + case 'U': + UndefinePreprocessorDefinitions += option+2; + break; + case 'V': + AdditionalOptions += option; + break; + case 'W': + switch (second) { + case 'a': + WarningLevel = "EnableAllWarnings"; + break; + case '4': + WarningLevel = "Level4"; + break; + case '3': + WarningLevel = "Level3"; + break; + case '2': + WarningLevel = "Level2"; + break; + case '1': + WarningLevel = "Level1"; + break; + case '0': + WarningLevel = "TurnOffAllWarnings"; + break; + case 'L': + AdditionalOptions += option; + break; + case 'X': + TreatWarningAsError = _True; + break; + case 'p': + if(third == '6' && fourth == '4') { + // Deprecated for VS2010 but can be used under Additional Options. + AdditionalOptions += option; + break; + } + // Fallthrough + default: + found = false; break; + } + break; + case 'X': + IgnoreStandardIncludePath = _True; + break; + case 'Y': + switch (second) { + case '\0': + case '-': + AdditionalOptions += option; + break; + case 'c': + PrecompiledHeader = "Create"; + PrecompiledHeaderFile = option+3; + break; + case 'd': + case 'l': + AdditionalOptions += option; + break; + case 'u': + PrecompiledHeader = "Use"; + PrecompiledHeaderFile = option+3; + break; + default: + found = false; break; + } + break; + case 'Z': + switch (second) { + case '7': + DebugInformationFormat = "OldStyle"; + break; + case 'I': + DebugInformationFormat = "EditAndContinue"; + break; + case 'i': + DebugInformationFormat = "ProgramDatabase"; + break; + case 'l': + OmitDefaultLibName = _True; + break; + case 'a': + DisableLanguageExtensions = _True; + break; + case 'e': + DisableLanguageExtensions = _False; + break; + case 'c': + if(third == ':') { + const char *c = option + 4; + // Go to the end of the option + while ( *c != '\0' && *c != ' ' && *c != '-') + ++c; + if(fourth == 'f') + ForceConformanceInForLoopScope = ((*c) == '-' ? _False : _True); + else if(fourth == 'w') + TreatWChar_tAsBuiltInType = ((*c) == '-' ? _False : _True); + else + found = false; + } else { + found = false; break; + } + break; + case 'g': + case 'm': + case 's': + AdditionalOptions += option; + break; + case 'p': + switch (third) + { + case '\0': + case '1': + StructMemberAlignment = "1Byte"; + if(fourth == '6') + StructMemberAlignment = "16Bytes"; + break; + case '2': + StructMemberAlignment = "2Bytes"; + break; + case '4': + StructMemberAlignment = "4Bytes"; + break; + case '8': + StructMemberAlignment = "8Bytes"; + break; + default: + found = false; break; + } + break; + default: + found = false; break; + } + break; + case 'a': + if (second == 'r' && third == 'c' && fourth == 'h') { + if (option[5] == ':') { + const char *o = option; + if (o[6] == 'S' && o[7] == 'S' && o[8] == 'E') { + EnableEnhancedInstructionSet = o[9] == '2' ? "StreamingSIMDExtensions2" : "StreamingSIMDExtensions"; + break; + } + } + } else if (second == 'n' && third == 'a' && fourth == 'l') { + EnablePREfast = _True; + break; + } + found = false; + break; + case 'b': // see http://msdn.microsoft.com/en-us/library/fwkeyyhe%28VS.100%29.aspx + if (second == 'i' && third == 'g' && fourth == 'o') { + const char *o = option; + if (o[5] == 'b' && o[6] == 'j') { + AdditionalOptions += option; + break; + } + } + found = false; + break; + case 'c': + if(second == 'l') { + if(*(option+5) == 'p') { + CompileAsManaged = "Pure"; + } else if(*(option+5) == 's') { + CompileAsManaged = "Safe"; + } else if(*(option+5) == 'o') { + CompileAsManaged = "OldSyntax"; + } else { + CompileAsManaged = "true"; + } + } else { + found = false; + break; + } + break; + case 'd': + if(second != 'o' && third == 'c') { + GenerateXMLDocumentationFiles = _True; + XMLDocumentationFileName += option+4; + break; + } + found = false; + break; + case 'e': + if (second == 'r' && third == 'r' && fourth == 'o') { + if (option[12] == ':') { + if ( option[13] == 'n') { + ErrorReporting = "None"; + } else if (option[13] == 'p') { + ErrorReporting = "Prompt"; + } else if (option[13] == 'q') { + ErrorReporting = "Queue"; + } else if (option[13] == 's') { + ErrorReporting = "Send"; + } else { + found = false; + } + break; + } + } + found = false; + break; + case 'f': + if(second == 'p' && third == ':') { + // Go to the end of the option + const char *c = option + 4; + while (*c != '\0' && *c != ' ' && *c != '-') + ++c; + switch (fourth) { + case 'e': + FloatingPointExceptions = ((*c) == '-' ? _False : _True); + break; + case 'f': + FloatingPointModel = "Fast"; + break; + case 'p': + FloatingPointModel = "Precise"; + break; + case 's': + FloatingPointModel = "Strict"; + break; + default: + found = false; + break; + } + } + break; + case 'h': + if(second == 'o' && third == 't' && fourth == 'p') { + CreateHotpatchableImage = _True; + break; + } + qWarning("Generator: Option '/help': MSVC.NET projects do not support outputting help info"); + found = false; + break; + case 'n': + if(second == 'o' && third == 'l' && fourth == 'o') { + SuppressStartupBanner = _True; + break; + } + found = false; + break; + case 'o': + if (second == 'p' && third == 'e' && fourth == 'n') { + OpenMPSupport = _True; + break; + } + found = false; + break; + case 's': + if(second == 'h' && third == 'o' && fourth == 'w') { + ShowIncludes = _True; + break; + } + found = false; + break; + case 'u': + UndefineAllPreprocessorDefinitions = _True; + break; + case 'v': + if(second == 'd' || second == 'm') { + AdditionalOptions += option; + break; + } + found = false; + break; + case 'w': + switch (second) { + case 'd': + DisableSpecificWarnings += option+3; + break; + case 'e': + TreatSpecificWarningsAsErrors = option+3; + break; + default: + AdditionalOptions += option; + } + break; + default: + AdditionalOptions += option; + break; + } + if(!found) { + warn_msg(WarnLogic, "Could not parse Compiler option: %s, added as AdditionalOption", option); + AdditionalOptions += option; + } + return true; +} + +// VCLinkerTool ----------------------------------------------------- +VCXLinkerTool::VCXLinkerTool() + : AllowIsolation(unset), + AssemblyDebug(unset), + DataExecutionPrevention(unset), + DelaySign(unset), + EnableCOMDATFolding(unset), + EnableUAC(unset), + FixedBaseAddress(unset), + GenerateDebugInformation(unset), + GenerateManifest(unset), + GenerateMapFile(unset), + HeapCommitSize(-1), + HeapReserveSize(-1), + IgnoreAllDefaultLibraries(unset), + IgnoreEmbeddedIDL(unset), + IgnoreImportLibrary(_True), + ImageHasSafeExceptionHandlers(unset), + LargeAddressAware(unset), + LinkDLL(unset), + LinkIncremental(unset), + LinkStatus(unset), + MapExports(unset), + NoEntryPoint(unset), + OptimizeReferences(unset), + PreventDllBinding(unset), + RandomizedBaseAddress(unset), + RegisterOutput(unset), + SectionAlignment(-1), + SetChecksum(unset), + //StackCommitSize(-1), + //StackReserveSize(-1), + SupportNobindOfDelayLoadedDLL(unset), + SupportUnloadOfDelayLoadedDLL(unset), + SuppressStartupBanner(unset), + SwapRunFromCD(unset), + SwapRunFromNet(unset), + TerminalServerAware(unset), + TreatLinkerWarningAsErrors(unset), + TurnOffAssemblyGeneration(unset), + TypeLibraryResourceID(0), + UACUIAccess(unset) +{ +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXLinkerTool &tool) +{ + return xml + << tag(_Link) + << attrTagX(_AdditionalDependencies, tool.AdditionalDependencies, ";") + << attrTagX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories, ";") + << attrTagX(_AdditionalManifestDependencies, tool.AdditionalManifestDependencies, ";") + << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ") + << attrTagX(_AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly, ";") + << attrTagT(_AllowIsolation, tool.AllowIsolation) + << attrTagT(_AssemblyDebug, tool.AssemblyDebug) + << attrTagX(_AssemblyLinkResource, tool.AssemblyLinkResource, ";") + << attrTagS(_BaseAddress, tool.BaseAddress) + << attrTagS(_CLRImageType, tool.CLRImageType) + << attrTagS(_CLRSupportLastError, tool.CLRSupportLastError) + << attrTagS(_CLRThreadAttribute, tool.CLRThreadAttribute) + << attrTagS(_CLRUnmanagedCodeCheck, tool.CLRUnmanagedCodeCheck) + << attrTagS(_CreateHotPatchableImage, tool.CreateHotPatchableImage) + << attrTagT(_DataExecutionPrevention, tool.DataExecutionPrevention) + << attrTagX(_DelayLoadDLLs, tool.DelayLoadDLLs, ";") + << attrTagT(_DelaySign, tool.DelaySign) + << attrTagS(_Driver, tool.Driver) + << attrTagX(_EmbedManagedResourceFile, tool.EmbedManagedResourceFile, ";") + << attrTagT(_EnableCOMDATFolding, tool.EnableCOMDATFolding) + << attrTagT(_EnableUAC, tool.EnableUAC) + << attrTagS(_EntryPointSymbol, tool.EntryPointSymbol) + << attrTagT(_FixedBaseAddress, tool.FixedBaseAddress) + << attrTagS(_ForceFileOutput, tool.ForceFileOutput) + << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";") + << attrTagS(_FunctionOrder, tool.FunctionOrder) + << attrTagT(_GenerateDebugInformation, tool.GenerateDebugInformation) + << attrTagT(_GenerateManifest, tool.GenerateManifest) + << attrTagT(_GenerateMapFile, tool.GenerateMapFile) + << attrTagL(_HeapCommitSize, tool.HeapCommitSize, /*ifNot*/ -1) + << attrTagL(_HeapReserveSize, tool.HeapReserveSize, /*ifNot*/ -1) + << attrTagT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries) + << attrTagT(_IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL) + << attrTagT(_IgnoreImportLibrary, tool.IgnoreImportLibrary) + << attrTagX(_IgnoreSpecificDefaultLibraries, tool.IgnoreSpecificDefaultLibraries, ";") + << attrTagT(_ImageHasSafeExceptionHandlers, tool.ImageHasSafeExceptionHandlers) + << attrTagS(_ImportLibrary, tool.ImportLibrary) + << attrTagS(_KeyContainer, tool.KeyContainer) + << attrTagS(_KeyFile, tool.KeyFile) + << attrTagT(_LargeAddressAware, tool.LargeAddressAware) + << attrTagT(_LinkDLL, tool.LinkDLL) + << attrTagS(_LinkErrorReporting, tool.LinkErrorReporting) + << attrTagT(_LinkIncremental, tool.LinkIncremental) + << attrTagT(_LinkStatus, tool.LinkStatus) + << attrTagS(_LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration) + << attrTagS(_ManifestFile, tool.ManifestFile) + << attrTagT(_MapExports, tool.MapExports) + << attrTagS(_MapFileName, tool.MapFileName) + << attrTagS(_MergedIDLBaseFileName, tool.MergedIDLBaseFileName) + << attrTagS(_MergeSections, tool.MergeSections) + << attrTagS(_MidlCommandFile, tool.MidlCommandFile) + << attrTagS(_ModuleDefinitionFile, tool.ModuleDefinitionFile) + << attrTagS(_MSDOSStubFileName, tool.MSDOSStubFileName) + << attrTagT(_NoEntryPoint, tool.NoEntryPoint) + << attrTagT(_OptimizeReferences, tool.OptimizeReferences) + << attrTagS(_OutputFile, tool.OutputFile) + << attrTagT(_PreventDllBinding, tool.PreventDllBinding) + << attrTagS(_Profile, tool.Profile) + << attrTagS(_ProfileGuidedDatabase, tool.ProfileGuidedDatabase) + << attrTagS(_ProgramDatabaseFile, tool.ProgramDatabaseFile) + << attrTagT(_RandomizedBaseAddress, tool.RandomizedBaseAddress) + << attrTagT(_RegisterOutput, tool.RegisterOutput) + << attrTagL(_SectionAlignment, tool.SectionAlignment, /*ifNot*/ -1) + << attrTagT(_SetChecksum, tool.SetChecksum) + << attrTagS(_ShowProgress, tool.ShowProgress) + << attrTagS(_SpecifySectionAttributes, tool.SpecifySectionAttributes) + << attrTagS(_StackCommitSize, tool.StackCommitSize) + << attrTagS(_StackReserveSize, tool.StackReserveSize) + << attrTagS(_StripPrivateSymbols, tool.StripPrivateSymbols) + << attrTagS(_SubSystem, tool.SubSystem) + << attrTagT(_SupportNobindOfDelayLoadedDLL, tool.SupportNobindOfDelayLoadedDLL) + << attrTagT(_SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL) + << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner) + << attrTagT(_SwapRunFromCD, tool.SwapRunFromCD) + << attrTagT(_SwapRunFromNet, tool.SwapRunFromNet) + << attrTagS(_TargetMachine, tool.TargetMachine) + << attrTagT(_TerminalServerAware, tool.TerminalServerAware) + << attrTagT(_TreatLinkerWarningAsErrors, tool.TreatLinkerWarningAsErrors) + << attrTagT(_TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration) + << attrTagS(_TypeLibraryFile, tool.TypeLibraryFile) + << attrTagL(_TypeLibraryResourceID, tool.TypeLibraryResourceID, /*ifNot*/ 0) + << attrTagS(_UACExecutionLevel, tool.UACExecutionLevel) + << attrTagT(_UACUIAccess, tool.UACUIAccess) + << attrTagS(_Version, tool.Version) + << closetag(_Link); +} + +// Hashing routine to do fast option lookups ---- +// Slightly rewritten to stop on ':' ',' and '\0' +// Original routine in qtranslator.cpp ---------- +static uint elfHash(const char* name) +{ + const uchar *k; + uint h = 0; + uint g; + + if(name) { + k = (const uchar *) name; + while((*k) && + (*k)!= ':' && + (*k)!=',' && + (*k)!=' ') { + h = (h << 4) + *k++; + if((g = (h & 0xf0000000)) != 0) + h ^= g >> 24; + h &= ~g; + } + } + if(!h) + h = 1; + return h; +} + +//#define USE_DISPLAY_HASH +#ifdef USE_DISPLAY_HASH +static void displayHash(const char* str) +{ + printf("case 0x%07x: // %s\n break;\n", elfHash(str), str); +} +#endif + +bool VCXLinkerTool::parseOption(const char* option) +{ +#ifdef USE_DISPLAY_HASH + // Main options + displayHash("/ALIGN"); displayHash("/ALLOWBIND"); displayHash("/ASSEMBLYMODULE"); + displayHash("/ASSEMBLYRESOURCE"); displayHash("/BASE"); displayHash("/DEBUG"); + displayHash("/DEF"); displayHash("/DEFAULTLIB"); displayHash("/DELAY"); + displayHash("/DELAYLOAD"); displayHash("/DLL"); displayHash("/DRIVER"); + displayHash("/ENTRY"); displayHash("/EXETYPE"); displayHash("/EXPORT"); + displayHash("/FIXED"); displayHash("/FORCE"); displayHash("/HEAP"); + displayHash("/IDLOUT"); displayHash("/IGNORE"); displayHash("/IGNOREIDL"); displayHash("/IMPLIB"); + displayHash("/INCLUDE"); displayHash("/INCREMENTAL"); displayHash("/LARGEADDRESSAWARE"); + displayHash("/LIBPATH"); displayHash("/LTCG"); displayHash("/MACHINE"); + displayHash("/MAP"); displayHash("/MAPINFO"); displayHash("/MERGE"); + displayHash("/MIDL"); displayHash("/NOASSEMBLY"); displayHash("/NODEFAULTLIB"); + displayHash("/NOENTRY"); displayHash("/NOLOGO"); displayHash("/OPT"); + displayHash("/ORDER"); displayHash("/OUT"); displayHash("/PDB"); + displayHash("/PDBSTRIPPED"); displayHash("/RELEASE"); displayHash("/SECTION"); + displayHash("/STACK"); displayHash("/STUB"); displayHash("/SUBSYSTEM"); + displayHash("/SWAPRUN"); displayHash("/TLBID"); displayHash("/TLBOUT"); + displayHash("/TSAWARE"); displayHash("/VERBOSE"); displayHash("/VERSION"); + displayHash("/VXD"); displayHash("/WS "); displayHash("/libpath"); + +#endif +#ifdef USE_DISPLAY_HASH + // Sub options + displayHash("UNLOAD"); displayHash("NOBIND"); displayHash("no"); displayHash("NOSTATUS"); displayHash("STATUS"); + displayHash("AM33"); displayHash("ARM"); displayHash("CEE"); displayHash("EBC"); displayHash("IA64"); displayHash("X86"); displayHash("X64"); displayHash("M32R"); + displayHash("MIPS"); displayHash("MIPS16"); displayHash("MIPSFPU"); displayHash("MIPSFPU16"); displayHash("MIPSR41XX"); displayHash("PPC"); + displayHash("SH3"); displayHash("SH3DSP"); displayHash("SH4"); displayHash("SH5"); displayHash("THUMB"); displayHash("TRICORE"); displayHash("EXPORTS"); + displayHash("LINES"); displayHash("REF"); displayHash("NOREF"); displayHash("ICF"); displayHash("WIN98"); displayHash("NOWIN98"); + displayHash("CONSOLE"); displayHash("EFI_APPLICATION"); displayHash("EFI_BOOT_SERVICE_DRIVER"); displayHash("EFI_ROM"); displayHash("EFI_RUNTIME_DRIVER"); displayHash("NATIVE"); + displayHash("POSIX"); displayHash("WINDOWS"); displayHash("WINDOWSCE"); displayHash("NET"); displayHash("CD"); displayHash("NO"); +#endif + bool found = true; + switch (elfHash(option)) { + case 0x6b21972: // /DEFAULTLIB:library + case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386] + case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA] + case 0x3dc3455: // /IGNORE:number,number,number,number ### NOTE: This one is undocumented, but it is even used by Microsoft. + // In recent versions of the Microsoft linker they have disabled this undocumented feature. + case 0x0034bc4: // /VXD + AdditionalOptions += option; + break; + case 0x3360dbe: // /ALIGN[:number] + SectionAlignment = QString(option+7).toLongLong(); + break; + case 0x1485c34: // /ALLOWBIND[:NO] + if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N')) + PreventDllBinding = _False; + else + PreventDllBinding = _True; + break; + case 0x312011e: // /ALLOWISOLATION[:NO] + if(*(option+15) == ':' && (*(option+16) == 'n' || *(option+16) == 'N')) + AllowIsolation = _False; + else + AllowIsolation = _True; + break; + case 0x679c075: // /ASSEMBLYMODULE:filename + AddModuleNamesToAssembly += option+15; + break; + case 0x75f35f7: // /ASSEMBLYDEBUG[:DISABLE] + if(*(option+14) == ':' && (*(option+15) == 'D')) + AssemblyDebug = _False; + else + AssemblyDebug = _True; + break; + case 0x43294a5: // /ASSEMBLYLINKRESOURCE:filename + AssemblyLinkResource += option+22; + break; + case 0x062d065: // /ASSEMBLYRESOURCE:filename + EmbedManagedResourceFile += option+18; + break; + case 0x0336675: // /BASE:{address | @filename,key} + // Do we need to do a manual lookup when '@filename,key'? + // Seems BaseAddress only can contain the location... + // We don't use it in Qt, so keep it simple for now + BaseAddress = option+6; + break; + case 0x63bf065: // /CLRIMAGETYPE:{IJW|PURE|SAFE} + if(*(option+14) == 'I') + CLRImageType = "ForceIJWImage"; + else if(*(option+14) == 'P') + CLRImageType = "ForcePureILImage"; + else if(*(option+14) == 'S') + CLRImageType = "ForceSafeILImage"; + break; + case 0x5f2a6a2: // /CLRSUPPORTLASTERROR{:NO | SYSTEMDLL} + if(*(option+20) == ':') { + if(*(option+21) == 'N') { + CLRSupportLastError = "Disabled"; + } else if(*(option+21) == 'S') { + CLRSupportLastError = "SystemDlls"; + } + } else { + CLRSupportLastError = "Enabled"; + } + break; + case 0xc7984f5: // /CLRTHREADATTRIBUTE:{STA|MTA|NONE} + if(*(option+20) == 'N') + CLRThreadAttribute = "DefaultThreadingAttribute"; + else if(*(option+20) == 'M') + CLRThreadAttribute = "MTAThreadingAttribute"; + else if(*(option+20) == 'S') + CLRThreadAttribute = "STAThreadingAttribute"; + break; + case 0xa8c637b: // /CLRUNMANAGEDCODECHECK[:NO] + if(*(option+23) == 'N') + CLRUnmanagedCodeCheck = _False; + else + CLRUnmanagedCodeCheck = _True; + break; + case 0x3389797: // /DEBUG + GenerateDebugInformation = _True; + break; + case 0x0033896: // /DEF:filename + ModuleDefinitionFile = option+5; + break; + case 0x338a069: // /DELAY:{UNLOAD | NOBIND} + if(*(option+7) == 'U') + SupportNobindOfDelayLoadedDLL = _True; + else if(*(option+7) == 'N') + SupportUnloadOfDelayLoadedDLL = _True; + break; + case 0x06f4bf4: // /DELAYLOAD:dllname + DelayLoadDLLs += option+11; + break; + case 0x06d451e: // /DELAYSIGN[:NO] + if(*(option+10) == ':' && (*(option+11) == 'n' || *(option+11) == 'N')) + DelaySign = _False; + else + DelaySign = _True; + break; + case 0x003390c: // /DLL + LinkDLL = _True; + break; + case 0x396ea92: // /DRIVER[:UPONLY | :WDM] + if((*(option+7) == ':') && (*(option+8) == 'U')) + Driver = "UpOnly"; + else if((*(option+7) == ':') && (*(option+8) == 'W')) + Driver = "WDM"; + else + Driver = "Driver"; + break; + case 0x2ee8415: // /DYNAMICBASE[:NO] + if(*(option+12) == ':' && (*(option+13) == 'n' || *(option+13) == 'N')) + RandomizedBaseAddress = _False; + else + RandomizedBaseAddress = _True; + break; + case 0x33a3979: // /ENTRY:function + EntryPointSymbol = option+7; + break; + case 0x4504334: // /ERRORREPORT:[ NONE | PROMPT | QUEUE | SEND ] + if(*(option+12) == ':' ) { + if(*(option+13) == 'N') + LinkErrorReporting = "NoErrorReport"; + else if(*(option+13) == 'P') + LinkErrorReporting = "PromptImmediately"; + else if(*(option+13) == 'Q') + LinkErrorReporting = "QueueForNextLogin"; + else if(*(option+13) == 'S') + LinkErrorReporting = "SendErrorReport"; + } + break; + case 0x33aec94: // /FIXED[:NO] + if(*(option+6) == ':' && (*(option+7) == 'n' || *(option+7) == 'N')) + FixedBaseAddress = _False; + else + FixedBaseAddress = _True; + break; + case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED] + if(*(option+6) == ':' && *(option+7) == 'M' ) + ForceFileOutput = "MultiplyDefinedSymbolOnly"; + else if(*(option+6) == ':' && *(option+7) == 'U' ) + ForceFileOutput = "UndefinedSymbolOnly"; + else + ForceFileOutput = "Enabled"; + break; + case 0x96d4e4e: // /FUNCTIONPADMIN[:space] + if(*(option+15) == ':') { + if(*(option+16) == '5') + CreateHotPatchableImage = "X86Image"; + else if(*(option+16) == '6') + CreateHotPatchableImage = "X64Image"; + else if((*(option+16) == '1') && (*(option+17) == '6')) + CreateHotPatchableImage = "ItaniumImage"; + } else { + CreateHotPatchableImage = "Enabled"; + } + break; + case 0x033c960: // /HEAP:reserve[,commit] + { + QStringList both = QString(option+6).split(","); + HeapReserveSize = both[0].toLongLong(); + if(both.count() == 2) + HeapCommitSize = both[1].toLongLong(); + } + break; + case 0x3d91494: // /IDLOUT:[path\]filename + MergedIDLBaseFileName = option+8; + break; + case 0x345a04c: // /IGNOREIDL + IgnoreEmbeddedIDL = _True; + break; + case 0x3e250e2: // /IMPLIB:filename + ImportLibrary = option+8; + break; + case 0xe281ab5: // /INCLUDE:symbol + ForceSymbolReferences += option+9; + break; + case 0xb28103c: // /INCREMENTAL[:no] + if(*(option+12) == ':' && + (*(option+13) == 'n' || *(option+13) == 'N')) + LinkIncremental = _False; + else + LinkIncremental = _True; + break; + case 0x07f1ab2: // /KEYCONTAINER:name + KeyContainer = option+14; + break; + case 0xfadaf35: // /KEYFILE:filename + KeyFile = option+9; + break; + case 0x26e4675: // /LARGEADDRESSAWARE[:no] + if(*(option+18) == ':' && + *(option+19) == 'n') + LargeAddressAware = _False; + else + LargeAddressAware = _True; + break; + case 0x2f96bc8: // /libpath:dir + case 0x0d745c8: // /LIBPATH:dir + AdditionalLibraryDirectories += option+9; + break; + case 0x0341877: // /LTCG[:NOSTATUS|:STATUS] + config->WholeProgramOptimization = _True; + LinkTimeCodeGeneration = "UseLinkTimeCodeGeneration"; + if(*(option+5) == ':') { + const char* str = option+6; + if (*str == 'S') + LinkStatus = _True; + else if (*str == 'N') + LinkStatus = _False; +#ifndef Q_OS_WIN + else if (strncasecmp(str, "pginstrument", 12)) + LinkTimeCodeGeneration = "PGInstrument"; + else if (strncasecmp(str, "pgoptimize", 10)) + LinkTimeCodeGeneration = "PGOptimization"; + else if (strncasecmp(str, "pgupdate", 8 )) + LinkTimeCodeGeneration = "PGUpdate"; +#else + + else if (_stricmp(str, "pginstrument")) + LinkTimeCodeGeneration = "PGInstrument"; + else if (_stricmp(str, "pgoptimize")) + LinkTimeCodeGeneration = "PGOptimization"; + else if (_stricmp(str, "pgupdate")) + LinkTimeCodeGeneration = "PGUpdate"; +#endif + } + break; + case 0x379ED25: + case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE} + switch (elfHash(option+9)) { + case 0x0005bb6: // X86 + TargetMachine = "MachineX86"; + break; + case 0x0005b94: // X64 + TargetMachine = "MachineX64"; + break; + case 0x000466d: // ARM + TargetMachine = "MachineARM"; + break; + case 0x0004963: // EBC + TargetMachine = "MachineEBC"; + break; + case 0x004d494: // IA64 + TargetMachine = "MachineIA64"; + break; + case 0x0051e53: // MIPS + TargetMachine = "MachineMIPS"; + break; + case 0x51e5646: // MIPS16 + TargetMachine = "MachineMIPS16"; + break; + case 0x1e57b05: // MIPSFPU + TargetMachine = "MachineMIPSFPU"; + break; + case 0x57b09a6: // MIPSFPU16 + TargetMachine = "MachineMIPSFPU16"; + break; + case 0x00057b4: // SH4 + TargetMachine = "MachineSH4"; + break; + case 0x058da12: // THUMB + TargetMachine = "MachineTHUMB"; + break; + // put the others in AdditionalOptions... + case 0x0046063: // AM33 + case 0x0004795: // CEE + case 0x0050672: // M32R + case 0x5852738: // MIPSR41XX + case 0x0005543: // PPC + case 0x00057b3: // SH3 + case 0x57b7980: // SH3DSP + case 0x00057b5: // SH5 + case 0x96d8435: // TRICORE + default: + AdditionalOptions += option; + break; + } + break; + case 0x62d9e94: // /MANIFEST[:NO] + if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n'))) + GenerateManifest = _False; + else + GenerateManifest = _True; + break; + case 0x8b64559: // /MANIFESTDEPENDENCY:manifest_dependency + AdditionalManifestDependencies += option+20; + break; + case 0xe9e8195: // /MANIFESTFILE:filename + ManifestFile = option+14; + break; + case 0x9e9fb83: // /MANIFESTUAC http://msdn.microsoft.com/en-us/library/bb384691%28VS.100%29.aspx + if ((*(option+12) == ':' && (*(option+13) == 'N' || *(option+13) == 'n'))) + EnableUAC = _False; + else if((*(option+12) == ':' && (*(option+13) == 'l' || *(option+14) == 'e'))) { // level + if(*(option+20) == 'a') + UACExecutionLevel = "AsInvoker"; + else if(*(option+20) == 'h') + UACExecutionLevel = "HighestAvailable"; + else if(*(option+20) == 'r') + UACExecutionLevel = "RequireAdministrator"; + } else if((*(option+12) == ':' && (*(option+13) == 'u' || *(option+14) == 'i'))) { // uiAccess + if(*(option+22) == 't') + UACUIAccess = _True; + else + UACUIAccess = _False; + } else if((*(option+12) == ':' && (*(option+13) == 'f' || *(option+14) == 'r'))) { // fragment + AdditionalOptions += option; + }else + EnableUAC = _True; + break; + case 0x0034160: // /MAP[:filename] + GenerateMapFile = _True; + MapFileName = option+5; + break; + case 0x164e1ef: // /MAPINFO:{EXPORTS} + if(*(option+9) == 'E') + MapExports = _True; + break; + case 0x341a6b5: // /MERGE:from=to + MergeSections = option+7; + break; + case 0x0341d8c: // /MIDL:@file + MidlCommandFile = option+7; + break; + case 0x84e2679: // /NOASSEMBLY + TurnOffAssemblyGeneration = _True; + break; + case 0x2b21942: // /NODEFAULTLIB[:library] + if(*(option+13) == '\0') + IgnoreAllDefaultLibraries = _True; + else + IgnoreSpecificDefaultLibraries += option+14; + break; + case 0x33a3a39: // /NOENTRY + NoEntryPoint = _True; + break; + case 0x434138f: // /NOLOGO + SuppressStartupBanner = _True; + break; + case 0xc841054: // /NXCOMPAT[:NO] + if ((*(option+9) == ':' && (*(option+10) == 'N' || *(option+10) == 'n'))) + DataExecutionPrevention = _False; + else + DataExecutionPrevention = _True; + break; + case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98} + { + char third = *(option+7); + switch (third) { + case 'F': // REF + if(*(option+5) == 'R') { + OptimizeReferences = _True; + } else { // ICF[=iterations] + EnableCOMDATFolding = _True; + // [=iterations] case is not documented + } + break; + case 'R': // NOREF + OptimizeReferences = _False; + break; + case 'I': // NOICF + EnableCOMDATFolding = _False; + break; + default: + found = false; + } + } + break; + case 0x34468a2: // /ORDER:@filename + FunctionOrder = option+8; + break; + case 0x00344a4: // /OUT:filename + OutputFile = option+5; + break; + case 0x0034482: // /PDB:filename + ProgramDatabaseFile = option+5; + break; + case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name + StripPrivateSymbols = option+13; + break; + case 0x00344b4: // /PGD:filename + ProfileGuidedDatabase = option+5; + break; + case 0x573af45: // /PROFILE + Profile = _True; + break; + case 0x6a09535: // /RELEASE + SetChecksum = _True; + break; + case 0x75AA4D8: // /SAFESEH:{NO} + { + if(*(option+8) == ':' && *(option+9) == 'N') + ImageHasSafeExceptionHandlers = _False; + else + ImageHasSafeExceptionHandlers = _True; + } + break; + case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#] + SpecifySectionAttributes = option+9; + break; + case 0x348857b: // /STACK:reserve[,commit] + { + QStringList both = QString(option+7).split(","); + StackReserveSize = both[0].toLongLong(); + if(both.count() == 2) + StackCommitSize = both[1].toLongLong(); + } + break; + case 0x0348992: // /STUB:filename + MSDOSStubFileName = option+6; + break; + case 0x9B3C00D: + case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]] + { + // Split up in subsystem, and version number + QStringList both = QString(option+11).split(","); + switch (elfHash(both[0].toLatin1())) { + case 0x8438445: // CONSOLE + SubSystem = "Console"; + break; + case 0xbe29493: // WINDOWS + SubSystem = "Windows"; + break; + case 0x5268ea5: // NATIVE + SubSystem = "Native"; + break; + case 0x240949e: // EFI_APPLICATION + SubSystem = "EFI Application"; + break; + case 0xe617652: // EFI_BOOT_SERVICE_DRIVER + SubSystem = "EFI Boot Service Driver"; + break; + case 0x9af477d: // EFI_ROM + SubSystem = "EFI ROM"; + break; + case 0xd34df42: // EFI_RUNTIME_DRIVER + SubSystem = "EFI Runtime"; + break; + case 0x2949c95: // WINDOWSCE + SubSystem = "WindowsCE"; + break; + case 0x05547e8: // POSIX + SubSystem = "POSIX"; + break; + // The following are undocumented, so add them to AdditionalOptions + case 0x4B69795: // windowsce + AdditionalOptions += option; + break; + default: + found = false; + } + } + break; + case 0x8b654de: // /SWAPRUN:{NET | CD} + if(*(option+9) == 'N') + SwapRunFromNet = _True; + else if(*(option+9) == 'C') + SwapRunFromCD = _True; + else + found = false; + break; + case 0x34906d4: // /TLBID:id + TypeLibraryResourceID = QString(option+7).toLongLong(); + break; + case 0x4907494: // /TLBOUT:[path\]filename + TypeLibraryFile = option+8; + break; + case 0x976b525: // /TSAWARE[:NO] + if(*(option+8) == ':') + TerminalServerAware = _False; + else + TerminalServerAware = _True; + break; + case 0xaa67735: // /VERBOSE[:ICF |:LIB |:REF |:SAFESEH] + if(*(option+9) == ':') { + if (*(option+10) == 'I') { + ShowProgress = "LinkVerboseICF"; + } else if ( *(option+10) == 'L') { + ShowProgress = "LinkVerboseLib"; + } else if ( *(option+10) == 'R') { + ShowProgress = "LinkVerboseREF"; + } else if ( *(option+10) == 'S') { + ShowProgress = "LinkVerboseSAFESEH"; + } else if ( *(option+10) == 'C') { + ShowProgress = "LinkVerboseCLR"; + } + } else { + ShowProgress = "LinkVerbose"; + } + break; + case 0xaa77f7e: // /VERSION:major[.minor] + Version = option+9; + break; + case 0x0034c50: // /WS[:NO] + if(*(option+3) == ':') + TreatLinkerWarningAsErrors = _False; + else + TreatLinkerWarningAsErrors = _True; + break; + default: + AdditionalOptions += option; + break; + } + if(!found) { + warn_msg(WarnLogic, "Could not parse Linker options: %s, added as AdditionalOption", option); + AdditionalOptions += option; + } + return found; +} + +// VCMIDLTool ------------------------------------------------------- +VCXMIDLTool::VCXMIDLTool() + : ApplicationConfigurationMode(unset), + ErrorCheckAllocations(unset), + ErrorCheckBounds(unset), + ErrorCheckEnumRange(unset), + ErrorCheckRefPointers(unset), + ErrorCheckStubData(unset), + GenerateStublessProxies(unset), + GenerateTypeLibrary(unset), + IgnoreStandardIncludePath(unset), + LocaleID(-1), + MkTypLibCompatible(unset), + SuppressCompilerWarnings(unset), + SuppressStartupBanner(unset), + ValidateAllParameters(unset), + WarnAsError(unset) +{ +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXMIDLTool &tool) +{ + return xml + << tag(_Midl) + << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";") + << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ") + << attrTagT(_ApplicationConfigurationMode, tool.ApplicationConfigurationMode) + << attrTagS(_ClientStubFile, tool.ClientStubFile) + << attrTagS(_CPreprocessOptions, tool.CPreprocessOptions) + << attrTagS(_DefaultCharType, tool.DefaultCharType) + << attrTagS(_DLLDataFileName, tool.DLLDataFileName) + << attrTagS(_EnableErrorChecks, tool.EnableErrorChecks) + << attrTagT(_ErrorCheckAllocations, tool.ErrorCheckAllocations) + << attrTagT(_ErrorCheckBounds, tool.ErrorCheckBounds) + << attrTagT(_ErrorCheckEnumRange, tool.ErrorCheckEnumRange) + << attrTagT(_ErrorCheckRefPointers, tool.ErrorCheckRefPointers) + << attrTagT(_ErrorCheckStubData, tool.ErrorCheckStubData) + << attrTagS(_GenerateClientFiles, tool.GenerateClientFiles) + << attrTagS(_GenerateServerFiles, tool.GenerateServerFiles) + << attrTagT(_GenerateStublessProxies, tool.GenerateStublessProxies) + << attrTagT(_GenerateTypeLibrary, tool.GenerateTypeLibrary) + << attrTagS(_HeaderFileName, tool.HeaderFileName) + << attrTagT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath) + << attrTagS(_InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName) + << attrTagL(_LocaleID, tool.LocaleID, /*ifNot*/ -1) + << attrTagT(_MkTypLibCompatible, tool.MkTypLibCompatible) + << attrTagS(_OutputDirectory, tool.OutputDirectory) + << attrTagX(_PreprocessorDefinitions, tool.PreprocessorDefinitions, ";") + << attrTagS(_ProxyFileName, tool.ProxyFileName) + << attrTagS(_RedirectOutputAndErrors, tool.RedirectOutputAndErrors) + << attrTagS(_ServerStubFile, tool.ServerStubFile) + << attrTagS(_StructMemberAlignment, tool.StructMemberAlignment) + << attrTagT(_SuppressCompilerWarnings, tool.SuppressCompilerWarnings) + << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner) + << attrTagS(_TargetEnvironment, tool.TargetEnvironment) + << attrTagS(_TypeLibFormat, tool.TypeLibFormat) + << attrTagS(_TypeLibraryName, tool.TypeLibraryName) + << attrTagX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions, ";") + << attrTagT(_ValidateAllParameters, tool.ValidateAllParameters) + << attrTagT(_WarnAsError, tool.WarnAsError) + << attrTagS(_WarningLevel, tool.WarningLevel) + << closetag(_Midl); +} + +bool VCXMIDLTool::parseOption(const char* option) +{ +#ifdef USE_DISPLAY_HASH + displayHash("/D name[=def]"); displayHash("/I directory-list"); displayHash("/Oi"); + displayHash("/Oic"); displayHash("/Oicf"); displayHash("/Oif"); displayHash("/Os"); + displayHash("/U name"); displayHash("/WX"); displayHash("/W{0|1|2|3|4}"); + displayHash("/Zp {N}"); displayHash("/Zs"); displayHash("/acf filename"); + displayHash("/align {N}"); displayHash("/app_config"); displayHash("/c_ext"); + displayHash("/char ascii7"); displayHash("/char signed"); displayHash("/char unsigned"); + displayHash("/client none"); displayHash("/client stub"); displayHash("/confirm"); + displayHash("/cpp_cmd cmd_line"); displayHash("/cpp_opt options"); + displayHash("/cstub filename"); displayHash("/dlldata filename"); displayHash("/env win32"); + displayHash("/env win64"); displayHash("/error all"); displayHash("/error allocation"); + displayHash("/error bounds_check"); displayHash("/error enum"); displayHash("/error none"); + displayHash("/error ref"); displayHash("/error stub_data"); displayHash("/h filename"); + displayHash("/header filename"); displayHash("/iid filename"); displayHash("/lcid"); + displayHash("/mktyplib203"); displayHash("/ms_ext"); displayHash("/ms_union"); + displayHash("/msc_ver <nnnn>"); displayHash("/newtlb"); displayHash("/no_cpp"); + displayHash("/no_def_idir"); displayHash("/no_default_epv"); displayHash("/no_format_opt"); + displayHash("/no_warn"); displayHash("/nocpp"); displayHash("/nologo"); displayHash("/notlb"); + displayHash("/o filename"); displayHash("/oldnames"); displayHash("/oldtlb"); + displayHash("/osf"); displayHash("/out directory"); displayHash("/pack {N}"); + displayHash("/prefix all"); displayHash("/prefix client"); displayHash("/prefix server"); + displayHash("/prefix switch"); displayHash("/protocol all"); displayHash("/protocol dce"); + displayHash("/protocol ndr64"); displayHash("/proxy filename"); displayHash("/robust"); + displayHash("/rpcss"); displayHash("/savePP"); displayHash("/server none"); + displayHash("/server stub"); displayHash("/sstub filename"); displayHash("/syntax_check"); + displayHash("/target {system}"); displayHash("/tlb filename"); displayHash("/use_epv"); + displayHash("/win32"); displayHash("/win64"); +#endif + bool found = true; + int offset = 0; + switch(elfHash(option)) { + case 0x0000334: // /D name[=def] + PreprocessorDefinitions += option+3; + break; + case 0x0000339: // /I directory-list + AdditionalIncludeDirectories += option+3; + break; + case 0x0345f96: // /Oicf + case 0x00345f6: // /Oif + GenerateStublessProxies = _True; + break; + case 0x0000345: // /U name + UndefinePreprocessorDefinitions += option+3; + break; + case 0x00034c8: // /WX + WarnAsError = _True; + break; + case 0x3582fde: // /align {N} + offset = 3; // Fallthrough + case 0x0003510: // /Zp {N} + switch (*(option+offset+4)) { + case '1': + StructMemberAlignment = (*(option+offset+5) == '\0') ? "1" : "16"; + break; + case '2': + StructMemberAlignment = "2"; + break; + case '4': + StructMemberAlignment = "4"; + break; + case '8': + StructMemberAlignment = "8"; + break; + default: + found = false; + } + break; + case 0x5b1cb97: // /app_config + ApplicationConfigurationMode = _True; + break; + case 0x0359e82: // /char {ascii7|signed|unsigned} + switch(*(option+6)) { + case 'a': + DefaultCharType = "Ascii"; + break; + case 's': + DefaultCharType = "Signed"; + break; + case 'u': + DefaultCharType = "Unsigned"; + break; + default: + found = false; + } + break; + case 0x5a2fc64: // /client {none|stub} + if(*(option+8) == 's') + GenerateClientFiles = "Stub"; + else + GenerateClientFiles = "None"; + break; + case 0xa766524: // /cpp_opt options + CPreprocessOptions += option+9; + break; + case 0x35aabb2: // /cstub filename + ClientStubFile = option+7; + break; + case 0xb32abf1: // /dlldata filename + DLLDataFileName = option + 9; + break; + case 0x0035c56: // /env {win32|ia64|x64} + if(*(option+7) == 'w' && *(option+10) == '3') + TargetEnvironment = "Win32"; + else if(*(option+7) == 'i') + TargetEnvironment = "Itanium"; + else if(*(option+7) == 'x') + TargetEnvironment = "X64"; + else + AdditionalOptions += option; + break; + case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data} + EnableErrorChecks = midlEnableCustom; + switch (*(option+7)) { + case '\0': + EnableErrorChecks = "EnableCustom"; + break; + case 'a': + if(*(option+10) == '\0') + EnableErrorChecks = "All"; + else + ErrorCheckAllocations = _True; + break; + case 'b': + ErrorCheckBounds = _True; + break; + case 'e': + ErrorCheckEnumRange = _True; + break; + case 'n': + EnableErrorChecks = "None"; + break; + case 'r': + ErrorCheckRefPointers = _True; + break; + case 's': + ErrorCheckStubData = _True; + break; + default: + found = false; + } + break; + case 0x5eb7af2: // /header filename + offset = 5; + case 0x0000358: // /h filename + HeaderFileName = option + offset + 3; + break; + case 0x0035ff4: // /iid filename + InterfaceIdentifierFileName = option+5; + break; + case 0x64b7933: // /mktyplib203 + MkTypLibCompatible = _True; + break; + case 0x64ceb12: // /newtlb + TypeLibFormat = "NewFormat"; + break; + case 0x8e0b0a2: // /no_def_idir + IgnoreStandardIncludePath = _True; + break; + case 0x65635ef: // /nologo + SuppressStartupBanner = _True; + break; + case 0x695e9f4: // /no_robust + ValidateAllParameters = _False; + break; + case 0x3656b22: // /notlb + GenerateTypeLibrary = _True; + break; + case 0x556dbee: // /no_warn + SuppressCompilerWarnings = _True; + break; + case 0x000035f: // /o filename + RedirectOutputAndErrors = option+3; + break; + case 0x662bb12: // /oldtlb + TypeLibFormat = "OldFormat"; + break; + case 0x00366c4: // /out directory + OutputDirectory = option+5; + break; + case 0x36796f9: // /proxy filename + ProxyFileName = option+7; + break; + case 0x6959c94: // /robust + ValidateAllParameters = _True; + break; + case 0x69c9cf2: // /server {none|stub} + if(*(option+8) == 's') + GenerateServerFiles = "Stub"; + else + GenerateServerFiles = "None"; + break; + case 0x36aabb2: // /sstub filename + ServerStubFile = option+7; + break; + case 0x0036b22: // /tlb filename + TypeLibraryName = option+5; + break; + case 0x36e0162: // /win32 + TargetEnvironment = "Win32"; + break; + case 0x36e0194: // /win64 + TargetEnvironment = "Itanium"; + break; + case 0x0003459: // /Oi + case 0x00345f3: // /Oic + case 0x0003463: // /Os + case 0x0003513: // /Zs + case 0x0035796: // /acf filename + case 0x3595cf4: // /c_ext + case 0xa64d3dd: // /confirm + case 0xa765b64: // /cpp_cmd cmd_line + case 0x03629f4: // /lcid + case 0x6495cc4: // /ms_ext + case 0x96c7a1e: // /ms_union + case 0x4996fa2: // /msc_ver <nnnn> + case 0x6555a40: // /no_cpp + case 0xf64d6a6: // /no_default_epv + case 0x6dd9384: // /no_format_opt + case 0x3655a70: // /nocpp + case 0x2b455a3: // /oldnames + case 0x0036696: // /osf + case 0x036679b: // /pack {N} + case 0x678bd38: // /prefix {all|client|server|switch} + case 0x96b702c: // /protocol {all|dce|ndr64} + case 0x3696aa3: // /rpcss + case 0x698ca60: // /savePP + case 0xce9b12b: // /syntax_check + case 0xc9b5f16: // /use_epv + AdditionalOptions += option; + break; + default: + // /W{0|1|2|3|4} case + if(*(option+1) == 'W') { + switch (*(option+2)) { + case '0': + WarningLevel = "0"; + break; + case '1': + WarningLevel = "1"; + break; + case '2': + WarningLevel = "2"; + break; + case '3': + WarningLevel = "3"; + break; + case '4': + WarningLevel = "4"; + break; + default: + found = false; + } + } + break; + } + if(!found) + warn_msg(WarnLogic, "Could not parse MIDL option: %s", option); + return true; +} + +// VCLibrarianTool -------------------------------------------------- +VCXLibrarianTool::VCXLibrarianTool() + : IgnoreAllDefaultLibraries(unset), + LinkTimeCodeGeneration(unset), + SuppressStartupBanner(_True), + TreatLibWarningAsErrors(unset), + Verbose(unset) +{ +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXLibrarianTool &tool) +{ + return xml + << tag(_Link) + << attrTagX(_AdditionalDependencies, tool.AdditionalDependencies, ";") + << attrTagX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories, ";") + << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ") + << attrTagS(_DisplayLibrary, tool.DisplayLibrary) + << attrTagS(_ErrorReporting, tool.ErrorReporting) + << attrTagX(_ExportNamedFunctions, tool.ExportNamedFunctions, ";") + << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";") + << attrTagT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries) + << attrTagX(_IgnoreSpecificDefaultLibraries, tool.IgnoreSpecificDefaultLibraries, ";") + << attrTagT(_LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration) + << attrTagS(_ModuleDefinitionFile, tool.ModuleDefinitionFile) + << attrTagS(_Name, tool.Name) + << attrTagS(_OutputFile, tool.OutputFile) + << attrTagX(_RemoveObjects, tool.RemoveObjects, ";") + << attrTagS(_SubSystem, tool.SubSystem) + << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner) + << attrTagS(_TargetMachine, tool.TargetMachine) + << attrTagT(_TreatLibWarningAsErrors, tool.TreatLibWarningAsErrors) + << attrTagT(_Verbose, tool.Verbose) + << closetag(_Link); +} + +// VCCustomBuildTool ------------------------------------------------ +VCXCustomBuildTool::VCXCustomBuildTool() +{ + ToolName = "VCXCustomBuildTool"; +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXCustomBuildTool &tool) +{ + // The code below offers two ways to split custom build step commands. + // Normally the $$escape_expand(\n\t) is used in a project file, which is correctly translated + // in all generators. However, if you use $$escape_expand(\n\r) (or \n\h) instead, the VCPROJ + // generator will instead of binding the commands with " && " will insert a proper newline into + // the VCPROJ file. We sometimes use this method of splitting commands if the custom buildstep + // contains a command-line which is too big to run on certain OS. + QString cmds; + int end = tool.CommandLine.count(); + for(int i = 0; i < end; ++i) { + QString cmdl = tool.CommandLine.at(i); + if (cmdl.contains("\r\t")) { + if (i == end - 1) + cmdl = cmdl.trimmed(); + cmdl.replace("\r\t", " && "); + } else if (cmdl.contains("\r\n")) { + ; + } else if (cmdl.contains("\r\\h")) { + // The above \r\n should work, but doesn't, so we have this hack + cmdl.replace("\r\\h", "\r\n"); + } else { + if (i < end - 1) + cmdl += " && "; + } + cmds += cmdl; + } + + if ( !tool.AdditionalDependencies.isEmpty() ) + { + xml << tag("AdditionalInputs") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.ConfigName)) + << valueTagDefX(tool.AdditionalDependencies, "AdditionalInputs", ";"); + } + + if( !cmds.isEmpty() ) + { + xml << tag("Command") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.ConfigName)) + << valueTag(cmds); + } + + if ( !tool.Description.isEmpty() ) + { + xml << tag("Message") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.ConfigName)) + << valueTag(tool.Description); + } + + if ( !tool.Outputs.isEmpty() ) + { + xml << tag("Outputs") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.ConfigName)) + << valueTagDefX(tool.Outputs, "Outputs", ";"); + } + + return xml; +} + +// VCResourceCompilerTool ------------------------------------------- +VCXResourceCompilerTool::VCXResourceCompilerTool() + : IgnoreStandardIncludePath(unset), + NullTerminateStrings(unset), + ShowProgress(unset), + SuppressStartupBanner(unset) +{ + PreprocessorDefinitions = QStringList("NDEBUG"); +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXResourceCompilerTool &tool) +{ + return xml + << tag(_ResourceCompile) + << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";") + << attrTagS(_AdditionalOptions, tool.AdditionalOptions) + << attrTagS(_Culture, tool.Culture) + << attrTagT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath) + << attrTagT(_NullTerminateStrings, tool.NullTerminateStrings) + << attrTagX(_PreprocessorDefinitions, tool.PreprocessorDefinitions, ";") + << attrTagS(_ResourceOutputFileName, tool.ResourceOutputFileName) + << attrTagT(_ShowProgress, tool.ShowProgress) + << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner) + << attrTagS(_TrackerLogDirectory, tool.TrackerLogDirectory) + << attrTagS(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions) + << closetag(_ResourceCompile); +} + +// VCXDeploymentTool -------------------------------------------- +VCXDeploymentTool::VCXDeploymentTool() +{ + DeploymentTag = "DeploymentTool"; + RemoteDirectory = ""; +} + +// http://msdn.microsoft.com/en-us/library/sa69he4t.aspx +XmlOutput &operator<<(XmlOutput &xml, const VCXDeploymentTool &tool) +{ + if (tool.AdditionalFiles.isEmpty()) + return xml; + return xml + << tag(tool.DeploymentTag) + << closetag(tool.DeploymentTag); +} + +// VCEventTool ------------------------------------------------- +XmlOutput &operator<<(XmlOutput &xml, const VCXEventTool &tool) +{ + return xml + << tag(tool.EventName) + << attrTagS(_Command, tool.CommandLine) + << attrTagS(_Message, tool.Description) + << closetag(tool.EventName); +} + +// VCXPostBuildEventTool --------------------------------------------- +VCXPostBuildEventTool::VCXPostBuildEventTool() +{ + EventName = "PostBuildEvent"; +} + +// VCXPreBuildEventTool ---------------------------------------------- +VCXPreBuildEventTool::VCXPreBuildEventTool() +{ + EventName = "PreBuildEvent"; +} + +// VCXPreLinkEventTool ----------------------------------------------- +VCXPreLinkEventTool::VCXPreLinkEventTool() +{ + EventName = "PreLinkEvent"; +} + +// VCConfiguration -------------------------------------------------- + +VCXConfiguration::VCXConfiguration() + : ATLMinimizesCRunTimeLibraryUsage(unset), + BuildBrowserInformation(unset), + RegisterOutput(unset), + WholeProgramOptimization(unset) +{ + compiler.config = this; + linker.config = this; + idl.config = this; +} + +XmlOutput &operator<<(XmlOutput &xml, const VCXConfiguration &tool) +{ + xml << tag("PropertyGroup") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Name)) + << attrTag("Label", "Configuration") + << attrTagS(_OutputDirectory, tool.OutputDirectory) + << attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage) + << attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation) + << attrTagS(_CharacterSet, tool.CharacterSet) + << attrTagS(_ConfigurationType, tool.ConfigurationType) + << attrTagS(_DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean) + << attrTagS(_ImportLibrary, tool.ImportLibrary) + << attrTagS(_IntermediateDirectory, tool.IntermediateDirectory) + << attrTagS(_PrimaryOutput, tool.PrimaryOutput) + << attrTagS(_ProgramDatabase, tool.ProgramDatabase) + << attrTagT(_RegisterOutput, tool.RegisterOutput) + << attrTagS(_UseOfATL, tool.UseOfATL) + << attrTagS(_UseOfMfc, tool.UseOfMfc) + << attrTagT(_WholeProgramOptimization, tool.WholeProgramOptimization) + << closetag(); + return xml; +} +// VCXFilter --------------------------------------------------------- +VCXFilter::VCXFilter() + : ParseFiles(unset), + Config(0) +{ + useCustomBuildTool = false; + useCompilerTool = false; +} + +void VCXFilter::addFile(const QString& filename) +{ + Files += VCXFilterFile(filename); +} + +void VCXFilter::addFile(const VCXFilterFile& fileInfo) +{ + Files += VCXFilterFile(fileInfo); +} + +void VCXFilter::addFiles(const QStringList& fileList) +{ + for (int i = 0; i < fileList.count(); ++i) + addFile(fileList.at(i)); +} + +void VCXFilter::modifyPCHstage(QString str) +{ + bool autogenSourceFile = Project->autogenPrecompCPP; + bool pchThroughSourceFile = !Project->precompCPP.isEmpty(); + bool isCFile = false; + for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { + if (str.endsWith(*it)) { + isCFile = true; + break; + } + } + bool isHFile = str.endsWith(".h") && (str == Project->precompH); + bool isCPPFile = pchThroughSourceFile && (str == Project->precompCPP); + + if(!isCFile && !isHFile && !isCPPFile) + return; + + if(isHFile && pchThroughSourceFile) { + if (autogenSourceFile) { + useCustomBuildTool = true; + QString toFile(Project->precompCPP); + CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ..."; + CustomBuildTool.Outputs += toFile; + + QStringList lines; + CustomBuildTool.CommandLine += + "echo /*-------------------------------------------------------------------- >" + toFile; + lines << "* Precompiled header source file used by Visual Studio.NET to generate"; + lines << "* the .pch file."; + lines << "*"; + lines << "* Due to issues with the dependencies checker within the IDE, it"; + lines << "* sometimes fails to recompile the PCH file, if we force the IDE to"; + lines << "* create the PCH file directly from the header file."; + lines << "*"; + lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was"; + lines << "* specified, and is used as the common stdafx.cpp. The file is only"; + lines << "* generated when creating .vcxproj project files, and is not used for"; + lines << "* command line compilations by nmake."; + lines << "*"; + lines << "* WARNING: All changes made in this file will be lost."; + lines << "--------------------------------------------------------------------*/"; + lines << "#include \"" + Project->precompHFilename + "\""; + foreach(QString line, lines) + CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile; + } + return; + } + + useCompilerTool = true; + // Setup PCH options + CompilerTool.PrecompiledHeader = (isCFile ? "NotUsing" : "Create" ); + CompilerTool.PrecompiledHeaderFile = (isCPPFile ? QString("$(INHERIT)") : QString("$(NOINHERIT)")); + CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); +} + +bool VCXFilter::addExtraCompiler(const VCXFilterFile &info) +{ + const QStringList &extraCompilers = Project->extraCompilerSources.value(info.file); + if (extraCompilers.isEmpty()) + return false; + + QString inFile = info.file; + + // is the extracompiler rule on a file with a built in compiler? + const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile]; + bool hasBuiltIn = false; + if (!objectMappedFile.isEmpty()) { + hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0)); +// qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(" "))); + } + + CustomBuildTool.AdditionalDependencies.clear(); + CustomBuildTool.CommandLine.clear(); + CustomBuildTool.Description.clear(); + CustomBuildTool.Outputs.clear(); + CustomBuildTool.ToolPath.clear(); + CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool); + + for (int x = 0; x < extraCompilers.count(); ++x) { + const QString &extraCompilerName = extraCompilers.at(x); + + if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn) + continue; + + // All information about the extra compiler + QString tmp_out = Project->project->first(extraCompilerName + ".output"); + QString tmp_cmd = Project->project->variables()[extraCompilerName + ".commands"].join(" "); + QString tmp_cmd_name = Project->project->variables()[extraCompilerName + ".name"].join(" "); + QStringList tmp_dep = Project->project->variables()[extraCompilerName + ".depends"]; + QString tmp_dep_cmd = Project->project->variables()[extraCompilerName + ".depend_command"].join(" "); + QStringList vars = Project->project->variables()[extraCompilerName + ".variables"]; + QStringList configs = Project->project->variables()[extraCompilerName + ".CONFIG"]; + bool combined = configs.indexOf("combine") != -1; + + QString cmd, cmd_name, out; + QStringList deps, inputs; + // Variabel replacement of output name + out = Option::fixPathToTargetOS( + Project->replaceExtraCompilerVariables(tmp_out, inFile, QString()), + false); + + // If file has built-in compiler, we've swapped the input and output of + // the command, as we in Visual Studio cannot have a Custom Buildstep on + // a file which uses a built-in compiler. We would in this case only get + // the result from the extra compiler. If 'hasBuiltIn' is true, we know + // that we're actually on the _output_file_ of the result, and we + // therefore swap inFile and out below, since the extra-compiler still + // must see it as the original way. If the result also has a built-in + // compiler, too bad.. + if (hasBuiltIn) { + out = inFile; + inFile = objectMappedFile.at(0); + } + + // Dependency for the output + if(!tmp_dep.isEmpty()) + deps = tmp_dep; + if(!tmp_dep_cmd.isEmpty()) { + // Execute dependency command, and add every line as a dep + char buff[256]; + QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd, Option::fixPathToLocalOS(inFile, true, false), out); + if(Project->canExecute(dep_cmd)) { + if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) { + QString indeps; + while(!feof(proc)) { + int read_in = (int)fread(buff, 1, 255, proc); + if(!read_in) + break; + indeps += QByteArray(buff, read_in); + } + QT_PCLOSE(proc); + if(!indeps.isEmpty()) { + QStringList extradeps = indeps.split(QLatin1Char('\n')); + for (int i = 0; i < extradeps.count(); ++i) { + QString dd = extradeps.at(i).simplified(); + if (!dd.isEmpty()) + deps += Project->fileFixify(dd); + } + } + } + } + } + for (int i = 0; i < deps.count(); ++i) + deps[i] = Option::fixPathToTargetOS( + Project->replaceExtraCompilerVariables(deps.at(i), inFile, out), + false).trimmed(); + // Command for file + if (combined) { + // Add dependencies for each file + QStringList tmp_in = Project->project->variables()[extraCompilerName + ".input"]; + for (int a = 0; a < tmp_in.count(); ++a) { + const QStringList &files = Project->project->variables()[tmp_in.at(a)]; + for (int b = 0; b < files.count(); ++b) { + deps += Project->findDependencies(files.at(b)); + inputs += Option::fixPathToTargetOS(files.at(b), false); + } + } + deps += inputs; // input files themselves too.. + + // Replace variables for command w/all input files + // ### join gives path issues with directories containing spaces! + cmd = Project->replaceExtraCompilerVariables(tmp_cmd, + inputs.join(" "), + out); + } else { + deps += inFile; // input file itself too.. + cmd = Project->replaceExtraCompilerVariables(tmp_cmd, + inFile, + out); + } + // Name for command + if(!tmp_cmd_name.isEmpty()) { + cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out); + } else { + int space = cmd.indexOf(' '); + if(space != -1) + cmd_name = cmd.left(space); + else + cmd_name = cmd; + if((cmd_name[0] == '\'' || cmd_name[0] == '"') && + cmd_name[0] == cmd_name[cmd_name.length()-1]) + cmd_name = cmd_name.mid(1,cmd_name.length()-2); + } + + // Fixify paths + for (int i = 0; i < deps.count(); ++i) + deps[i] = Option::fixPathToTargetOS(deps[i], false); + + + // Output in info.additionalFile ----------- + if (!CustomBuildTool.Description.isEmpty()) + CustomBuildTool.Description += " & "; + CustomBuildTool.Description += cmd_name; + CustomBuildTool.CommandLine += cmd.trimmed().split("\n", QString::SkipEmptyParts); + int space = cmd.indexOf(' '); + QFileInfo finf(cmd.left(space)); + if (CustomBuildTool.ToolPath.isEmpty()) + CustomBuildTool.ToolPath += Option::fixPathToTargetOS(finf.path()); + CustomBuildTool.Outputs += out; + + deps += CustomBuildTool.AdditionalDependencies; + deps += cmd.left(cmd.indexOf(' ')); + // Make sure that all deps are only once + QMap<QString, bool> uniqDeps; + for (int c = 0; c < deps.count(); ++c) { + QString aDep = deps.at(c).trimmed(); + if (!aDep.isEmpty()) + uniqDeps[aDep] = false; + } + CustomBuildTool.AdditionalDependencies = uniqDeps.keys(); + } + + // Ensure that none of the output files are also dependencies. Or else, the custom buildstep + // will be rebuild every time, even if nothing has changed. + foreach(QString output, CustomBuildTool.Outputs) { + CustomBuildTool.AdditionalDependencies.removeAll(output); + } + + useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty(); + return useCustomBuildTool; +} + +bool VCXFilter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded) +{ + bool fileAdded = false; + + // Clearing each filter tool + useCustomBuildTool = false; + useCompilerTool = false; + CustomBuildTool = VCXCustomBuildTool(); + CompilerTool = VCXCLCompilerTool(); + + // Unset some default options + CompilerTool.BufferSecurityCheck = unset; + CompilerTool.DebugInformationFormat = ""; + CompilerTool.ExceptionHandling = ""; + //CompilerTool.Optimization = optimizeDefault; + CompilerTool.ProgramDataBaseFileName.clear(); + CompilerTool.RuntimeLibrary = ""; + //CompilerTool.WarningLevel = warningLevelUnknown; + CompilerTool.config = Config; + + bool inBuild = false; + VCXFilterFile info; + for (int i = 0; i < Files.count(); ++i) { + if (Files.at(i).file == filename) { + info = Files.at(i); + inBuild = true; + } + } + inBuild &= !info.excludeFromBuild; + + if (inBuild) { + addExtraCompiler(info); + if(Project->usePCH) + modifyPCHstage(info.file); + } else { + // Excluded files uses an empty compiler stage + if(info.excludeFromBuild) + useCompilerTool = true; + } + + // Actual XML output ---------------------------------- + if(useCustomBuildTool || useCompilerTool || !inBuild) { + + if (useCustomBuildTool) + { + CustomBuildTool.ConfigName = (*Config).Name; + + if ( !fileAllreadyAdded ) { + + fileAdded = true; + + xmlFilter << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + + if ( filtername == "Form Files" || filtername == "Generated Files" || filtername == "Resource Files" ) + xml << attrTagS("FileType", "Document"); + } + + xml << CustomBuildTool; + } + + if ( !fileAdded && !fileAllreadyAdded ) + { + fileAdded = true; + + if (filtername == "Source Files") { + + xmlFilter << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + + } else if(filtername == "Header Files") { + + xmlFilter << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + } else if(filtername == "Generated Files" || filtername == "Form Files") { + + if (filename.endsWith(".h")) { + + xmlFilter << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + } else if(filename.endsWith(".cpp")) { + + xmlFilter << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + } else { + + xmlFilter << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(filename)) + << attrTagS("Filter", filtername); + + xml << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(filename)); + } + } + } + + if(!inBuild) { + + xml << tag("ExcludedFromBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg((*Config).Name)) + << valueTag("true"); + } + + if (useCompilerTool) { + + if ( !CompilerTool.ForcedIncludeFiles.isEmpty() ) { + xml << tag("ForcedIncludeFiles") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg((*Config).Name)) + << valueTagX(CompilerTool.ForcedIncludeFiles); + } + + if ( !CompilerTool.PrecompiledHeaderFile.isEmpty() ) { + + xml << tag("PrecompiledHeaderFile") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg((*Config).Name)) + << valueTag(CompilerTool.PrecompiledHeaderFile); + } + + if ( !CompilerTool.PrecompiledHeader.isEmpty() ) { + + xml << tag("PrecompiledHeader") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg((*Config).Name)) + << valueTag(CompilerTool.PrecompiledHeader); + } + + //xml << CompilerTool; + } + } + + return fileAdded; +} + + +// VCXProjectSingleConfig -------------------------------------------- +VCXFilter nullFilter; +VCXFilter& VCXProjectSingleConfig::filterForExtraCompiler(const QString &compilerName) +{ + for (int i = 0; i < ExtraCompilersFiles.count(); ++i) + if (ExtraCompilersFiles.at(i).Name == compilerName) + return ExtraCompilersFiles[i]; + return nullFilter; +} + + +XmlOutput &operator<<(XmlOutput &xml, const VCXProjectSingleConfig &tool) +{ + xml.setIndentString(" "); + + xml << decl("1.0", "utf-8") + << tag("Project") + << attrTag("DefaultTargets","Build") + << attrTag("ToolsVersion", "4.0") + << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") + << tag("ItemGroup") + << attrTag("Label", "ProjectConfigurations"); + + xml << tag("ProjectConfiguration") + << attrTag("Include" , tool.Configuration.Name) + << tagValue("Configuration", tool.Configuration.ConfigurationName) + << tagValue("Platform", tool.PlatformName) + << closetag(); + + xml << closetag() + << tag("PropertyGroup") + << attrTag("Label", "Globals") + << tagValue("ProjectGuid", tool.ProjectGUID) + << tagValue("RootNamespace", tool.Name) + << tagValue("Keyword", tool.Keyword) + << closetag(); + + // config part. + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); + + xml << tool.Configuration; + + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); + + // Extension settings + xml << tag("ImportGroup") + << attrTag("Label", "ExtensionSettings") + << closetag(); + + // PropertySheets + xml << tag("ImportGroup") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << attrTag("Label", "PropertySheets"); + + xml << tag("Import") + << attrTag("Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props") + << attrTag("Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')") + << closetag() + << closetag(); + + + // UserMacros + xml << tag("PropertyGroup") + << attrTag("Label", "UserMacros") + << closetag(); + + xml << tag("PropertyGroup"); + + if ( !tool.Configuration.OutputDirectory.isEmpty() ) { + xml<< tag("OutDir") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTag(tool.Configuration.OutputDirectory); + } + if ( !tool.Configuration.IntermediateDirectory.isEmpty() ) { + xml<< tag("IntDir") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTag(tool.Configuration.IntermediateDirectory); + } + if ( !tool.Configuration.TargetName.isEmpty() ) { + xml<< tag("TargetName") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTag(tool.Configuration.TargetName); + } + + if ( tool.Configuration.linker.IgnoreImportLibrary != unset) { + xml<< tag("IgnoreImportLibrary") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTagT(tool.Configuration.linker.IgnoreImportLibrary); + } + + if ( tool.Configuration.linker.LinkIncremental != unset) { + xml<< tag("LinkIncremental") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTagT(tool.Configuration.linker.LinkIncremental); + } + + if ( tool.Configuration.preBuild.UseInBuild != unset ) + { + xml<< tag("PreBuildEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTagT(tool.Configuration.preBuild.UseInBuild); + } + + if ( tool.Configuration.preLink.UseInBuild != unset ) + { + xml<< tag("PreLinkEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTagT(tool.Configuration.preLink.UseInBuild); + } + + if ( tool.Configuration.postBuild.UseInBuild != unset ) + { + xml<< tag("PostBuildEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)) + << valueTagT(tool.Configuration.postBuild.UseInBuild); + } + xml << closetag(); + + xml << tag("ItemDefinitionGroup") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.Configuration.Name)); + + // ClCompile + xml << tool.Configuration.compiler; + + // Link + xml << tool.Configuration.linker; + + // Midl + xml << tool.Configuration.idl; + + // ResourceCompiler + xml << tool.Configuration.resource; + + xml << closetag(); + + QFile filterFile; + filterFile.setFileName(Option::output.fileName().append(".filters")); + filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + QTextStream ts(&filterFile); + XmlOutput xmlFilter(ts, XmlOutput::NoConversion); + + xmlFilter.setIndentString(" "); + + xmlFilter << decl("1.0", "utf-8") + << tag("Project") + << attrTag("ToolsVersion", "4.0") + << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); + + xmlFilter << tag("ItemGroup"); + + VCXProject tempProj; + tempProj.SingleProjects += tool; + + tempProj.addFilters(xmlFilter, "Form Files"); + tempProj.addFilters(xmlFilter, "Generated Files"); + tempProj.addFilters(xmlFilter, "Header Files"); + tempProj.addFilters(xmlFilter, "LexYacc Files"); + tempProj.addFilters(xmlFilter, "Resource Files"); + tempProj.addFilters(xmlFilter, "Source Files"); + tempProj.addFilters(xmlFilter, "Translation Files"); + xmlFilter << closetag(); + + tempProj.outputFilter(xml, xmlFilter, "Source Files"); + tempProj.outputFilter(xml, xmlFilter, "Header Files"); + tempProj.outputFilter(xml, xmlFilter, "Generated Files"); + tempProj.outputFilter(xml, xmlFilter, "LexYacc Files"); + tempProj.outputFilter(xml, xmlFilter, "Translation Files"); + tempProj.outputFilter(xml, xmlFilter, "Form Files"); + tempProj.outputFilter(xml, xmlFilter, "Resource Files"); + + for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) { + tempProj.outputFilter(xml, xmlFilter, tempProj.ExtraCompilers.at(x)); + } + + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); + + xml << tag("ImportGroup") + << attrTag("Label", "ExtensionTargets") + << closetag(); + + return xml; +} + + +// Tree file generation --------------------------------------------- +void XTreeNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCXProject &tool, const QString &filter) { + + if (children.size()) { + // Filter + ChildrenMap::ConstIterator it, end = children.constEnd(); + if (!tagName.isEmpty()) { + xmlFilter << tag("Filter") + << attrTag("Include", tagName) + << attrTagS("Extensions", ""); + } + // First round, do nested filters + for (it = children.constBegin(); it != end; ++it) + if ((*it)->children.size()) + (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); + // Second round, do leafs + for (it = children.constBegin(); it != end; ++it) + if (!(*it)->children.size()) + (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter); + + if (!tagName.isEmpty()) + xml << closetag("Filter"); + } else { + // Leaf + tool.outputFileConfigs(xml, xmlFilter, info, filter); + } +} + + +// Flat file generation --------------------------------------------- +void XFlatNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &/*tagName*/, VCXProject &tool, const QString &filter) { + if (children.size()) { + ChildrenMapFlat::ConstIterator it = children.constBegin(); + ChildrenMapFlat::ConstIterator end = children.constEnd(); + xml << tag(_ItemGroup); + xmlFilter << tag(_ItemGroup); + for (; it != end; ++it) { + tool.outputFileConfigs(xml, xmlFilter, (*it), filter); + } + xml << closetag(); + xmlFilter << closetag(); + } +} + + +// VCXProject -------------------------------------------------------- +// Output all configurations (by filtername) for a file (by info) +// A filters config output is in VCXFilter.outputFileConfig() +void VCXProject::outputFileConfigs(XmlOutput &xml, + XmlOutput &xmlFilter, + const VCXFilterFile &info, + const QString &filtername) +{ + // We need to check if the file has any custom build step. + // If there is one then it has to be included with "CustomBuild Include" + bool fileAdded = false; + + for (int i = 0; i < SingleProjects.count(); ++i) { + VCXFilter filter; + if (filtername == "Root Files") { + filter = SingleProjects.at(i).RootFiles; + } else if (filtername == "Source Files") { + filter = SingleProjects.at(i).SourceFiles; + } else if (filtername == "Header Files") { + filter = SingleProjects.at(i).HeaderFiles; + } else if (filtername == "Generated Files") { + filter = SingleProjects.at(i).GeneratedFiles; + } else if (filtername == "LexYacc Files") { + filter = SingleProjects.at(i).LexYaccFiles; + } else if (filtername == "Translation Files") { + filter = SingleProjects.at(i).TranslationFiles; + } else if (filtername == "Form Files") { + filter = SingleProjects.at(i).FormFiles; + } else if (filtername == "Resource Files") { + filter = SingleProjects.at(i).ResourceFiles; + } else { + // ExtraCompilers + filter = SingleProjects[i].filterForExtraCompiler(filtername); + } + + if (filter.Config) // only if the filter is not empty + if (filter.outputFileConfig(xml, xmlFilter, info.file, filtername, fileAdded)) // only add it once. + fileAdded = true; + } + + if ( !fileAdded ) + { + if (filtername == "Source Files") { + + xmlFilter << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + + } else if(filtername == "Header Files") { + + xmlFilter << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + } else if(filtername == "Generated Files" || filtername == "Form Files") { + + if (info.file.endsWith(".h")) { + + xmlFilter << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("ClInclude") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + } else if(info.file.endsWith(".cpp")) { + + xmlFilter << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("ClCompile") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + } else { + + xmlFilter << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("CustomBuild") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + } + + } else { + + xmlFilter << tag("None") + << attrTag("Include",Option::fixPathToLocalOS(info.file)) + << attrTagS("Filter", filtername); + + xml << tag("None") + << attrTag("Include",Option::fixPathToLocalOS(info.file)); + } + } + + xml << closetag(); + xmlFilter << closetag(); +} + +// outputs a given filter for all existing configurations of a project +void VCXProject::outputFilter(XmlOutput &xml, + XmlOutput &xmlFilter, + const QString &filtername) +{ + XNode *root; + if (SingleProjects.at(0).flat_files) + root = new XFlatNode; + else + root = new XTreeNode; + + QString name, extfilter; + triState parse; + + for (int i = 0; i < SingleProjects.count(); ++i) { + VCXFilter filter; + if (filtername == "Root Files") { + filter = SingleProjects.at(i).RootFiles; + } else if (filtername == "Source Files") { + filter = SingleProjects.at(i).SourceFiles; + } else if (filtername == "Header Files") { + filter = SingleProjects.at(i).HeaderFiles; + } else if (filtername == "Generated Files") { + filter = SingleProjects.at(i).GeneratedFiles; + } else if (filtername == "LexYacc Files") { + filter = SingleProjects.at(i).LexYaccFiles; + } else if (filtername == "Translation Files") { + filter = SingleProjects.at(i).TranslationFiles; + } else if (filtername == "Form Files") { + filter = SingleProjects.at(i).FormFiles; + } else if (filtername == "Resource Files") { + filter = SingleProjects.at(i).ResourceFiles; + } else { + // ExtraCompilers + filter = SingleProjects[i].filterForExtraCompiler(filtername); + } + + // Merge all files in this filter to root tree + for (int x = 0; x < filter.Files.count(); ++x) + root->addElement(filter.Files.at(x)); + + // Save filter setting from first filter. Next filters + // may differ but we cannot handle that. (ex. extfilter) + if (name.isEmpty()) { + name = filter.Name; + extfilter = filter.Filter; + parse = filter.ParseFiles; + } + } + + if (!root->hasElements()) + return; + + root->generateXML(xml, xmlFilter, "", *this, filtername); // output root tree +} + + +void VCXProject::addFilters(XmlOutput &xmlFilter, + const QString &filtername) +{ + bool added = false; + + for (int i = 0; i < SingleProjects.count(); ++i) { + VCXFilter filter; + if (filtername == "Root Files") { + filter = SingleProjects.at(i).RootFiles; + } else if (filtername == "Source Files") { + filter = SingleProjects.at(i).SourceFiles; + } else if (filtername == "Header Files") { + filter = SingleProjects.at(i).HeaderFiles; + } else if (filtername == "Generated Files") { + filter = SingleProjects.at(i).GeneratedFiles; + } else if (filtername == "LexYacc Files") { + filter = SingleProjects.at(i).LexYaccFiles; + } else if (filtername == "Translation Files") { + filter = SingleProjects.at(i).TranslationFiles; + } else if (filtername == "Form Files") { + filter = SingleProjects.at(i).FormFiles; + } else if (filtername == "Resource Files") { + filter = SingleProjects.at(i).ResourceFiles; + } else { + // ExtraCompilers + filter = SingleProjects[i].filterForExtraCompiler(filtername); + } + + if(!filter.Files.isEmpty() && !added) { + added = true; + xmlFilter << tag("Filter") + << attrTag("Include", filtername) + << attrTagS("UniqueIdentifier", filter.Guid) + << attrTagS("Extensions", filter.Filter) + << attrTagT("ParseFiles", filter.ParseFiles) + << closetag(); + } + } +} + + +XmlOutput &operator<<(XmlOutput &xml, VCXProject &tool) +{ + + if (tool.SingleProjects.count() == 0) { + warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output"); + return xml; + } + + xml.setIndentString(" "); + + xml << decl("1.0", "utf-8") + << tag("Project") + << attrTag("DefaultTargets","Build") + << attrTag("ToolsVersion", "4.0") + << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") + << tag("ItemGroup") + << attrTag("Label", "ProjectConfigurations"); + + for (int i = 0; i < tool.SingleProjects.count(); ++i) { + xml << tag("ProjectConfiguration") + << attrTag("Include" , tool.SingleProjects.at(i).Configuration.Name) + << tagValue("Configuration", tool.SingleProjects.at(i).Configuration.ConfigurationName) + << tagValue("Platform", tool.SingleProjects.at(i).PlatformName) + << closetag(); + } + + xml << closetag() + << tag("PropertyGroup") + << attrTag("Label", "Globals") + << tagValue("ProjectGuid", tool.ProjectGUID) + << tagValue("RootNamespace", tool.Name) + << tagValue("Keyword", tool.Keyword) + << closetag(); + + // config part. + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); + for (int i = 0; i < tool.SingleProjects.count(); ++i) + xml << tool.SingleProjects.at(i).Configuration; + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); + + // Extension settings + xml << tag("ImportGroup") + << attrTag("Label", "ExtensionSettings") + << closetag(); + + // PropertySheets + for (int i = 0; i < tool.SingleProjects.count(); ++i) { + xml << tag("ImportGroup") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << attrTag("Label", "PropertySheets"); + + xml << tag("Import") + << attrTag("Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props") + << attrTag("Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')") + << closetag() + << closetag(); + } + + // UserMacros + xml << tag("PropertyGroup") + << attrTag("Label", "UserMacros") + << closetag(); + + xml << tag("PropertyGroup"); + for (int i = 0; i < tool.SingleProjects.count(); ++i) { + + if ( !tool.SingleProjects.at(i).Configuration.OutputDirectory.isEmpty() ) { + xml << tag("OutDir") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTag(tool.SingleProjects.at(i).Configuration.OutputDirectory); + } + if ( !tool.SingleProjects.at(i).Configuration.IntermediateDirectory.isEmpty() ) { + xml << tag("IntDir") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTag(tool.SingleProjects.at(i).Configuration.IntermediateDirectory); + } + if ( !tool.SingleProjects.at(i).Configuration.TargetName.isEmpty() ) { + xml << tag("TargetName") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTag(tool.SingleProjects.at(i).Configuration.TargetName); + } + + if ( tool.SingleProjects.at(i).Configuration.linker.IgnoreImportLibrary != unset) { + xml << tag("IgnoreImportLibrary") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTagT(tool.SingleProjects.at(i).Configuration.linker.IgnoreImportLibrary); + } + + if ( tool.SingleProjects.at(i).Configuration.linker.LinkIncremental != unset) { + xml << tag("LinkIncremental") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTagT(tool.SingleProjects.at(i).Configuration.linker.LinkIncremental); + } + + if ( tool.SingleProjects.at(i).Configuration.preBuild.UseInBuild != unset ) + { + xml << tag("PreBuildEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTagT(tool.SingleProjects.at(i).Configuration.preBuild.UseInBuild); + } + + if ( tool.SingleProjects.at(i).Configuration.preLink.UseInBuild != unset ) + { + xml << tag("PreLinkEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTagT(tool.SingleProjects.at(i).Configuration.preLink.UseInBuild); + } + + if ( tool.SingleProjects.at(i).Configuration.postBuild.UseInBuild != unset ) + { + xml << tag("PostBuildEventUseInBuild") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)) + << valueTagT(tool.SingleProjects.at(i).Configuration.postBuild.UseInBuild); + } + } + xml << closetag(); + + for (int i = 0; i < tool.SingleProjects.count(); ++i) { + xml << tag("ItemDefinitionGroup") + << attrTag("Condition", QString("'$(Configuration)|$(Platform)'=='%1'").arg(tool.SingleProjects.at(i).Configuration.Name)); + + // ClCompile + xml << tool.SingleProjects.at(i).Configuration.compiler; + + // Link + xml << tool.SingleProjects.at(i).Configuration.linker; + + // Midl + xml << tool.SingleProjects.at(i).Configuration.idl; + + // ResourceCompiler + xml << tool.SingleProjects.at(i).Configuration.resource; + + xml << closetag(); + } + + // The file filters are added in a separate file for MSBUILD. + QFile filterFile; + filterFile.setFileName(Option::output.fileName().append(".filters")); + filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + QTextStream ts(&filterFile); + XmlOutput xmlFilter(ts, XmlOutput::NoConversion); + + xmlFilter.setIndentString(" "); + + xmlFilter << decl("1.0", "utf-8") + << tag("Project") + << attrTag("ToolsVersion", "4.0") + << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); + + xmlFilter << tag("ItemGroup"); + + tool.addFilters(xmlFilter, "Form Files"); + tool.addFilters(xmlFilter, "Generated Files"); + tool.addFilters(xmlFilter, "Header Files"); + tool.addFilters(xmlFilter, "LexYacc Files"); + tool.addFilters(xmlFilter, "Resource Files"); + tool.addFilters(xmlFilter, "Source Files"); + tool.addFilters(xmlFilter, "Translation Files"); + xmlFilter << closetag(); + + tool.outputFilter(xml, xmlFilter, "Source Files"); + tool.outputFilter(xml, xmlFilter, "Header Files"); + tool.outputFilter(xml, xmlFilter, "Generated Files"); + tool.outputFilter(xml, xmlFilter, "LexYacc Files"); + tool.outputFilter(xml, xmlFilter, "Translation Files"); + tool.outputFilter(xml, xmlFilter, "Form Files"); + tool.outputFilter(xml, xmlFilter, "Resource Files"); + for (int x = 0; x < tool.ExtraCompilers.count(); ++x) { + tool.outputFilter(xml, xmlFilter, tool.ExtraCompilers.at(x)); + } + + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); + + xml << tag("ImportGroup") + << attrTag("Label", "ExtensionTargets") + << closetag(); + + return xml; +} + +QT_END_NAMESPACE diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h new file mode 100644 index 0000000..567985d --- /dev/null +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -0,0 +1,708 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MSBUILD_OBJECTMODEL_H +#define MSBUILD_OBJECTMODEL_H + +#include "project.h" +#include "xmloutput.h" +#include "msvc_objectmodel.h" +#include <qatomic.h> +#include <qlist.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qdebug.h> + +QT_BEGIN_NAMESPACE + + +class VCXConfiguration; +class VCXProject; + +class VCXCLCompilerTool : public VCToolBase +{ +public: + // Functions + VCXCLCompilerTool(); + virtual ~VCXCLCompilerTool(){} + bool parseOption(const char* option); + + // Variables + QStringList AdditionalIncludeDirectories; + QStringList AdditionalOptions; + QStringList AdditionalUsingDirectories; + QString AlwaysAppend; + QString AssemblerListingLocation; + QString AssemblerOutput; + QString BasicRuntimeChecks; + triState BrowseInformation; + QString BrowseInformationFile; + triState BufferSecurityCheck; + QString CallingConvention; + QString CompileAs; + QString CompileAsManaged; + triState CreateHotpatchableImage; + QString DebugInformationFormat; + triState DisableLanguageExtensions; + QStringList DisableSpecificWarnings; + QString EnableEnhancedInstructionSet; + triState EnableFiberSafeOptimizations; + triState EnablePREfast; + QString ErrorReporting; + QString ExceptionHandling; + triState ExpandAttributedSource; + QString FavorSizeOrSpeed; + triState FloatingPointExceptions; + QString FloatingPointModel; + triState ForceConformanceInForLoopScope; + QStringList ForcedIncludeFiles; + QStringList ForcedUsingFiles; + triState FunctionLevelLinking; + triState GenerateXMLDocumentationFiles; + triState IgnoreStandardIncludePath; + QString InlineFunctionExpansion; + triState IntrinsicFunctions; + triState MinimalRebuild; + triState MultiProcessorCompilation; + QString ObjectFileName; + QStringList ObjectFiles; + triState OmitDefaultLibName; + triState OmitFramePointers; + triState OpenMPSupport; + QString Optimization; + QString PrecompiledHeader; + QString PrecompiledHeaderFile; + QString PrecompiledHeaderOutputFile; + triState PreprocessKeepComments; + QStringList PreprocessorDefinitions; + QString PreprocessOutputPath; + triState PreprocessSuppressLineNumbers; + triState PreprocessToFile; + QString ProgramDataBaseFileName; + QString ProcessorNumber; + QString RuntimeLibrary; + triState RuntimeTypeInfo; + triState ShowIncludes; + triState SmallerTypeCheck; + triState StringPooling; + QString StructMemberAlignment; + triState SuppressStartupBanner; + QString TreatSpecificWarningsAsErrors; + triState TreatWarningAsError; + triState TreatWChar_tAsBuiltInType; + triState UndefineAllPreprocessorDefinitions; + QStringList UndefinePreprocessorDefinitions; + triState UseFullPaths; + triState UseUnicodeForAssemblerListing; + QString WarningLevel; + triState WholeProgramOptimization; + QString XMLDocumentationFileName; + + VCXConfiguration* config; +}; + +class VCXLinkerTool : public VCToolBase +{ +public: + // Functions + VCXLinkerTool(); + virtual ~VCXLinkerTool(){} + bool parseOption(const char* option); + + // Variables + QStringList AdditionalDependencies; + QStringList AdditionalLibraryDirectories; + QStringList AdditionalManifestDependencies; + QStringList AdditionalOptions; + QStringList AddModuleNamesToAssembly; + triState AllowIsolation; + triState AssemblyDebug; + QStringList AssemblyLinkResource; + QString BaseAddress; + QString CLRImageType; + QString CLRSupportLastError; + QString CLRThreadAttribute; + QString CLRUnmanagedCodeCheck; + QString CreateHotPatchableImage; + triState DataExecutionPrevention; + QStringList DelayLoadDLLs; + triState DelaySign; + QString Driver; + QStringList EmbedManagedResourceFile; + triState EnableCOMDATFolding; + triState EnableUAC; + QString EntryPointSymbol; + triState FixedBaseAddress; + QString ForceFileOutput; + QStringList ForceSymbolReferences; + QString FunctionOrder; + triState GenerateDebugInformation; + triState GenerateManifest; + triState GenerateMapFile; + qlonglong HeapCommitSize; + qlonglong HeapReserveSize; + triState IgnoreAllDefaultLibraries; + triState IgnoreEmbeddedIDL; + triState IgnoreImportLibrary; + QStringList IgnoreSpecificDefaultLibraries; + triState ImageHasSafeExceptionHandlers; + QString ImportLibrary; + QString KeyContainer; + QString KeyFile; + triState LargeAddressAware; + triState LinkDLL; + QString LinkErrorReporting; + triState LinkIncremental; + triState LinkStatus; + QString LinkTimeCodeGeneration; + QString ManifestFile; + triState MapExports; + QString MapFileName; + QString MergedIDLBaseFileName; + QString MergeSections; + QString MidlCommandFile; + QString ModuleDefinitionFile; + QString MSDOSStubFileName; + triState NoEntryPoint; + triState OptimizeReferences; + QString OutputFile; + triState PreventDllBinding; + QString Profile; + QString ProfileGuidedDatabase; + QString ProgramDatabaseFile; + triState RandomizedBaseAddress; + triState RegisterOutput; + qlonglong SectionAlignment; + triState SetChecksum; + QString ShowProgress; + QString SpecifySectionAttributes; + QString StackCommitSize; + QString StackReserveSize; + QString StripPrivateSymbols; + QString SubSystem; + triState SupportNobindOfDelayLoadedDLL; + triState SupportUnloadOfDelayLoadedDLL; + triState SuppressStartupBanner; + triState SwapRunFromCD; + triState SwapRunFromNet; + QString TargetMachine; + triState TerminalServerAware; + triState TreatLinkerWarningAsErrors; + triState TurnOffAssemblyGeneration; + QString TypeLibraryFile; + qlonglong TypeLibraryResourceID; + QString UACExecutionLevel; + triState UACUIAccess; + QString Version; + + + VCXConfiguration* config; +}; + +class VCXMIDLTool : public VCToolBase +{ +public: + // Functions + VCXMIDLTool(); + virtual ~VCXMIDLTool(){} + bool parseOption(const char* option); + + // Variables + QStringList AdditionalIncludeDirectories; + QStringList AdditionalOptions; + triState ApplicationConfigurationMode; + QString ClientStubFile; + QString CPreprocessOptions; + QString DefaultCharType; + QString DLLDataFileName; + QString EnableErrorChecks; + triState ErrorCheckAllocations; + triState ErrorCheckBounds; + triState ErrorCheckEnumRange; + triState ErrorCheckRefPointers; + triState ErrorCheckStubData; + QString GenerateClientFiles; + QString GenerateServerFiles; + triState GenerateStublessProxies; + triState GenerateTypeLibrary; + QString HeaderFileName; + triState IgnoreStandardIncludePath; + QString InterfaceIdentifierFileName; + qlonglong LocaleID; + triState MkTypLibCompatible; + QString OutputDirectory; + QStringList PreprocessorDefinitions; + QString ProxyFileName; + QString RedirectOutputAndErrors; + QString ServerStubFile; + QString StructMemberAlignment; + triState SuppressCompilerWarnings; + triState SuppressStartupBanner; + QString TargetEnvironment; + QString TypeLibFormat; + QString TypeLibraryName; + QStringList UndefinePreprocessorDefinitions; + triState ValidateAllParameters; + triState WarnAsError; + QString WarningLevel; + + VCXConfiguration* config; +}; + +class VCXLibrarianTool : public VCToolBase +{ +public: + // Functions + VCXLibrarianTool(); + virtual ~VCXLibrarianTool(){} + bool parseOption(const char*){ return false; }; + + // Variables + QStringList AdditionalDependencies; + QStringList AdditionalLibraryDirectories; + QStringList AdditionalOptions; + QString DisplayLibrary; + QString ErrorReporting; + QStringList ExportNamedFunctions; + QStringList ForceSymbolReferences; + triState IgnoreAllDefaultLibraries; + QStringList IgnoreSpecificDefaultLibraries; + triState LinkTimeCodeGeneration; + QString ModuleDefinitionFile; + QString Name; + QString OutputFile; + QStringList RemoveObjects; + QString SubSystem; + triState SuppressStartupBanner; + QString TargetMachine; + triState TreatLibWarningAsErrors; + triState Verbose; + +}; + +class VCXCustomBuildTool : public VCToolBase +{ +public: + // Functions + VCXCustomBuildTool(); + virtual ~VCXCustomBuildTool(){} + bool parseOption(const char*){ return false; }; + + // Variables + QStringList AdditionalDependencies; + QStringList CommandLine; + QString Description; + QStringList Outputs; + QString ToolName; + QString ToolPath; + QString ConfigName; +}; + +class VCXResourceCompilerTool : public VCToolBase +{ +public: + // Functions + VCXResourceCompilerTool(); + virtual ~VCXResourceCompilerTool(){} + bool parseOption(const char*){ return false; }; + + // Variables + QStringList AdditionalIncludeDirectories; + QString AdditionalOptions; + QString Culture; + triState IgnoreStandardIncludePath; + triState NullTerminateStrings; + QStringList PreprocessorDefinitions; + QString ResourceOutputFileName; + triState ShowProgress; + triState SuppressStartupBanner; + QString TrackerLogDirectory; + QString UndefinePreprocessorDefinitions; +}; + +class VCXDeploymentTool +{ +public: + // Functions + VCXDeploymentTool(); + virtual ~VCXDeploymentTool() {} + + // Variables + QString DeploymentTag; + QString RemoteDirectory; + QString AdditionalFiles; +}; + +class VCXEventTool : public VCToolBase +{ +protected: + // Functions + VCXEventTool() : UseInBuild(unset){}; + virtual ~VCXEventTool(){} + bool parseOption(const char*){ return false; }; + +public: + // Variables + QString CommandLine; + QString Description; + triState UseInBuild; + QString EventName; + QString ToolPath; +}; + +class VCXPostBuildEventTool : public VCXEventTool +{ +public: + VCXPostBuildEventTool(); + ~VCXPostBuildEventTool(){} +}; + +class VCXPreBuildEventTool : public VCXEventTool +{ +public: + VCXPreBuildEventTool(); + ~VCXPreBuildEventTool(){} +}; + +class VCXPreLinkEventTool : public VCXEventTool +{ +public: + VCXPreLinkEventTool(); + ~VCXPreLinkEventTool(){} +}; + +class VCXConfiguration +{ +public: + // Functions + VCXConfiguration(); + ~VCXConfiguration(){} + + // Variables + triState ATLMinimizesCRunTimeLibraryUsage; + triState BuildBrowserInformation; + QString CharacterSet; + QString ConfigurationType; + QString DeleteExtensionsOnClean; + QString ImportLibrary; + QString IntermediateDirectory; + QString Name; + QString ConfigurationName; + QString OutputDirectory; + QString PrimaryOutput; + QString ProgramDatabase; + triState RegisterOutput; + QString TargetName; + QString UseOfATL; + QString UseOfMfc; + triState WholeProgramOptimization; + + // XML sub-parts + VCXCLCompilerTool compiler; + VCXLibrarianTool librarian; + VCXLinkerTool linker; + VCXMIDLTool idl; + VCXResourceCompilerTool resource; + VCXCustomBuildTool custom; + VCXDeploymentTool deployment; // Not likely to be supported: http://msdn.microsoft.com/en-us/library/sa69he4t.aspx + VCXPostBuildEventTool postBuild; + VCXPreBuildEventTool preBuild; + VCXPreLinkEventTool preLink; +}; + +struct VCXFilterFile +{ + VCXFilterFile() + { excludeFromBuild = false; } + VCXFilterFile(const QString &filename, bool exclude = false ) + { file = filename; excludeFromBuild = exclude; } + VCXFilterFile(const QString &filename, const QString &additional, bool exclude = false ) + { file = filename; excludeFromBuild = exclude; additionalFile = additional; } + bool operator==(const VCXFilterFile &other){ + return file == other.file + && additionalFile == other.additionalFile + && excludeFromBuild == other.excludeFromBuild; + } + + bool excludeFromBuild; + QString file; + QString additionalFile; // For tools like MOC +}; + +class VcxprojGenerator; +class VCXFilter +{ +public: + // Functions + VCXFilter(); + ~VCXFilter(){}; + + void addFile(const QString& filename); + void addFile(const VCXFilterFile& fileInfo); + void addFiles(const QStringList& fileList); + bool addExtraCompiler(const VCXFilterFile &info); + void modifyPCHstage(QString str); + bool outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded); + + // Variables + QString Name; + QString Filter; + QString Guid; + triState ParseFiles; + VcxprojGenerator* Project; + VCXConfiguration* Config; + QList<VCXFilterFile> Files; + + customBuildCheck CustomBuild; + + bool useCustomBuildTool; + VCXCustomBuildTool CustomBuildTool; + + bool useCompilerTool; + VCXCLCompilerTool CompilerTool; +}; + +typedef QList<VCXFilter> VCXFilterList; +class VCXProjectSingleConfig +{ +public: + enum FilterTypes { + None, + Source, + Header, + Generated, + LexYacc, + Translation, + Resources, + Extras + }; + // Functions + VCXProjectSingleConfig(){}; + ~VCXProjectSingleConfig(){} + + // Variables + QString Name; + QString Version; + QString ProjectGUID; + QString Keyword; + QString SccProjectName; + QString SccLocalPath; + QString PlatformName; + + // XML sub-parts + VCXConfiguration Configuration; + VCXFilter RootFiles; + VCXFilter SourceFiles; + VCXFilter HeaderFiles; + VCXFilter GeneratedFiles; + VCXFilter LexYaccFiles; + VCXFilter TranslationFiles; + VCXFilter FormFiles; + VCXFilter ResourceFiles; + VCXFilterList ExtraCompilersFiles; + + bool flat_files; + + // Accessor for extracompilers + VCXFilter &filterForExtraCompiler(const QString &compilerName); +}; + + + +// Tree & Flat view of files -------------------------------------------------- +class VCXFilter; +class XNode +{ +public: + virtual ~XNode() { } + void addElement(const VCXFilterFile &file) { + addElement(file.file, file); + } + virtual void addElement(const QString &filepath, const VCXFilterFile &allInfo) = 0; + virtual void removeElements()= 0; + virtual void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCXProject &tool, const QString &filter) = 0; + virtual bool hasElements() = 0; +}; + +class XTreeNode : public XNode +{ + typedef QMap<QString, XTreeNode*> ChildrenMap; + VCXFilterFile info; + ChildrenMap children; + +public: + virtual ~XTreeNode() { removeElements(); } + + int pathIndex(const QString &filepath) { + int Windex = filepath.indexOf("\\"); + int Uindex = filepath.indexOf("/"); + if (Windex != -1 && Uindex != -1) + return qMin(Windex, Uindex); + else if (Windex != -1) + return Windex; + return Uindex; + } + + void addElement(const QString &filepath, const VCXFilterFile &allInfo){ + QString newNodeName(filepath); + + int index = pathIndex(filepath); + if (index != -1) + newNodeName = filepath.left(index); + + XTreeNode *n = children.value(newNodeName); + if (!n) { + n = new XTreeNode; + n->info = allInfo; + children.insert(newNodeName, n); + } + if (index != -1) + n->addElement(filepath.mid(index+1), allInfo); + } + + void removeElements() { + ChildrenMap::ConstIterator it = children.constBegin(); + ChildrenMap::ConstIterator end = children.constEnd(); + for( ; it != end; it++) { + (*it)->removeElements(); + delete it.value(); + } + children.clear(); + } + + void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCXProject &tool, const QString &filter); + bool hasElements() { + return children.size() != 0; + } +}; + +class XFlatNode : public XNode +{ + typedef QMap<QString, VCXFilterFile> ChildrenMapFlat; + ChildrenMapFlat children; + +public: + virtual ~XFlatNode() { removeElements(); } + + int pathIndex(const QString &filepath) { + int Windex = filepath.lastIndexOf("\\"); + int Uindex = filepath.lastIndexOf("/"); + if (Windex != -1 && Uindex != -1) + return qMax(Windex, Uindex); + else if (Windex != -1) + return Windex; + return Uindex; + } + + void addElement(const QString &filepath, const VCXFilterFile &allInfo){ + QString newKey(filepath); + + int index = pathIndex(filepath); + if (index != -1) + newKey = filepath.mid(index+1); + + // Key designed to sort files with same + // name in different paths correctly + children.insert(newKey + "\0" + allInfo.file, allInfo); + } + + void removeElements() { + children.clear(); + } + + void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCXProject &proj, const QString &filter); + bool hasElements() { + return children.size() != 0; + } +}; +// ---------------------------------------------------------------------------- + +class VCXProject +{ +public: + // Variables + QString Name; + QString Version; + QString ProjectGUID; + QString Keyword; + QString SccProjectName; + QString SccLocalPath; + QString PlatformName; + + // Single projects + QList<VCXProjectSingleConfig> SingleProjects; + + // List of all extracompilers + QStringList ExtraCompilers; + + // Functions + void outputFilter(XmlOutput &xml, + XmlOutput &xmlFilter, + const QString &filtername); + + void outputFileConfigs(XmlOutput &xml, + XmlOutput &xmlFilter, + const VCXFilterFile &info, + const QString &filtername); + + void addFilters(XmlOutput &xmlFilter, + const QString &filtername); + +}; + + +XmlOutput &operator<<(XmlOutput &, const VCXCLCompilerTool &); +XmlOutput &operator<<(XmlOutput &, const VCXLinkerTool &); +XmlOutput &operator<<(XmlOutput &, const VCXMIDLTool &); +XmlOutput &operator<<(XmlOutput &, const VCXCustomBuildTool &); +XmlOutput &operator<<(XmlOutput &, const VCXLibrarianTool &); +XmlOutput &operator<<(XmlOutput &, const VCXResourceCompilerTool &); +XmlOutput &operator<<(XmlOutput &, const VCXEventTool &); +XmlOutput &operator<<(XmlOutput &, const VCXDeploymentTool &); +XmlOutput &operator<<(XmlOutput &, const VCXConfiguration &); +XmlOutput &operator<<(XmlOutput &, const VCXProjectSingleConfig &); +XmlOutput &operator<<(XmlOutput &, VCXProject &); + + +QT_END_NAMESPACE + +#endif // MSVC_OBJECTMODEL_H diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 5f3d433..604aa8a 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -41,6 +41,7 @@ #include "msvc_objectmodel.h" #include "msvc_vcproj.h" +#include "msvc_vcxproj.h" #include <qstringlist.h> #include <qfileinfo.h> diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index c56187c..3f60a13 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -58,7 +58,8 @@ enum DotNET { NET2002 = 0x70, NET2003 = 0x71, NET2005 = 0x80, - NET2008 = 0x90 + NET2008 = 0x90, + NET2010 = 0x91 }; /* @@ -867,7 +868,7 @@ public: customBuildCheck CustomBuild; - bool useCustomBuildTool; + bool useCustomBuildTool; VCCustomBuildTool CustomBuildTool; bool useCompilerTool; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index f1777e1..8c9bba8 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -77,6 +77,8 @@ struct { const char *regKey; } dotNetCombo[] = { #ifdef Q_OS_WIN64 + {NET2010, "MSVC.NET 2010 (10.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir"}, + {NET2010, "MSVC.NET 2010 Express Edition (10.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\10.0\\Setup\\VC\\ProductDir"}, {NET2008, "MSVC.NET 2008 (9.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\Setup\\VC\\ProductDir"}, {NET2008, "MSVC.NET 2008 Express Edition (9.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\9.0\\Setup\\VC\\ProductDir"}, {NET2005, "MSVC.NET 2005 (8.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"}, @@ -84,6 +86,8 @@ struct { {NET2003, "MSVC.NET 2003 (7.1)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"}, {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"}, #else + {NET2010, "MSVC.NET 2010 (10.0)", "Software\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir"}, + {NET2010, "MSVC.NET 2010 Express Edition (10.0)", "Software\\Microsoft\\VCExpress\\10.0\\Setup\\VC\\ProductDir"}, {NET2008, "MSVC.NET 2008 (9.0)", "Software\\Microsoft\\VisualStudio\\9.0\\Setup\\VC\\ProductDir"}, {NET2008, "MSVC.NET 2008 Express Edition (9.0)", "Software\\Microsoft\\VCExpress\\9.0\\Setup\\VC\\ProductDir"}, {NET2005, "MSVC.NET 2005 (8.0)", "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir"}, @@ -165,8 +169,12 @@ DotNET which_dotnet_version() // Flatfile Tags ---------------------------------------------------- const char _slnHeader70[] = "Microsoft Visual Studio Solution File, Format Version 7.00"; const char _slnHeader71[] = "Microsoft Visual Studio Solution File, Format Version 8.00"; -const char _slnHeader80[] = "Microsoft Visual Studio Solution File, Format Version 9.00"; -const char _slnHeader90[] = "Microsoft Visual Studio Solution File, Format Version 10.00"; +const char _slnHeader80[] = "Microsoft Visual Studio Solution File, Format Version 9.00" + "\n# Visual Studio 2005"; +const char _slnHeader90[] = "Microsoft Visual Studio Solution File, Format Version 10.00" + "\n# Visual Studio 2008"; +const char _slnHeader100[] = "Microsoft Visual Studio Solution File, Format Version 11.00" + "\n# Visual Studio 2010"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -354,6 +362,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch(which_dotnet_version()) { + case NET2010: + t << _slnHeader100; + break; case NET2008: t << _slnHeader90; break; diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index ed67ea7..8f028a1 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -61,7 +61,6 @@ class VcprojGenerator : public Win32MakefileGenerator bool writeMakefile(QTextStream &); bool writeProjectMakefile(); - void writeSubDirs(QTextStream &t); QString findTemplate(QString file); void init(); @@ -119,6 +118,9 @@ protected: void initLexYaccFiles(); void initExtraCompilerOutputs(); + void writeSubDirs(QTextStream &t); // Called from VCXProj backend + QUuid getProjectUUID(const QString &filename=QString()); // Called from VCXProj backend + Target projectTarget; // Used for single project @@ -129,7 +131,6 @@ protected: private: QString fixCommandLine(DotNET version, const QString &input) const; - QUuid getProjectUUID(const QString &filename=QString()); QUuid increaseUUID(const QUuid &id); friend class VCFilter; }; diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp new file mode 100644 index 0000000..6a91c6b --- /dev/null +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -0,0 +1,851 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "msvc_vcxproj.h" +#include "msbuild_objectmodel.h" +#include <qdir.h> +#include <qdiriterator.h> +#include <quuid.h> + + +QT_BEGIN_NAMESPACE +// Filter GUIDs (Do NOT change these!) ------------------------------ +const char _GUIDSourceFiles[] = "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"; +const char _GUIDHeaderFiles[] = "{93995380-89BD-4b04-88EB-625FBE52EBFB}"; +const char _GUIDGeneratedFiles[] = "{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"; +const char _GUIDResourceFiles[] = "{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"; +const char _GUIDLexYaccFiles[] = "{E12AE0D2-192F-4d59-BD23-7D3FA58D3183}"; +const char _GUIDTranslationFiles[] = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}"; +const char _GUIDFormFiles[] = "{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"; +const char _GUIDExtraCompilerFiles[] = "{E0D8C965-CC5F-43d7-AD63-FAEF0BBC0F85}"; +QT_END_NAMESPACE + +QT_BEGIN_NAMESPACE + + +VcxprojGenerator::VcxprojGenerator() : VcprojGenerator() +{ +} +bool VcxprojGenerator::writeMakefile(QTextStream &t) +{ + initProject(); // Fills the whole project with proper data + + // Generate solution file + if(project->first("TEMPLATE") == "vcsubdirs") { + if (!project->isActiveConfig("build_pass")) { + debug_msg(1, "Generator: MSVC.NET: Writing solution file"); + writeSubDirs(t); + } else { + debug_msg(1, "Generator: MSVC.NET: Not writing solution file for build_pass configs"); + } + return true; + } else + // Generate single configuration project file + if (project->first("TEMPLATE") == "vcapp" || + project->first("TEMPLATE") == "vclib") { + if(!project->isActiveConfig("build_pass")) { + debug_msg(1, "Generator: MSVC.NET: Writing single configuration project file"); + XmlOutput xmlOut(t); + xmlOut << vcxProject; + } + return true; + } + return project->isActiveConfig("build_pass"); + return true; +} + + +void VcxprojGenerator::initProject() +{ + // Initialize XML sub elements + // - Do this first since project elements may need + // - to know of certain configuration options + initConfiguration(); + initRootFiles(); + initSourceFiles(); + initHeaderFiles(); + initGeneratedFiles(); + initLexYaccFiles(); + initTranslationFiles(); + initFormFiles(); + initResourceFiles(); + initExtraCompilerOutputs(); + + // Own elements ----------------------------- + vcxProject.Name = unescapeFilePath(project->first("QMAKE_ORIG_TARGET")); + + vcxProject.Keyword = project->first("VCPROJ_KEYWORD"); + if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { + vcxProject.PlatformName = vcxProject.Configuration.idl.TargetEnvironment; + if ( vcxProject.Configuration.idl.TargetEnvironment.isEmpty() ) + vcxProject.PlatformName = "Win32"; + } else { + vcxProject.PlatformName = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; + } + // These are not used by Qt, but may be used by customers + vcxProject.SccProjectName = project->first("SCCPROJECTNAME"); + vcxProject.SccLocalPath = project->first("SCCLOCALPATH"); + vcxProject.flat_files = project->isActiveConfig("flat"); +} + + +void VcxprojGenerator::initConfiguration() +{ + // Initialize XML sub elements + // - Do this first since main configuration elements may need + // - to know of certain compiler/linker options + VCXConfiguration &conf = vcxProject.Configuration; + + initCompilerTool(); + + // Only on configuration per build + bool isDebug = project->isActiveConfig("debug"); + + if(projectTarget == StaticLib) + initLibrarianTool(); + else { + conf.linker.GenerateDebugInformation = isDebug ? _True : _False; + initLinkerTool(); + } + initResourceTool(); + initIDLTool(); + + // Own elements ----------------------------- + QString temp = project->first("BuildBrowserInformation"); + switch (projectTarget) { + case SharedLib: + conf.ConfigurationType = "DynamicLibrary"; + break; + case StaticLib: + conf.ConfigurationType = "StaticLibrary"; + break; + case Application: + default: + conf.ConfigurationType = "Application"; + break; + } + + conf.OutputDirectory = project->first("DESTDIR"); + + if(conf.OutputDirectory.isEmpty()) + conf.OutputDirectory = ".\\"; + + if(!conf.OutputDirectory.endsWith("\\")) + conf.OutputDirectory += '\\'; + + // The target name could have been changed. + conf.TargetName = project->first("TARGET"); + if ( !conf.TargetName.isEmpty() && !project->first("TARGET_VERSION_EXT").isEmpty() && project->isActiveConfig("shared")) + conf.TargetName.append(project->first("TARGET_VERSION_EXT")); + + conf.Name = project->values("BUILD_NAME").join(" "); + if (conf.Name.isEmpty()) + conf.Name = isDebug ? "Debug" : "Release"; + conf.ConfigurationName = conf.Name; + if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { + conf.Name += (conf.idl.TargetEnvironment == "Win64" ? "|Win64" : "|Win32"); + } else { + conf.Name += "|" + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; + } + conf.ATLMinimizesCRunTimeLibraryUsage = (project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True); + conf.BuildBrowserInformation = triState(temp.isEmpty() ? (short)unset : temp.toShort()); + temp = project->first("CharacterSet"); + if (!temp.isEmpty()) + { + switch (charSet(temp.toShort())) { + + case charSetMBCS: + conf.CharacterSet = "MultiByte"; + break; + case charSetUnicode: + conf.CharacterSet = "Unicode"; + break; + case charSetNotSet: + default: + conf.CharacterSet = "NotSet"; + break; + } + conf.CharacterSet = charSet(temp.isEmpty() ? (short)charSetNotSet : temp.toShort()); + } + conf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); + conf.ImportLibrary = conf.linker.ImportLibrary; + conf.IntermediateDirectory = project->first("OBJECTS_DIR"); + //conf.OutputDirectory = "."; + conf.PrimaryOutput = project->first("PrimaryOutput"); + conf.WholeProgramOptimization = conf.compiler.WholeProgramOptimization; + temp = project->first("UseOfATL"); + if(!temp.isEmpty()) + { + switch (useOfATL(temp.toShort())) { + + case useATLStatic: + conf.UseOfATL = "Static"; + break; + case useATLDynamic: + conf.UseOfATL = "Dynamic"; + break; + case useATLNotSet: + default: + conf.UseOfATL = "false"; + break; + } + } + temp = project->first("UseOfMfc"); + if(!temp.isEmpty()) + { + switch (useOfMfc(temp.toShort())) { + + case useMfcStatic: + conf.UseOfMfc = "Static"; + break; + case useMfcDynamic: + conf.UseOfMfc = "Dynamic"; + break; + case useMfcStdWin: + default: + conf.UseOfMfc = "false"; + break; + } + } + + // Configuration does not need parameters from + // these sub XML items; + initCustomBuildTool(); + initPreBuildEventTools(); + initPostBuildEventTools(); + // Only deploy for CE projects + if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) + initDeploymentTool(); + initPreLinkEventTools(); + + // Set definite values in both configurations + if (isDebug) { + conf.compiler.PreprocessorDefinitions.removeAll("NDEBUG"); + } else { + conf.compiler.PreprocessorDefinitions += "NDEBUG"; + } +} + + +void VcxprojGenerator::initCompilerTool() +{ + QString placement = project->first("OBJECTS_DIR"); + if(placement.isEmpty()) + placement = ".\\"; + + VCXConfiguration &conf = vcxProject.Configuration; + conf.compiler.AssemblerListingLocation = placement ; + conf.compiler.ProgramDataBaseFileName = ".\\" ; + conf.compiler.ObjectFileName = placement ; + // PCH + if (usePCH) { + conf.compiler.PrecompiledHeader = "Use"; + conf.compiler.PrecompiledHeaderOutputFile = "$(IntDir)\\" + precompPch; + conf.compiler.PrecompiledHeaderFile = project->first("PRECOMPILED_HEADER"); + conf.compiler.ForcedIncludeFiles = project->values("PRECOMPILED_HEADER"); + conf.compiler.PreprocessToFile = _False; + conf.compiler.PreprocessSuppressLineNumbers = _False; + // Minimal build option triggers an Internal Compiler Error + // when used in conjunction with /FI and /Yu, so remove it + project->values("QMAKE_CFLAGS_DEBUG").removeAll("-Gm"); + project->values("QMAKE_CFLAGS_DEBUG").removeAll("/Gm"); + project->values("QMAKE_CXXFLAGS_DEBUG").removeAll("-Gm"); + project->values("QMAKE_CXXFLAGS_DEBUG").removeAll("/Gm"); + } + + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); + if(project->isActiveConfig("debug")){ + // Debug version + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG")); + if((projectTarget == Application) || (projectTarget == StaticLib)) + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG")); + else + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG")); + } else { + // Release version + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE")); + conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + conf.compiler.PreprocessorDefinitions += "NDEBUG"; + if((projectTarget == Application) || (projectTarget == StaticLib)) + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT")); + else + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLL")); + } + + // Common for both release and debug + if(project->isActiveConfig("warn_off")) + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF")); + else if(project->isActiveConfig("warn_on")) + conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON")); + if(project->isActiveConfig("windows")) + conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF"); + + // Can this be set for ALL configs? + // If so, use qmake.conf! + if(projectTarget == SharedLib) + conf.compiler.PreprocessorDefinitions += "_WINDOWS"; + + conf.compiler.PreprocessorDefinitions += project->values("DEFINES"); + conf.compiler.PreprocessorDefinitions += project->values("PRL_EXPORT_DEFINES"); + conf.compiler.parseOptions(project->values("MSVCPROJ_INCPATH")); +} + +void VcxprojGenerator::initLinkerTool() +{ + findLibraries(); // Need to add the highest version of the libs + VCXConfiguration &conf = vcxProject.Configuration; + conf.linker.parseOptions(project->values("MSVCPROJ_LFLAGS")); + + foreach(QString libs, project->values("MSVCPROJ_LIBS")) { + if (libs.left(9).toUpper() == "/LIBPATH:") { + QStringList l = QStringList(libs); + conf.linker.parseOptions(l); + } else { + conf.linker.AdditionalDependencies += libs; + } + } + + switch (projectTarget) { + case Application: + conf.linker.OutputFile = project->first("DESTDIR"); + break; + case SharedLib: + conf.linker.parseOptions(project->values("MSVCPROJ_LIBOPTIONS")); + conf.linker.OutputFile = project->first("DESTDIR"); + break; + case StaticLib: //unhandled - added to remove warnings.. + break; + } + + if(conf.linker.OutputFile.isEmpty()) + conf.linker.OutputFile = ".\\"; + + if(!conf.linker.OutputFile.endsWith("\\")) + conf.linker.OutputFile += '\\'; + + conf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); + + if(project->isActiveConfig("debug")){ + conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG")); + } else { + conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE")); + } + + if(project->isActiveConfig("dll")){ + conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL")); + } + + if(project->isActiveConfig("console")){ + conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE")); + } else { + conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS")); + } + +} + +void VcxprojGenerator::initResourceTool() +{ + VCXConfiguration &conf = vcxProject.Configuration; + conf.resource.PreprocessorDefinitions = conf.compiler.PreprocessorDefinitions; + + // We need to add _DEBUG for the debug version of the project, since the normal compiler defines + // do not contain it. (The compiler defines this symbol automatically, which is wy we don't need + // to add it for the compiler) However, the resource tool does not do this. + if(project->isActiveConfig("debug")) + conf.resource.PreprocessorDefinitions += "_DEBUG"; + if(project->isActiveConfig("staticlib")) + conf.resource.ResourceOutputFileName = project->first("DESTDIR") + "/$(InputName).res"; +} + + +void VcxprojGenerator::initPostBuildEventTools() +{ + VCXConfiguration &conf = vcxProject.Configuration; + if(!project->values("QMAKE_POST_LINK").isEmpty()) { + QString cmdline = var("QMAKE_POST_LINK"); + conf.postBuild.CommandLine = cmdline; + conf.postBuild.Description = cmdline; + } + + QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE"); + bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") && + !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"); + if(useSignature) + conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" + + (!conf.postBuild.CommandLine.isEmpty() ? " && " : "")); + + if(!project->values("MSVCPROJ_COPY_DLL").isEmpty()) { + if(!conf.postBuild.CommandLine.isEmpty()) + conf.postBuild.CommandLine += " && "; + conf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC"); + conf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL"); + } +} + + +void VcxprojGenerator::initDeploymentTool() +{ + VCXConfiguration &conf = vcxProject.Configuration; + QString targetPath = project->values("deploy.path").join(" "); + if (targetPath.isEmpty()) + targetPath = QString("%CSIDL_PROGRAM_FILES%\\") + project->first("TARGET"); + if (targetPath.endsWith("/") || targetPath.endsWith("\\")) + targetPath.chop(1); + + // Only deploy Qt libs for shared build + if (!project->values("QMAKE_QT_DLL").isEmpty()) { + QStringList& arg = project->values("MSVCPROJ_LIBS"); + for (QStringList::ConstIterator it = arg.constBegin(); it != arg.constEnd(); ++it) { + if (it->contains(project->first("QMAKE_LIBDIR"))) { + QString dllName = *it; + + if (dllName.contains(QLatin1String("QAxContainer")) + || dllName.contains(QLatin1String("qtmain")) + || dllName.contains(QLatin1String("QtUiTools"))) + continue; + dllName.replace(QLatin1String(".lib") , QLatin1String(".dll")); + QFileInfo info(dllName); + conf.deployment.AdditionalFiles += info.fileName() + + "|" + QDir::toNativeSeparators(info.absolutePath()) + + "|" + targetPath + + "|0;"; + } + } + } + + // C-runtime deployment + QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1String(" ")); + if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) { + QString runtimeVersion = QLatin1String("msvcr"); + QString mkspec = project->first("QMAKESPEC"); + // If no .qmake.cache has been found, we fallback to the original mkspec + if (mkspec.isEmpty()) + mkspec = project->first("QMAKESPEC_ORIGINAL"); + + if (!mkspec.isEmpty()) { + if (mkspec.endsWith("2010")) + runtimeVersion.append("100"); + else if (mkspec.endsWith("2008")) + runtimeVersion.append("90"); + else + runtimeVersion.append("80"); + if (project->isActiveConfig("debug")) + runtimeVersion.append("d"); + runtimeVersion.append(".dll"); + + if (runtime == "yes") { + // Auto-find C-runtime + QString vcInstallDir = qgetenv("VCINSTALLDIR"); + if (!vcInstallDir.isEmpty()) { + vcInstallDir += "\\ce\\dll\\"; + vcInstallDir += project->values("CE_ARCH").join(QLatin1String(" ")); + if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists()) + runtime.clear(); + else + runtime = vcInstallDir; + } + } + } + + if (!runtime.isEmpty() && runtime != QLatin1String("yes")) { + conf.deployment.AdditionalFiles += runtimeVersion + + "|" + QDir::toNativeSeparators(runtime) + + "|" + targetPath + + "|0;"; + } + } + + // foreach item in DEPLOYMENT + foreach(QString item, project->values("DEPLOYMENT")) { + // get item.path + QString devicePath = project->first(item + ".path"); + if (devicePath.isEmpty()) + devicePath = targetPath; + // check if item.path is relative (! either /,\ or %) + if (!(devicePath.at(0) == QLatin1Char('/') + || devicePath.at(0) == QLatin1Char('\\') + || devicePath.at(0) == QLatin1Char('%'))) { + // create output path + devicePath = Option::fixPathToLocalOS(QDir::cleanPath(targetPath + QLatin1Char('\\') + devicePath)); + } + // foreach d in item.sources + foreach(QString source, project->values(item + ".sources")) { + QString itemDevicePath = devicePath; + source = Option::fixPathToLocalOS(source); + QString nameFilter; + QFileInfo info(source); + QString searchPath; + if (info.isDir()) { + nameFilter = QLatin1String("*"); + itemDevicePath += "\\" + info.fileName(); + searchPath = info.absoluteFilePath(); + } else { + nameFilter = source.split('\\').last(); + searchPath = info.absolutePath(); + } + + int pathSize = searchPath.size(); + QDirIterator iterator(searchPath, QStringList() << nameFilter + , QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks + , QDirIterator::Subdirectories); + // foreach dirIterator-entry in d + while(iterator.hasNext()) { + iterator.next(); + QString absoluteItemPath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absolutePath()); + // Identify if it is just another subdir + int diffSize = absoluteItemPath.size() - pathSize; + // write out rules + conf.deployment.AdditionalFiles += iterator.fileName() + + "|" + absoluteItemPath + + "|" + itemDevicePath + (diffSize ? (absoluteItemPath.right(diffSize)) : QLatin1String("")) + + "|0;"; + } + } + } +} + +void VcxprojGenerator::initPreLinkEventTools() +{ + VCXConfiguration &conf = vcxProject.Configuration; + if(!project->values("QMAKE_PRE_LINK").isEmpty()) { + QString cmdline = var("QMAKE_PRE_LINK"); + conf.preLink.Description = cmdline; + conf.preLink.CommandLine = cmdline; + } +} + +void VcxprojGenerator::initRootFiles() +{ + vcxProject.RootFiles.addFiles(project->values("RC_FILE")); + vcxProject.RootFiles.Project = this; + vcxProject.RootFiles.Config = &(vcxProject.Configuration); + vcxProject.RootFiles.CustomBuild = none; +} + +void VcxprojGenerator::initSourceFiles() +{ + vcxProject.SourceFiles.Name = "Source Files"; + vcxProject.SourceFiles.Filter = "cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"; + vcxProject.SourceFiles.Guid = _GUIDSourceFiles; + + vcxProject.SourceFiles.addFiles(project->values("SOURCES")); + + vcxProject.SourceFiles.Project = this; + vcxProject.SourceFiles.Config = &(vcxProject.Configuration); + vcxProject.SourceFiles.CustomBuild = none; +} + +void VcxprojGenerator::initHeaderFiles() +{ + vcxProject.HeaderFiles.Name = "Header Files"; + vcxProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl;inc;xsd"; + vcxProject.HeaderFiles.Guid = _GUIDHeaderFiles; + + vcxProject.HeaderFiles.addFiles(project->values("HEADERS")); + if (usePCH) // Generated PCH cpp file + vcxProject.HeaderFiles.addFile(precompH); + + vcxProject.HeaderFiles.Project = this; + vcxProject.HeaderFiles.Config = &(vcxProject.Configuration); +} + +void VcxprojGenerator::initGeneratedFiles() +{ + vcxProject.GeneratedFiles.Name = "Generated Files"; + vcxProject.GeneratedFiles.Filter = "cpp;c;cxx;moc;h;def;odl;idl;res"; + vcxProject.GeneratedFiles.Guid = _GUIDGeneratedFiles; + + // ### These cannot have CustomBuild (mocSrc)!! + vcxProject.GeneratedFiles.addFiles(project->values("GENERATED_SOURCES")); + vcxProject.GeneratedFiles.addFiles(project->values("GENERATED_FILES")); + vcxProject.GeneratedFiles.addFiles(project->values("IDLSOURCES")); + vcxProject.GeneratedFiles.addFiles(project->values("RES_FILE")); + vcxProject.GeneratedFiles.addFiles(project->values("QMAKE_IMAGE_COLLECTION")); // compat + if(!extraCompilerOutputs.isEmpty()) + vcxProject.GeneratedFiles.addFiles(extraCompilerOutputs.keys()); + + vcxProject.GeneratedFiles.Project = this; + vcxProject.GeneratedFiles.Config = &(vcxProject.Configuration); +} + +void VcxprojGenerator::initLexYaccFiles() +{ + vcxProject.LexYaccFiles.Name = "Lex / Yacc Files"; + vcxProject.LexYaccFiles.ParseFiles = _False; + vcxProject.LexYaccFiles.Filter = "l;y"; + vcxProject.LexYaccFiles.Guid = _GUIDLexYaccFiles; + + vcxProject.LexYaccFiles.addFiles(project->values("LEXSOURCES")); + vcxProject.LexYaccFiles.addFiles(project->values("YACCSOURCES")); + + vcxProject.LexYaccFiles.Project = this; + vcxProject.LexYaccFiles.Config = &(vcxProject.Configuration); + vcxProject.LexYaccFiles.CustomBuild = lexyacc; +} + +void VcxprojGenerator::initTranslationFiles() +{ + vcxProject.TranslationFiles.Name = "Translation Files"; + vcxProject.TranslationFiles.ParseFiles = _False; + vcxProject.TranslationFiles.Filter = "ts;xlf"; + vcxProject.TranslationFiles.Guid = _GUIDTranslationFiles; + + vcxProject.TranslationFiles.addFiles(project->values("TRANSLATIONS")); + + vcxProject.TranslationFiles.Project = this; + vcxProject.TranslationFiles.Config = &(vcxProject.Configuration); + vcxProject.TranslationFiles.CustomBuild = none; +} + + +void VcxprojGenerator::initFormFiles() +{ + vcxProject.FormFiles.Name = "Form Files"; + vcxProject.FormFiles.ParseFiles = _False; + vcxProject.FormFiles.Filter = "ui"; + vcxProject.FormFiles.Guid = _GUIDFormFiles; + + vcxProject.FormFiles.addFiles(project->values("FORMS")); + vcxProject.FormFiles.addFiles(project->values("FORMS3")); + + vcxProject.FormFiles.Project = this; + vcxProject.FormFiles.Config = &(vcxProject.Configuration); + vcxProject.FormFiles.CustomBuild = none; +} + + +void VcxprojGenerator::initResourceFiles() +{ + vcxProject.ResourceFiles.Name = "Resource Files"; + vcxProject.ResourceFiles.ParseFiles = _False; + vcxProject.ResourceFiles.Filter = "qrc;*"; //"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;ts;xlf;qrc"; + vcxProject.ResourceFiles.Guid = _GUIDResourceFiles; + + // Bad hack, please look away ------------------------------------- + QString rcc_dep_cmd = project->values("rcc.depend_command").join(" "); + if(!rcc_dep_cmd.isEmpty()) { + QStringList qrc_files = project->values("RESOURCES"); + QStringList deps; + if(!qrc_files.isEmpty()) { + for (int i = 0; i < qrc_files.count(); ++i) { + char buff[256]; + QString dep_cmd = replaceExtraCompilerVariables(rcc_dep_cmd, qrc_files.at(i),""); + + dep_cmd = Option::fixPathToLocalOS(dep_cmd, true, false); + if(canExecute(dep_cmd)) { + if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) { + QString indeps; + while(!feof(proc)) { + int read_in = (int)fread(buff, 1, 255, proc); + if(!read_in) + break; + indeps += QByteArray(buff, read_in); + } + QT_PCLOSE(proc); + if(!indeps.isEmpty()) + deps += fileFixify(indeps.replace('\n', ' ').simplified().split(' ')); + } + } + } + vcxProject.ResourceFiles.addFiles(deps); + } + } + // You may look again -------------------------------------------- + + vcxProject.ResourceFiles.addFiles(project->values("RESOURCES")); + vcxProject.ResourceFiles.addFiles(project->values("IMAGES")); + + vcxProject.ResourceFiles.Project = this; + vcxProject.ResourceFiles.Config = &(vcxProject.Configuration); + vcxProject.ResourceFiles.CustomBuild = none; +} + +void VcxprojGenerator::initExtraCompilerOutputs() +{ + QStringList otherFilters; + otherFilters << "FORMS" + << "FORMS3" + << "GENERATED_FILES" + << "GENERATED_SOURCES" + << "HEADERS" + << "IDLSOURCES" + << "IMAGES" + << "LEXSOURCES" + << "QMAKE_IMAGE_COLLECTION" + << "RC_FILE" + << "RESOURCES" + << "RES_FILE" + << "SOURCES" + << "TRANSLATIONS" + << "YACCSOURCES"; + const QStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); + for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { + QString extracompilerName = project->first((*it) + ".name"); + if (extracompilerName.isEmpty()) + extracompilerName = (*it); + + // Create an extra compiler filter and add the files + VCXFilter extraCompile; + extraCompile.Name = extracompilerName; + extraCompile.ParseFiles = _False; + extraCompile.Filter = ""; + extraCompile.Guid = QString(_GUIDExtraCompilerFiles) + "-" + (*it); + + // If the extra compiler has a variable_out set the output file + // is added to an other file list, and does not need its own.. + bool addOnInput = hasBuiltinCompiler(project->first((*it) + ".output")); + QString tmp_other_out = project->first((*it) + ".variable_out"); + if (!tmp_other_out.isEmpty() && !addOnInput) + continue; + + if (!addOnInput) { + QString tmp_out = project->first((*it) + ".output"); + if (project->values((*it) + ".CONFIG").indexOf("combine") != -1) { + // Combined output, only one file result + extraCompile.addFile( + Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, QString(), QString()), false)); + } else { + // One output file per input + QStringList tmp_in = project->values(project->first((*it) + ".input")); + for (int i = 0; i < tmp_in.count(); ++i) { + const QString &filename = tmp_in.at(i); + if (extraCompilerSources.contains(filename)) + extraCompile.addFile( + Option::fixPathToTargetOS(replaceExtraCompilerVariables(filename, tmp_out, QString()), false)); + } + } + } else { + // In this case we the outputs have a built-in compiler, so we cannot add the custom + // build steps there. So, we turn it around and add it to the input files instead, + // provided that the input file variable is not handled already (those in otherFilters + // are handled, so we avoid them). + QStringList inputVars = project->values((*it) + ".input"); + foreach(QString inputVar, inputVars) { + if (!otherFilters.contains(inputVar)) { + QStringList tmp_in = project->values(inputVar); + for (int i = 0; i < tmp_in.count(); ++i) { + const QString &filename = tmp_in.at(i); + if (extraCompilerSources.contains(filename)) + extraCompile.addFile( + Option::fixPathToTargetOS(replaceExtraCompilerVariables(filename, QString(), QString()), false)); + } + } + } + } + extraCompile.Project = this; + extraCompile.Config = &(vcxProject.Configuration); + extraCompile.CustomBuild = none; + + vcxProject.ExtraCompilersFiles.append(extraCompile); + } +} + + + +bool VcxprojGenerator::writeProjectMakefile() +{ + usePlatformDir(); + QTextStream t(&Option::output); + + // Check if all requirements are fulfilled + if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) { + fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", + var("QMAKE_FAILED_REQUIREMENTS").toLatin1().constData()); + return true; + } + + // Generate project file + if(project->first("TEMPLATE") == "vcapp" || + project->first("TEMPLATE") == "vclib") { + if (!mergedProjects.count()) { + warn_msg(WarnLogic, "Generator: MSVC.NET: no single configuration created, cannot output project!"); + return false; + } + + debug_msg(1, "Generator: MSVC.NET: Writing project file"); + VCXProject mergedProject; + for (int i = 0; i < mergedProjects.count(); ++i) { + VCXProjectSingleConfig *singleProject = &(mergedProjects.at(i)->vcxProject); + mergedProject.SingleProjects += *singleProject; + for (int j = 0; j < singleProject->ExtraCompilersFiles.count(); ++j) { + const QString &compilerName = singleProject->ExtraCompilersFiles.at(j).Name; + if (!mergedProject.ExtraCompilers.contains(compilerName)) + mergedProject.ExtraCompilers += compilerName; + } + } + + if(mergedProjects.count() > 1 && + mergedProjects.at(0)->vcxProject.Name == + mergedProjects.at(1)->vcxProject.Name) + mergedProjects.at(0)->writePrlFile(); + mergedProject.Name = unescapeFilePath(project->first("QMAKE_ORIG_TARGET")); + mergedProject.Version = mergedProjects.at(0)->vcxProject.Version; + mergedProject.ProjectGUID = project->isEmpty("QMAKE_UUID") ? getProjectUUID().toString().toUpper() : project->first("QMAKE_UUID"); + mergedProject.Keyword = project->first("VCPROJ_KEYWORD"); + mergedProject.SccProjectName = mergedProjects.at(0)->vcxProject.SccProjectName; + mergedProject.SccLocalPath = mergedProjects.at(0)->vcxProject.SccLocalPath; + mergedProject.PlatformName = mergedProjects.at(0)->vcxProject.PlatformName; + + XmlOutput xmlOut(t); + xmlOut << mergedProject; + return true; + } else if(project->first("TEMPLATE") == "vcsubdirs") { + return writeMakefile(t); + } + return false; +} + + + + +bool VcxprojGenerator::mergeBuildProject(MakefileGenerator *other) +{ + VcxprojGenerator *otherVC = static_cast<VcxprojGenerator*>(other); + if (!otherVC) { + warn_msg(WarnLogic, "VcxprojGenerator: Cannot merge other types of projects! (ignored)"); + return false; + } + mergedProjects += otherVC; + return true; +} + +QT_END_NAMESPACE + diff --git a/qmake/generators/win32/msvc_vcxproj.h b/qmake/generators/win32/msvc_vcxproj.h new file mode 100644 index 0000000..8a183e9 --- /dev/null +++ b/qmake/generators/win32/msvc_vcxproj.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MSVC_VCXPROJ_H +#define MSVC_VCXPROJ_H + +#include "winmakefile.h" +#include "msbuild_objectmodel.h" +#include "msvc_vcproj.h" + +QT_BEGIN_NAMESPACE + +class VcxprojGenerator : public VcprojGenerator +{ + bool writeMakefile(QTextStream &); + bool writeProjectMakefile(); + +public: + VcxprojGenerator(); + ~VcxprojGenerator(); + +protected: + virtual bool supportsMetaBuild() { return true; } + virtual bool supportsMergedBuilds() { return true; } + virtual bool mergeBuildProject(MakefileGenerator *other); + + virtual void initProject(); + + void initConfiguration(); + void initCompilerTool(); + void initDeploymentTool(); + void initLinkerTool(); + void initPreLinkEventTools(); + void initPostBuildEventTools(); + void initRootFiles(); + void initResourceTool(); + void initSourceFiles(); + void initHeaderFiles(); + void initGeneratedFiles(); + void initTranslationFiles(); + void initFormFiles(); + void initResourceFiles(); + void initLexYaccFiles(); + void initExtraCompilerOutputs(); + + // Used for single project + VCXProjectSingleConfig vcxProject; + + // Holds all configurations for glue (merged) project + QList<VcxprojGenerator*> mergedProjects; + +private: + friend class VCXFilter; + +}; + +inline VcxprojGenerator::~VcxprojGenerator() +{ } + +QT_END_NAMESPACE + +#endif // MSVC_VCXPROJ_H diff --git a/qmake/generators/xmloutput.cpp b/qmake/generators/xmloutput.cpp index e8578aa..718bdd6 100644 --- a/qmake/generators/xmloutput.cpp +++ b/qmake/generators/xmloutput.cpp @@ -81,6 +81,11 @@ void XmlOutput::setState(XMLState state) currentState = state; } +void XmlOutput::setFormat(XMLFormat newFormat) +{ + format = newFormat; +} + XmlOutput::XMLState XmlOutput::state() { return currentState; @@ -172,6 +177,20 @@ XmlOutput& XmlOutput::operator<<(const xml_output& o) case tTag: newTagOpen(o.xo_text); break; + case tTagValue: + addRaw(QString("\n%1<%2>").arg(currentIndent).arg(o.xo_text)); + addRaw(QString("%1").arg(o.xo_value)); + addRaw(QString("</%1>").arg(o.xo_text)); + break; + case tValueTag: + addRaw(QString("%1").arg(doConversion(o.xo_text))); + setFormat(NoNewLine); + closeTag(); + setFormat(NewLine); + break; + case tImport: + addRaw(QString("\n%1<Import %2=\"%3\" />").arg(currentIndent).arg(o.xo_text).arg(o.xo_value)); + break; case tCloseTag: if (o.xo_value.count()) closeAll(); @@ -183,6 +202,9 @@ XmlOutput& XmlOutput::operator<<(const xml_output& o) case tAttribute: addAttribute(o.xo_text, o.xo_value); break; + case tAttributeTag: + addAttributeTag(o.xo_text, o.xo_value); + break; case tData: { // Special case to be able to close tag in normal @@ -266,7 +288,7 @@ void XmlOutput::closeTag() tagStack.pop_back(); break; case Attribute: - xmlFile << "/>"; + xmlFile << " />"; tagStack.pop_back(); currentState = Tag; decreaseIndent(); // <--- Post-decrease indent @@ -307,7 +329,7 @@ void XmlOutput::addDeclaration(const QString &version, const QString &encoding) qDebug("<%s>: Cannot add declaration when not in bare state", tagStack.last().toLatin1().constData()); return; } - QString outData = QString("<?xml version=\"%1\" encoding = \"%2\"?>") + QString outData = QString("<?xml version=\"%1\" encoding=\"%2\"?>") .arg(doConversion(version)) .arg(doConversion(encoding)); addRaw(outData); @@ -337,4 +359,20 @@ void XmlOutput::addAttribute(const QString &attribute, const QString &value) xmlFile << currentIndent << doConversion(attribute) << "=\"" << doConversion(value) << "\""; } +void XmlOutput::addAttributeTag(const QString &attribute, const QString &value) +{ + switch(currentState) { + case Bare: + case Tag: + //warn_msg(WarnLogic, "<%s>: Cannot add attribute since tags not open", tagStack.last().toLatin1().constData()); + qDebug("<%s>: Cannot add attribute (%s) since tag's not open", + (tagStack.count() ? tagStack.last().toLatin1().constData() : "Root"), + attribute.toLatin1().constData()); + return; + case Attribute: + break; + } + xmlFile << " " << doConversion(attribute) << "=\"" << doConversion(value) << "\""; +} + QT_END_NAMESPACE diff --git a/qmake/generators/xmloutput.h b/qmake/generators/xmloutput.h index a472c99..7c0667c 100644 --- a/qmake/generators/xmloutput.h +++ b/qmake/generators/xmloutput.h @@ -69,9 +69,13 @@ public: tRaw, // Raw text (no formating) tDeclaration, // <?xml version="x.x" encoding="xxx"?> tTag, // <tagname attribute1="value" + tTagValue, // <tagname>value</tagname> + tValueTag, // value</tagname> tCloseTag, // Closes an open tag tAttribute, // attribute2="value"> + tAttributeTag, // attribute on the same line as a tag tData, // Tag data (formating done) + tImport, // <import "type"="path" /> tComment, // <!-- Comment --> tCDATA // <![CDATA[ ... ]]> }; @@ -85,6 +89,7 @@ public: void setIndentLevel(int level); int indentLevel(); void setState(XMLState state); + void setFormat(XMLFormat newFormat); XMLState state(); @@ -121,6 +126,7 @@ private: void addDeclaration(const QString &version, const QString &encoding); void addRaw(const QString &rawText); void addAttribute(const QString &attribute, const QString &value); + void addAttributeTag(const QString &attribute, const QString &value); void addData(const QString &data); // Data @@ -163,6 +169,22 @@ inline XmlOutput::xml_output tag(const QString &name) return XmlOutput::xml_output(XmlOutput::tTag, name, QString()); } + +inline XmlOutput::xml_output valueTag(const QString &value) +{ + return XmlOutput::xml_output(XmlOutput::tValueTag, value, QString()); +} + +inline XmlOutput::xml_output tagValue(const QString &tagName, const QString &value) +{ + return XmlOutput::xml_output(XmlOutput::tTagValue, tagName, value); +} + +inline XmlOutput::xml_output import(const QString &tagName, const QString &value) +{ + return XmlOutput::xml_output(XmlOutput::tImport, tagName, value); +} + inline XmlOutput::xml_output closetag() { return XmlOutput::xml_output(XmlOutput::tCloseTag, QString(), QString()); @@ -184,12 +206,24 @@ inline XmlOutput::xml_output attribute(const QString &name, return XmlOutput::xml_output(XmlOutput::tAttribute, name, value); } +inline XmlOutput::xml_output attributeTag(const QString &name, + const QString &value) +{ + return XmlOutput::xml_output(XmlOutput::tAttributeTag, name, value); +} + inline XmlOutput::xml_output attr(const QString &name, const QString &value) { return attribute(name, value); } +inline XmlOutput::xml_output attrTag(const QString &name, + const QString &value) +{ + return attributeTag(name, value); +} + inline XmlOutput::xml_output data(const QString &text = QString()) { return XmlOutput::xml_output(XmlOutput::tData, text, QString()); diff --git a/qmake/qmake.pro b/qmake/qmake.pro index f3f9d53..4213253 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -19,7 +19,8 @@ VPATH += $$QT_SOURCE_TREE/src/corelib/global \ $$QT_SOURCE_TREE/src/corelib/plugin \ $$QT_SOURCE_TREE/src/corelib/xml \ $$QT_SOURCE_TREE/src/corelib/io -INCPATH += generators \ +INCPATH += . \ + generators \ generators/unix \ generators/win32 \ generators/mac \ |