Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
++
++ #include "msbuild_objectmodel.h"
++
++ #include "msvc_objectmodel.h"
++ #include "msvc_vcproj.h"
++ #include "msvc_vcxproj.h"
++ #include <qscopedpointer.h>
++ #include <qstringlist.h>
++ #include <qfileinfo.h>
++ #include <qregularexpression.h>
++ #include <qvarlengtharray.h>
++
++ QT_BEGIN_NAMESPACE
++
++ // XML Tags ---------------------------------------------------------
++ const char _CLCompile[] = "ClCompile";
++ const char _ItemGroup[] = "ItemGroup";
++ const char _Link[] = "Link";
++ const char _Lib[] = "Lib";
++ const char _Midl[] = "Midl";
++ const char _ResourceCompile[] = "ResourceCompile";
++
++ // XML Properties ---------------------------------------------------
++ const char _AddModuleNamesToAssembly[] = "AddModuleNamesToAssembly";
++ const char _AdditionalDependencies[] = "AdditionalDependencies";
++ 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 _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 _CompileAs[] = "CompileAs";
++ const char _CompileAsManaged[] = "CompileAsManaged";
++ const char _CompileAsWinRT[] = "CompileAsWinRT";
++ const char _ConfigurationType[] = "ConfigurationType";
++ const char _CPreprocessOptions[] = "CPreprocessOptions";
++ const char _CreateHotpatchableImage[] = "CreateHotpatchableImage";
++ const char _Culture[] = "Culture";
++ const char _DataExecutionPrevention[] = "DataExecutionPrevention";
++ const char _DebugInformationFormat[] = "DebugInformationFormat";
++ const char _DefaultCharType[] = "DefaultCharType";
++ const char _DelayLoadDLLs[] = "DelayLoadDLLs";
++ const char _DelaySign[] = "DelaySign";
++ const char _DeleteExtensionsOnClean[] = "DeleteExtensionsOnClean";
++ const char _DisableLanguageExtensions[] = "DisableLanguageExtensions";
++ const char _DisableSpecificWarnings[] = "DisableSpecificWarnings";
++ const char _DLLDataFileName[] = "DLLDataFileName";
++ const char _EmbedManagedResourceFile[] = "EmbedManagedResourceFile";
++ const char _EmbedManifest[] = "EmbedManifest";
++ const char _EnableCOMDATFolding[] = "EnableCOMDATFolding";
++ const char _EnableUAC[] = "EnableUAC";
++ const char _EnableErrorChecks[] = "EnableErrorChecks";
++ const char _EnableEnhancedInstructionSet[] = "EnableEnhancedInstructionSet";
++ const char _EnableFiberSafeOptimizations[] = "EnableFiberSafeOptimizations";
++ 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 _ExpandAttributedSource[] = "ExpandAttributedSource";
++ const char _ExportNamedFunctions[] = "ExportNamedFunctions";
++ const char _FavorSizeOrSpeed[] = "FavorSizeOrSpeed";
++ const char _FloatingPointModel[] = "FloatingPointModel";
++ const char _FloatingPointExceptions[] = "FloatingPointExceptions";
++ const char _ForceConformanceInForLoopScope[] = "ForceConformanceInForLoopScope";
++ const char _ForceSymbolReferences[] = "ForceSymbolReferences";
++ const char _ForcedIncludeFiles[] = "ForcedIncludeFiles";
++ const char _ForcedUsingFiles[] = "ForcedUsingFiles";
++ 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 _GenerateServerFiles[] = "GenerateServerFiles";
++ const char _GenerateStublessProxies[] = "GenerateStublessProxies";
++ const char _GenerateTypeLibrary[] = "GenerateTypeLibrary";
++ const char _GenerateWindowsMetadata[] = "GenerateWindowsMetadata";
++ const char _GenerateXMLDocumentationFiles[] = "GenerateXMLDocumentationFiles";
++ const char _HeaderFileName[] = "HeaderFileName";
++ const char _HeapCommitSize[] = "HeapCommitSize";
++ const char _HeapReserveSize[] = "HeapReserveSize";
++ const char _IgnoreAllDefaultLibraries[] = "IgnoreAllDefaultLibraries";
++ const char _IgnoreEmbeddedIDL[] = "IgnoreEmbeddedIDL";
++ const char _IgnoreImportLibrary[] = "IgnoreImportLibrary";
++ const char _ImageHasSafeExceptionHandlers[] = "ImageHasSafeExceptionHandlers";
++ const char _IgnoreSpecificDefaultLibraries[] = "IgnoreSpecificDefaultLibraries";
++ const char _IgnoreStandardIncludePath[] = "IgnoreStandardIncludePath";
++ const char _ImportLibrary[] = "ImportLibrary";
++ const char _InlineFunctionExpansion[] = "InlineFunctionExpansion";
++ const char _IntrinsicFunctions[] = "IntrinsicFunctions";
++ const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
++ const char _IntermediateDirectory[] = "IntermediateDirectory";
++ const char _KeyContainer[] = "KeyContainer";
++ const char _KeyFile[] = "KeyFile";
++ const char _LanguageStandard[] = "LanguageStandard";
++ const char _LanguageStandard_C[] = "LanguageStandard_C";
++ 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 _LocaleID[] = "LocaleID";
++ const char _ManifestFile[] = "ManifestFile";
++ const char _MapExports[] = "MapExports";
++ const char _MapFileName[] = "MapFileName";
++ 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 _MultiProcessorCompilation[] = "MultiProcessorCompilation";
++ const char _Name[] = "Name";
++ const char _NoEntryPoint[] = "NoEntryPoint";
++ const char _ObjectFileName[] = "ObjectFileName";
++ const char _OmitDefaultLibName[] = "OmitDefaultLibName";
++ const char _OmitFramePointers[] = "OmitFramePointers";
++ const char _OpenMPSupport[] = "OpenMPSupport";
++ const char _Optimization[] = "Optimization";
++ const char _OptimizeReferences[] = "OptimizeReferences";
++ const char _OutputDirectory[] = "OutputDirectory";
++ const char _OutputFile[] = "OutputFile";
++ const char _PlatformToolSet[] = "PlatformToolset";
++ const char _PrecompiledHeader[] = "PrecompiledHeader";
++ const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile";
++ const char _PrecompiledHeaderOutputFile[] = "PrecompiledHeaderOutputFile";
++ 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 _ProcessorNumber[] = "ProcessorNumber";
++ 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 _ResourceOutputFileName[] = "ResourceOutputFileName";
++ const char _RuntimeLibrary[] = "RuntimeLibrary";
++ const char _RuntimeTypeInfo[] = "RuntimeTypeInfo";
++ 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 _StackCommitSize[] = "StackCommitSize";
++ const char _StackReserveSize[] = "StackReserveSize";
++ const char _StringPooling[] = "StringPooling";
++ const char _StripPrivateSymbols[] = "StripPrivateSymbols";
++ const char _StructMemberAlignment[] = "StructMemberAlignment";
++ const char _SubSystem[] = "SubSystem";
++ 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 _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 _UseFullPaths[] = "UseFullPaths";
++ const char _UseOfATL[] = "UseOfATL";
++ const char _UseOfMfc[] = "UseOfMfc";
++ const char _UseUnicodeForAssemblerListing[] = "UseUnicodeForAssemblerListing";
++ const char _ValidateAllParameters[] = "ValidateAllParameters";
++ const char _Version[] = "Version";
++ const char _WarnAsError[] = "WarnAsError";
++ const char _WarningLevel[] = "WarningLevel";
++ const char _WholeProgramOptimization[] = "WholeProgramOptimization";
++ const char _WindowsMetadataFile[] = "WindowsMetadataFile";
++ 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");
++ }
++
++ static QString commandLinesForOutput(QStringList commands)
++ {
++ // MSBuild puts the contents of the custom commands into a batch file and calls it.
++ // As we want every sub-command to be error-checked (as is done by makefile-based
++ // backends), we insert the checks ourselves, using the undocumented jump target.
++ static QString errchk = QStringLiteral("if errorlevel 1 goto VCEnd");
++ for (int i = commands.size() - 2; i >= 0; --i) {
++ if (!commands.at(i).startsWith("rem", Qt::CaseInsensitive))
++ commands.insert(i + 1, errchk);
++ }
++ return commands.join("\r\n");
++ }
++
++ static QString unquote(const QString &value)
++ {
++ QString result = value;
++ result.replace(QLatin1String("\\\""), QLatin1String("\""));
++ return result;
++ }
++
++ static QStringList unquote(const QStringList &values)
++ {
++ QStringList result;
++ result.reserve(values.size());
++ for (int i = 0; i < values.size(); ++i)
++ result << unquote(values.at(i));
++ return result;
++ }
++
++ // Tree file generation ---------------------------------------------
++ void XTreeNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName,
++ VCProject &tool, const QString &filter)
++ {
++ if (children.size()) {
++ // Filter
++ QString tempFilterName;
++ ChildrenMap::ConstIterator it, end = children.constEnd();
++ if (!tagName.isEmpty()) {
++ tempFilterName.append(filter);
++ tempFilterName.append("\\");
++ tempFilterName.append(tagName);
++ xmlFilter << tag(_ItemGroup);
++ xmlFilter << tag("Filter")
++ << attrTag("Include", tempFilterName)
++ << closetag();
++ xmlFilter << closetag();
++ }
++ // First round, do nested filters
++ for (it = children.constBegin(); it != end; ++it)
++ if ((*it)->children.size())
++ {
++ if ( !tempFilterName.isEmpty() )
++ (*it)->generateXML(xml, xmlFilter, it.key(), tool, tempFilterName);
++ else
++ (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter);
++ }
++ // Second round, do leafs
++ for (it = children.constBegin(); it != end; ++it)
++ if (!(*it)->children.size())
++ {
++ if ( !tempFilterName.isEmpty() )
++ (*it)->generateXML(xml, xmlFilter, it.key(), tool, tempFilterName);
++ else
++ (*it)->generateXML(xml, xmlFilter, it.key(), tool, filter);
++ }
++ } else {
++ // Leaf
++ xml << tag(_ItemGroup);
++ xmlFilter << tag(_ItemGroup);
++ VCXProjectWriter::outputFileConfigs(tool, xml, xmlFilter, info, filter);
++ xmlFilter << closetag();
++ xml << closetag();
++ }
++ }
++
++ // Flat file generation ---------------------------------------------
++ void XFlatNode::generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &/*tagName*/,
++ VCProject &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) {
++ VCXProjectWriter::outputFileConfigs(tool, xml, xmlFilter, (*it), filter);
++ }
++ xml << closetag();
++ xmlFilter << closetag();
++ }
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
++ {
++ xml.setIndentString(" ");
++
++ xml << decl("1.0", "utf-8")
++ << tag("Project")
++ << attrTag("DefaultTargets","Build")
++ << attrTagToolsVersion(tool.Configuration)
++ << 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");
++
++ write(xml, tool.Configuration);
++ const QString condition = generateCondition(tool.Configuration);
++
++ xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
++
++ // Extension settings
++ xml << tag("ImportGroup")
++ << attrTag("Label", "ExtensionSettings")
++ << closetag();
++
++ // PropertySheets
++ xml << tag("ImportGroup")
++ << attrTag("Condition", condition)
++ << 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", condition)
++ << valueTag(tool.Configuration.OutputDirectory);
++ }
++ if ( !tool.Configuration.IntermediateDirectory.isEmpty() ) {
++ xml<< tag("IntDir")
++ << attrTag("Condition", condition)
++ << valueTag(tool.Configuration.IntermediateDirectory);
++ }
++ if ( !tool.Configuration.PrimaryOutput.isEmpty() ) {
++ xml<< tag("TargetName")
++ << attrTag("Condition", condition)
++ << valueTag(tool.Configuration.PrimaryOutput);
++ }
++ if (!tool.Configuration.PrimaryOutputExtension.isEmpty()) {
++ xml<< tag("TargetExt")
++ << attrTag("Condition", condition)
++ << valueTag(tool.Configuration.PrimaryOutputExtension);
++ }
++ if ( tool.Configuration.linker.IgnoreImportLibrary != unset) {
++ xml<< tag("IgnoreImportLibrary")
++ << attrTag("Condition", condition)
++ << valueTagT(tool.Configuration.linker.IgnoreImportLibrary);
++ }
++
++ if ( tool.Configuration.linker.LinkIncremental != linkIncrementalDefault) {
++ const triState ts = (tool.Configuration.linker.LinkIncremental == linkIncrementalYes ? _True : _False);
++ xml<< tag("LinkIncremental")
++ << attrTag("Condition", condition)
++ << valueTagT(ts);
++ }
++
++ if ( tool.Configuration.preBuild.ExcludedFromBuild != unset )
++ {
++ xml<< tag("PreBuildEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!tool.Configuration.preBuild.ExcludedFromBuild);
++ }
++
++ if ( tool.Configuration.preLink.ExcludedFromBuild != unset )
++ {
++ xml<< tag("PreLinkEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!tool.Configuration.preLink.ExcludedFromBuild);
++ }
++
++ if ( tool.Configuration.postBuild.ExcludedFromBuild != unset )
++ {
++ xml<< tag("PostBuildEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!tool.Configuration.postBuild.ExcludedFromBuild);
++ }
++ xml << closetag();
++
++ xml << tag("ItemDefinitionGroup")
++ << attrTag("Condition", condition);
++
++ // ClCompile
++ write(xml, tool.Configuration.compiler);
++
++ // Link
++ write(xml, tool.Configuration.linker);
++
++ // Midl
++ write(xml, tool.Configuration.idl);
++
++ // ResourceCompiler
++ write(xml, tool.Configuration.resource);
++
++ // Post build event
++ if ( tool.Configuration.postBuild.ExcludedFromBuild != unset )
++ write(xml, tool.Configuration.postBuild);
++
++ // Pre build event
++ if ( tool.Configuration.preBuild.ExcludedFromBuild != unset )
++ write(xml, tool.Configuration.preBuild);
++
++ // Pre link event
++ if ( tool.Configuration.preLink.ExcludedFromBuild != unset )
++ write(xml, tool.Configuration.preLink);
++
++ xml << closetag();
++
++ QFile filterFile;
++ filterFile.setFileName(Option::output.fileName().append(".filters"));
++ if (!filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
++ warn_msg(WarnLogic, "Generator: cannot open output filter file");
++ return;
++ }
++ QTextStream ts(&filterFile);
++ XmlOutput xmlFilter(ts, XmlOutput::NoConversion);
++
++ xmlFilter.setIndentString(" ");
++
++ xmlFilter << decl("1.0", "utf-8")
++ << tag("Project")
++ << attrTagToolsVersion(tool.Configuration)
++
++ xmlFilter << tag("ItemGroup");
++
++ VCProject tempProj;
++ tempProj.SingleProjects += tool;
++
++ addFilters(tempProj, xmlFilter, "Form Files");
++ addFilters(tempProj, xmlFilter, "Generated Files");
++ addFilters(tempProj, xmlFilter, "Header Files");
++ addFilters(tempProj, xmlFilter, "LexYacc Files");
++ addFilters(tempProj, xmlFilter, "Resource Files");
++ addFilters(tempProj, xmlFilter, "Source Files");
++ addFilters(tempProj, xmlFilter, "Translation Files");
++ addFilters(tempProj, xmlFilter, "Deployment Files");
++ addFilters(tempProj, xmlFilter, "Distribution Files");
++
++ tempProj.ExtraCompilers.reserve(tool.ExtraCompilersFiles.size());
++ std::transform(tool.ExtraCompilersFiles.cbegin(), tool.ExtraCompilersFiles.cend(),
++ std::back_inserter(tempProj.ExtraCompilers),
++ [] (const VCFilter &filter) { return filter.Name; });
++ tempProj.ExtraCompilers.removeDuplicates();
++
++ for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x)
++ addFilters(tempProj, xmlFilter, tempProj.ExtraCompilers.at(x));
++
++ xmlFilter << closetag();
++
++ outputFilter(tempProj, xml, xmlFilter, "Source Files");
++ outputFilter(tempProj, xml, xmlFilter, "Header Files");
++ outputFilter(tempProj, xml, xmlFilter, "Generated Files");
++ outputFilter(tempProj, xml, xmlFilter, "LexYacc Files");
++ outputFilter(tempProj, xml, xmlFilter, "Translation Files");
++ outputFilter(tempProj, xml, xmlFilter, "Form Files");
++ outputFilter(tempProj, xml, xmlFilter, "Resource Files");
++ outputFilter(tempProj, xml, xmlFilter, "Deployment Files");
++ outputFilter(tempProj, xml, xmlFilter, "Distribution Files");
++
++ for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x) {
++ outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x));
++ }
++
++ outputFilter(tempProj, xml, xmlFilter, "Root Files");
++
++ xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
++
++ xml << tag("ImportGroup")
++ << attrTag("Label", "ExtensionTargets")
++ << closetag();
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
++ {
++ if (tool.SingleProjects.size() == 0) {
++ warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output");
++ return;
++ }
++
++ xml.setIndentString(" ");
++
++ xml << decl("1.0", "utf-8")
++ << tag("Project")
++ << attrTag("DefaultTargets","Build")
++ << attrTagToolsVersion(tool.SingleProjects.first().Configuration)
++ << tag("ItemGroup")
++ << attrTag("Label", "ProjectConfigurations");
++
++ for (int i = 0; i < tool.SingleProjects.size(); ++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);
++
++ if (!tool.WindowsTargetPlatformVersion.isEmpty())
++ xml << tagValue("WindowsTargetPlatformVersion", tool.WindowsTargetPlatformVersion);
++ if (!tool.WindowsTargetPlatformMinVersion.isEmpty())
++ xml << tagValue("WindowsTargetPlatformMinVersion", tool.WindowsTargetPlatformMinVersion);
++
++ xml << closetag();
++
++ // config part.
++ xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
++ for (int i = 0; i < tool.SingleProjects.size(); ++i)
++ write(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.size(); ++i) {
++ xml << tag("ImportGroup")
++ << attrTag("Condition", generateCondition(tool.SingleProjects.at(i).Configuration))
++ << 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.size(); ++i) {
++ const VCConfiguration &config = tool.SingleProjects.at(i).Configuration;
++ const QString condition = generateCondition(config);
++
++ if (!config.OutputDirectory.isEmpty()) {
++ xml << tag("OutDir")
++ << attrTag("Condition", condition)
++ << valueTag(config.OutputDirectory);
++ }
++ if (!config.IntermediateDirectory.isEmpty()) {
++ xml << tag("IntDir")
++ << attrTag("Condition", condition)
++ << valueTag(config.IntermediateDirectory);
++ }
++ if (!config.PrimaryOutput.isEmpty()) {
++ xml << tag("TargetName")
++ << attrTag("Condition", condition)
++ << valueTag(config.PrimaryOutput);
++ }
++ if (!config.PrimaryOutputExtension.isEmpty()) {
++ xml << tag("TargetExt")
++ << attrTag("Condition", condition)
++ << valueTag(config.PrimaryOutputExtension);
++ }
++ if (config.linker.IgnoreImportLibrary != unset) {
++ xml << tag("IgnoreImportLibrary")
++ << attrTag("Condition", condition)
++ << valueTagT(config.linker.IgnoreImportLibrary);
++ }
++
++ if (config.linker.LinkIncremental != linkIncrementalDefault) {
++ const triState ts = (config.linker.LinkIncremental == linkIncrementalYes ? _True : _False);
++ xml << tag("LinkIncremental")
++ << attrTag("Condition", condition)
++ << valueTagT(ts);
++ }
++
++ const triState generateManifest = config.linker.GenerateManifest;
++ if (generateManifest != unset) {
++ xml << tag("GenerateManifest")
++ << attrTag("Condition", condition)
++ << valueTagT(generateManifest);
++ }
++
++ if (config.preBuild.ExcludedFromBuild != unset)
++ {
++ xml << tag("PreBuildEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!config.preBuild.ExcludedFromBuild);
++ }
++
++ if (config.preLink.ExcludedFromBuild != unset)
++ {
++ xml << tag("PreLinkEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!config.preLink.ExcludedFromBuild);
++ }
++
++ if (config.postBuild.ExcludedFromBuild != unset)
++ {
++ xml << tag("PostBuildEventUseInBuild")
++ << attrTag("Condition", condition)
++ << valueTagT(!config.postBuild.ExcludedFromBuild);
++ }
++ }
++ xml << closetag();
++
++ for (int i = 0; i < tool.SingleProjects.size(); ++i) {
++ const VCConfiguration &config = tool.SingleProjects.at(i).Configuration;
++
++ xml << tag("ItemDefinitionGroup")
++ << attrTag("Condition", generateCondition(config));
++
++ // ClCompile
++ write(xml, config.compiler);
++
++ // Librarian / Linker
++ if (config.ConfigurationType == typeStaticLibrary)
++ write(xml, config.librarian);
++ else
++ write(xml, config.linker);
++
++ // Midl
++ write(xml, config.idl);
++
++ // ResourceCompiler
++ write(xml, config.resource);
++
++ // Post build event
++ if (config.postBuild.ExcludedFromBuild != unset)
++ write(xml, config.postBuild);
++
++ // Pre build event
++ if (config.preBuild.ExcludedFromBuild != unset)
++ write(xml, config.preBuild);
++
++ // Pre link event
++ if (config.preLink.ExcludedFromBuild != unset)
++ write(xml, config.preLink);
++
++ xml << closetag();
++
++ // windeployqt
++ if (!config.windeployqt.ExcludedFromBuild)
++ write(xml, config.windeployqt);
++ }
++
++ // The file filters are added in a separate file for MSBUILD.
++ QFile filterFile;
++ filterFile.setFileName(Option::output.fileName().append(".filters"));
++ if (!filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
++ warn_msg(WarnLogic, "Cannot open output filter file");
++ return;
++ }
++ QTextStream ts(&filterFile);
++ XmlOutput xmlFilter(ts, XmlOutput::NoConversion);
++
++ xmlFilter.setIndentString(" ");
++
++ xmlFilter << decl("1.0", "utf-8")
++ << tag("Project")
++ << attrTagToolsVersion(tool.SingleProjects.first().Configuration)
++
++ xmlFilter << tag("ItemGroup");
++
++ addFilters(tool, xmlFilter, "Form Files");
++ addFilters(tool, xmlFilter, "Generated Files");
++ addFilters(tool, xmlFilter, "Header Files");
++ addFilters(tool, xmlFilter, "LexYacc Files");
++ addFilters(tool, xmlFilter, "Resource Files");
++ addFilters(tool, xmlFilter, "Source Files");
++ addFilters(tool, xmlFilter, "Translation Files");
++ addFilters(tool, xmlFilter, "Deployment Files");
++ addFilters(tool, xmlFilter, "Distribution Files");
++
++ for (int x = 0; x < tool.ExtraCompilers.size(); ++x)
++ addFilters(tool, xmlFilter, tool.ExtraCompilers.at(x));
++
++ xmlFilter << closetag();
++
++ outputFilter(tool, xml, xmlFilter, "Source Files");
++ outputFilter(tool, xml, xmlFilter, "Header Files");
++ outputFilter(tool, xml, xmlFilter, "Generated Files");
++ outputFilter(tool, xml, xmlFilter, "LexYacc Files");
++ outputFilter(tool, xml, xmlFilter, "Translation Files");
++ outputFilter(tool, xml, xmlFilter, "Form Files");
++ outputFilter(tool, xml, xmlFilter, "Resource Files");
++ outputFilter(tool, xml, xmlFilter, "Deployment Files");
++ outputFilter(tool, xml, xmlFilter, "Distribution Files");
++ for (int x = 0; x < tool.ExtraCompilers.size(); ++x) {
++ outputFilter(tool, xml, xmlFilter, tool.ExtraCompilers.at(x));
++ }
++ outputFilter(tool, xml, xmlFilter, "Root Files");
++
++ xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets")
++ << tag("ImportGroup")
++ << attrTag("Label", "ExtensionTargets")
++ << closetag();
++ }
++
++ static inline QString toString(asmListingOption option)
++ {
++ switch (option) {
++ case asmListingNone:
++ break;
++ case asmListingAsmMachine:
++ return "AssemblyAndMachineCode";
++ case asmListingAsmMachineSrc:
++ return "All";
++ case asmListingAsmSrc:
++ return "AssemblyAndSourceCode";
++ case asmListingAssemblyOnly:
++ return "AssemblyCode";
++ }
++ return QString();
++ }
++
++ static inline QString toString(basicRuntimeCheckOption option)
++ {
++ switch (option) {
++ case runtimeBasicCheckNone:
++ return "";
++ case runtimeCheckStackFrame:
++ return "StackFrameRuntimeCheck";
++ case runtimeCheckUninitVariables:
++ return "UninitializedLocalUsageCheck";
++ case runtimeBasicCheckAll:
++ return "EnableFastChecks";
++ }
++ return QString();
++ }
++
++ static inline QString toString(callingConventionOption option)
++ {
++ switch (option) {
++ case callConventionDefault:
++ break;
++ case callConventionCDecl:
++ return "Cdecl";
++ case callConventionFastCall:
++ return "FastCall";
++ case callConventionStdCall:
++ return "StdCall";
++ }
++ return QString();
++ }
++
++ static inline QString toString(CompileAsOptions option)
++ {
++ switch (option) {
++ case compileAsDefault:
++ break;
++ case compileAsC:
++ return "CompileAsC";
++ case compileAsCPlusPlus:
++ return "CompileAsCpp";
++ }
++ return QString();
++ }
++
++ static inline QString toString(compileAsManagedOptions option)
++ {
++ switch (option) {
++ case managedDefault:
++ case managedAssemblySafe:
++ break;
++ case managedAssembly:
++ return "true";
++ case managedAssemblyPure:
++ return "Safe";
++ case managedAssemblyOldSyntax:
++ return "OldSyntax";
++ }
++ return QString();
++ }
++
++ static inline QString toString(debugOption option, DotNET compilerVersion)
++ {
++ switch (option) {
++ case debugUnknown:
++ case debugLineInfoOnly:
++ break;
++ case debugDisabled:
++ if (compilerVersion <= NET2010)
++ break;
++ return "None";
++ case debugOldStyleInfo:
++ return "OldStyle";
++ case debugEditAndContinue:
++ return "EditAndContinue";
++ case debugEnabled:
++ return "ProgramDatabase";
++ }
++ return QString();
++ }
++
++ static inline QString toString(enhancedInstructionSetOption option)
++ {
++ switch (option) {
++ case archNotSet:
++ break;
++ case archSSE:
++ return "StreamingSIMDExtensions";
++ case archSSE2:
++ return "StreamingSIMDExtensions2";
++ }
++ return QString();
++ }
++
++ static inline QString toString(exceptionHandling option)
++ {
++ switch (option) {
++ case ehDefault:
++ break;
++ case ehNone:
++ return "false";
++ case ehNoSEH:
++ return "Sync";
++ case ehSEH:
++ return "Async";
++ }
++ return QString();
++ }
++
++ static inline QString toString(favorSizeOrSpeedOption option)
++ {
++ switch (option) {
++ case favorNone:
++ break;
++ case favorSize:
++ return "Size";
++ case favorSpeed:
++ return "Speed";
++ }
++ return QString();
++ }
++
++ static inline QString toString(floatingPointModel option)
++ {
++ switch (option) {
++ case floatingPointNotSet:
++ break;
++ case floatingPointFast:
++ return "Fast";
++ case floatingPointPrecise:
++ return "Precise";
++ case floatingPointStrict:
++ return "Strict";
++ }
++ return QString();
++ }
++
++ static inline QString toString(inlineExpansionOption option)
++ {
++ switch (option) {
++ case expandDefault:
++ break;
++ case expandDisable:
++ return "Disabled";
++ case expandOnlyInline:
++ return "OnlyExplicitInline";
++ case expandAnySuitable:
++ return "AnySuitable";
++ }
++ return QString();
++ }
++
++ static inline QString toString(optimizeOption option)
++ {
++ switch (option) {
++ case optimizeCustom:
++ case optimizeDefault:
++ break;
++ case optimizeDisabled:
++ return "Disabled";
++ case optimizeMinSpace:
++ return "MinSpace";
++ case optimizeMaxSpeed:
++ return "MaxSpeed";
++ case optimizeFull:
++ return "Full";
++ }
++ return QString();
++ }
++
++ static inline QString toString(pchOption option)
++ {
++ switch (option) {
++ case pchUnset:
++ case pchGenerateAuto:
++ break;
++ case pchNone:
++ return "NotUsing";
++ case pchCreateUsingSpecific:
++ return "Create";
++ case pchUseUsingSpecific:
++ return "Use";
++ }
++ return QString();
++ }
++
++ static inline QString toString(runtimeLibraryOption option)
++ {
++ switch (option) {
++ case rtUnknown:
++ case rtSingleThreaded:
++ case rtSingleThreadedDebug:
++ break;
++ case rtMultiThreaded:
++ return "MultiThreaded";
++ case rtMultiThreadedDLL:
++ return "MultiThreadedDLL";
++ case rtMultiThreadedDebug:
++ return "MultiThreadedDebug";
++ case rtMultiThreadedDebugDLL:
++ return "MultiThreadedDebugDLL";
++ }
++ return QString();
++ }
++
++ static inline QString toString(structMemberAlignOption option)
++ {
++ switch (option) {
++ case alignNotSet:
++ break;
++ case alignSingleByte:
++ return "1Byte";
++ case alignTwoBytes:
++ return "2Bytes";
++ case alignFourBytes:
++ return "4Bytes";
++ case alignEightBytes:
++ return "8Bytes";
++ case alignSixteenBytes:
++ return "16Bytes";
++ }
++ return QString();
++ }
++
++ static inline QString toString(warningLevelOption option)
++ {
++ switch (option) {
++ case warningLevelUnknown:
++ break;
++ case warningLevel_0:
++ return "TurnOffAllWarnings";
++ case warningLevel_1:
++ return "Level1";
++ case warningLevel_2:
++ return "Level2";
++ case warningLevel_3:
++ return "Level3";
++ case warningLevel_4:
++ return "Level4";
++ }
++ return QString();
++ }
++
++ static inline QString toString(optLinkTimeCodeGenType option)
++ {
++ switch (option) {
++ case optLTCGDefault:
++ break;
++ case optLTCGEnabled:
++ return "UseLinkTimeCodeGeneration";
++ case optLTCGIncremental:
++ return "UseFastLinkTimeCodeGeneration";
++ case optLTCGInstrument:
++ return "PGInstrument";
++ case optLTCGOptimize:
++ return "PGOptimization";
++ case optLTCGUpdate:
++ return "PGUpdate";
++ }
++ return QString();
++ }
++
++ static inline QString toString(subSystemOption option)
++ {
++ switch (option) {
++ case subSystemNotSet:
++ break;
++ case subSystemConsole:
++ return "Console";
++ case subSystemWindows:
++ return "Windows";
++ }
++ return QString();
++ }
++
++ static inline QString toString(triState genDebugInfo, linkerDebugOption option)
++ {
++ switch (genDebugInfo) {
++ case unset:
++ break;
++ case _False:
++ return "false";
++ case _True:
++ if (option == linkerDebugOptionFastLink)
++ return "DebugFastLink";
++ else if (option == linkerDebugOptionFull)
++ return "DebugFull";
++ return "true";
++ }
++ return QString();
++ }
++
++ static inline QString toString(machineTypeOption option)
++ {
++ switch (option) {
++ case machineNotSet:
++ break;
++ case machineX86:
++ return "MachineX86";
++ case machineX64:
++ return "MachineX64";
++ }
++ return QString();
++ }
++
++ static inline QString toString(midlCharOption option)
++ {
++ switch (option) {
++ case midlCharUnsigned:
++ return "Unsigned";
++ case midlCharSigned:
++ return "Signed";
++ case midlCharAscii7:
++ return "Ascii";
++ }
++ return QString();
++ }
++
++ static inline QString toString(midlErrorCheckOption option)
++ {
++ switch (option) {
++ case midlEnableCustom:
++ break;
++ case midlDisableAll:
++ return "None";
++ case midlEnableAll:
++ return "All";
++ }
++ return QString();
++ }
++
++ static inline QString toString(midlStructMemberAlignOption option)
++ {
++ switch (option) {
++ case midlAlignNotSet:
++ break;
++ case midlAlignSingleByte:
++ return "1";
++ case midlAlignTwoBytes:
++ return "2";
++ case midlAlignFourBytes:
++ return "4";
++ case midlAlignEightBytes:
++ return "8";
++ case midlAlignSixteenBytes:
++ return "16";
++ }
++ return QString();
++ }
++
++ static inline QString toString(midlTargetEnvironment option)
++ {
++ switch (option) {
++ case midlTargetNotSet:
++ break;
++ case midlTargetWin32:
++ return "Win32";
++ case midlTargetWin64:
++ return "X64";
++ }
++ return QString();
++ }
++
++ static inline QString toString(midlWarningLevelOption option)
++ {
++ switch (option) {
++ case midlWarningLevel_0:
++ return "0";
++ case midlWarningLevel_1:
++ return "1";
++ case midlWarningLevel_2:
++ return "2";
++ case midlWarningLevel_3:
++ return "3";
++ case midlWarningLevel_4:
++ return "4";
++ }
++ return QString();
++ }
++
++ static inline QString toString(enumResourceLangID option)
++ {
++ if (option == 0)
++ return QString();
++ else
++ return QString::number(qlonglong(option));
++ }
++
++ static inline QString toString(charSet option)
++ {
++ switch (option) {
++ case charSetNotSet:
++ return "NotSet";
++ case charSetUnicode:
++ return "Unicode";
++ case charSetMBCS:
++ return "MultiByte";
++ }
++ return QString();
++ }
++
++ static inline QString toString(ConfigurationTypes option)
++ {
++ switch (option) {
++ case typeUnknown:
++ case typeGeneric:
++ break;
++ case typeApplication:
++ return "Application";
++ case typeDynamicLibrary:
++ return "DynamicLibrary";
++ case typeStaticLibrary:
++ return "StaticLibrary";
++ }
++ return QString();
++ }
++
++ static inline QString toString(useOfATL option)
++ {
++ switch (option) {
++ case useATLNotSet:
++ break;
++ case useATLStatic:
++ return "Static";
++ case useATLDynamic:
++ return "Dynamic";
++ }
++ return QString();
++ }
++
++ static inline QString toString(useOfMfc option)
++ {
++ switch (option) {
++ case useMfcStdWin:
++ break;
++ case useMfcStatic:
++ return "Static";
++ case useMfcDynamic:
++ return "Dynamic";
++ }
++ return QString();
++ }
++
++ static inline triState toTriState(browseInfoOption option)
++ {
++ switch (option)
++ {
++ case brInfoNone:
++ return _False;
++ case brAllInfo:
++ case brNoLocalSymbols:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(preprocessOption option)
++ {
++ switch (option)
++ {
++ case preprocessUnknown:
++ break;
++ case preprocessNo:
++ return _False;
++ case preprocessNoLineNumbers:
++ case preprocessYes:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(optFoldingType option)
++ {
++ switch (option)
++ {
++ case optFoldingDefault:
++ break;
++ case optNoFolding:
++ return _False;
++ case optFolding:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(addressAwarenessType option)
++ {
++ switch (option)
++ {
++ case addrAwareDefault:
++ return unset;
++ case addrAwareNoLarge:
++ return _False;
++ case addrAwareLarge:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(linkIncrementalType option)
++ {
++ switch (option)
++ {
++ case linkIncrementalDefault:
++ return unset;
++ case linkIncrementalNo:
++ return _False;
++ case linkIncrementalYes:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(linkProgressOption option)
++ {
++ switch (option)
++ {
++ case linkProgressNotSet:
++ return unset;
++ case linkProgressAll:
++ case linkProgressLibs:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(optRefType option)
++ {
++ switch (option)
++ {
++ case optReferencesDefault:
++ return unset;
++ case optNoReferences:
++ return _False;
++ case optReferences:
++ return _True;
++ }
++ return unset;
++ }
++
++ static inline triState toTriState(termSvrAwarenessType option)
++ {
++ switch (option)
++ {
++ case termSvrAwareDefault:
++ return unset;
++ case termSvrAwareNo:
++ return _False;
++ case termSvrAwareYes:
++ return _True;
++ }
++ return unset;
++ }
++
++ static XmlOutput::xml_output fixedProgramDataBaseFileNameOutput(const VCCLCompilerTool &tool)
++ {
++ if (tool.config->CompilerVersion >= NET2012
++ && tool.DebugInformationFormat == debugDisabled
++ && tool.ProgramDataBaseFileName.isEmpty()) {
++ // Force the creation of an empty tag to work-around Visual Studio bug. See QTBUG-35570.
++ return tagValue(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName);
++ }
++ return attrTagS(_ProgramDataBaseFileName, tool.ProgramDataBaseFileName);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
++ {
++ xml
++ << tag(_CLCompile)
++ << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";")
++ << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ")
++ << attrTagX(_AdditionalUsingDirectories, tool.AdditionalUsingDirectories, ";")
++ << attrTagS(_AssemblerListingLocation, tool.AssemblerListingLocation)
++ << attrTagS(_AssemblerOutput, toString(tool.AssemblerOutput))
++ << attrTagS(_BasicRuntimeChecks, toString(tool.BasicRuntimeChecks))
++ << attrTagT(_BrowseInformation, toTriState(tool.BrowseInformation))
++ << attrTagS(_BrowseInformationFile, tool.BrowseInformationFile)
++ << attrTagT(_BufferSecurityCheck, tool.BufferSecurityCheck)
++ << attrTagS(_CallingConvention, toString(tool.CallingConvention))
++ << attrTagS(_CompileAs, toString(tool.CompileAs))
++ << attrTagS(_CompileAsManaged, toString(tool.CompileAsManaged))
++ << attrTagT(_CompileAsWinRT, tool.CompileAsWinRT)
++ << attrTagT(_CreateHotpatchableImage, tool.CreateHotpatchableImage)
++ << attrTagS(_DebugInformationFormat, toString(tool.DebugInformationFormat,
++ tool.config->CompilerVersion))
++ << attrTagT(_DisableLanguageExtensions, tool.DisableLanguageExtensions)
++ << attrTagX(_DisableSpecificWarnings, tool.DisableSpecificWarnings, ";")
++ << attrTagS(_EnableEnhancedInstructionSet, toString(tool.EnableEnhancedInstructionSet))
++ << attrTagT(_EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations)
++ << attrTagT(_EnablePREfast, tool.EnablePREfast)
++ << attrTagS(_ErrorReporting, tool.ErrorReporting)
++ << attrTagS(_ExceptionHandling, toString(tool.ExceptionHandling))
++ << attrTagT(_ExpandAttributedSource, tool.ExpandAttributedSource)
++ << attrTagS(_FavorSizeOrSpeed, toString(tool.FavorSizeOrSpeed))
++ << attrTagT(_FloatingPointExceptions, tool.FloatingPointExceptions)
++ << attrTagS(_FloatingPointModel, toString(tool.FloatingPointModel))
++ << attrTagT(_ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope)
++ << attrTagX(_ForcedIncludeFiles, tool.ForcedIncludeFiles, ";")
++ << attrTagX(_ForcedUsingFiles, tool.ForcedUsingFiles, ";")
++ << attrTagT(_FunctionLevelLinking, tool.EnableFunctionLevelLinking)
++ << attrTagT(_GenerateXMLDocumentationFiles, tool.GenerateXMLDocumentationFiles)
++ << attrTagT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
++ << attrTagS(_InlineFunctionExpansion, toString(tool.InlineFunctionExpansion))
++ << attrTagT(_IntrinsicFunctions, tool.EnableIntrinsicFunctions)
++ << attrTagT(_MinimalRebuild, tool.MinimalRebuild)
++ << attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation)
++ << attrTagS(_LanguageStandard, tool.LanguageStandard)
++ << attrTagS(_LanguageStandard_C, tool.LanguageStandard_C)
++ << attrTagS(_ObjectFileName, tool.ObjectFile)
++ << attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName)
++ << attrTagT(_OmitFramePointers, tool.OmitFramePointers)
++ << attrTagT(_OpenMPSupport, tool.OpenMP)
++ << attrTagS(_Optimization, toString(tool.Optimization))
++ << attrTagS(_PrecompiledHeader, toString(tool.UsePrecompiledHeader))
++ << attrTagS(_PrecompiledHeaderFile, tool.PrecompiledHeaderThrough)
++ << attrTagS(_PrecompiledHeaderOutputFile, tool.PrecompiledHeaderFile)
++ << attrTagT(_PreprocessKeepComments, tool.KeepComments)
++ << attrTagX(_PreprocessorDefinitions, unquote(tool.PreprocessorDefinitions), ";")
++ << attrTagS(_PreprocessOutputPath, tool.PreprocessOutputPath)
++ << attrTagT(_PreprocessSuppressLineNumbers, tool.PreprocessSuppressLineNumbers)
++ << attrTagT(_PreprocessToFile, toTriState(tool.GeneratePreprocessedFile))
++ << fixedProgramDataBaseFileNameOutput(tool)
++ << attrTagS(_ProcessorNumber, tool.MultiProcessorCompilationProcessorCount)
++ << attrTagS(_RuntimeLibrary, toString(tool.RuntimeLibrary))
++ << attrTagT(_RuntimeTypeInfo, tool.RuntimeTypeInfo)
++ << attrTagT(_ShowIncludes, tool.ShowIncludes)
++ << attrTagT(_SmallerTypeCheck, tool.SmallerTypeCheck)
++ << attrTagT(_StringPooling, tool.StringPooling)
++ << attrTagS(_StructMemberAlignment, toString(tool.StructMemberAlignment))
++ << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner)
++ << attrTagX(_TreatSpecificWarningsAsErrors, tool.TreatSpecificWarningsAsErrors, ";")
++ << attrTagT(_TreatWarningAsError, tool.WarnAsError)
++ << attrTagT(_TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType)
++ << attrTagT(_UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions)
++ << attrTagX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions, ";")
++ << attrTagT(_UseFullPaths, tool.DisplayFullPaths)
++ << attrTagT(_UseUnicodeForAssemblerListing, tool.UseUnicodeForAssemblerListing)
++ << attrTagS(_WarningLevel, toString(tool.WarningLevel))
++ << attrTagT(_WholeProgramOptimization, tool.WholeProgramOptimization)
++ << attrTagS(_XMLDocumentationFileName, tool.XMLDocumentationFileName)
++ << closetag(_CLCompile);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
++ {
++ 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)
++ << attrTagT(_CLRUnmanagedCodeCheck, tool.CLRUnmanagedCodeCheck)
++ << attrTagT(_DataExecutionPrevention, tool.DataExecutionPrevention)
++ << attrTagX(_DelayLoadDLLs, tool.DelayLoadDLLs, ";")
++ << attrTagT(_DelaySign, tool.DelaySign)
++ << attrTagS(_EmbedManagedResourceFile, tool.LinkToManagedResourceFile)
++ << attrTagT(_EnableCOMDATFolding, toTriState(tool.EnableCOMDATFolding))
++ << attrTagT(_EnableUAC, tool.EnableUAC)
++ << attrTagS(_EntryPointSymbol, tool.EntryPointSymbol)
++ << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";")
++ << attrTagS(_FunctionOrder, tool.FunctionOrder)
++ << attrTagS(_GenerateDebugInformation, toString(tool.GenerateDebugInformation, tool.DebugInfoOption))
++ << attrTagT(_GenerateManifest, tool.GenerateManifest)
++ << attrTagT(_GenerateWindowsMetadata, tool.GenerateWindowsMetadata)
++ << attrTagS(_WindowsMetadataFile, tool.GenerateWindowsMetadata == _True ? tool.WindowsMetadataFile : QString())
++ << 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)
++ << attrTagT(_ImageHasSafeExceptionHandlers, tool.ImageHasSafeExceptionHandlers)
++ << attrTagX(_IgnoreSpecificDefaultLibraries, tool.IgnoreDefaultLibraryNames, ";")
++ << attrTagS(_ImportLibrary, tool.ImportLibrary)
++ << attrTagS(_KeyContainer, tool.KeyContainer)
++ << attrTagS(_KeyFile, tool.KeyFile)
++ << attrTagT(_LargeAddressAware, toTriState(tool.LargeAddressAware))
++ << attrTagT(_LinkDLL, (tool.config->ConfigurationType == typeDynamicLibrary ? _True : unset))
++ << attrTagS(_LinkErrorReporting, tool.LinkErrorReporting)
++ << attrTagT(_LinkIncremental, toTriState(tool.LinkIncremental))
++ << attrTagT(_LinkStatus, toTriState(tool.ShowProgress))
++ << attrTagS(_LinkTimeCodeGeneration, toString(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)
++ << attrTagT(_NoEntryPoint, tool.ResourceOnlyDLL)
++ << attrTagT(_OptimizeReferences, toTriState(tool.OptimizeReferences))
++ << attrTagS(_OutputFile, tool.OutputFile)
++ << attrTagT(_PreventDllBinding, tool.PreventDllBinding)
++ << attrTagS(_ProgramDatabaseFile, tool.ProgramDatabaseFile)
++ << attrTagT(_RandomizedBaseAddress, tool.RandomizedBaseAddress)
++ << attrTagT(_RegisterOutput, tool.RegisterOutput)
++ << attrTagL(_SectionAlignment, tool.SectionAlignment, /*ifNot*/ -1)
++ << attrTagT(_SetChecksum, tool.SetChecksum)
++ << attrTagL(_StackCommitSize, tool.StackCommitSize, /*ifNot*/ -1)
++ << attrTagL(_StackReserveSize, tool.StackReserveSize, /*ifNot*/ -1)
++ << attrTagS(_StripPrivateSymbols, tool.StripPrivateSymbols)
++ << attrTagS(_SubSystem, toString(tool.SubSystem))
++ // << attrTagT(_SupportNobindOfDelayLoadedDLL, tool.SupportNobindOfDelayLoadedDLL)
++ << attrTagT(_SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL)
++ << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner)
++ << attrTagT(_SwapRunFromCD, tool.SwapRunFromCD)
++ << attrTagT(_SwapRunFromNet, tool.SwapRunFromNet)
++ << attrTagS(_TargetMachine, toString(tool.TargetMachine))
++ << attrTagT(_TerminalServerAware, toTriState(tool.TerminalServerAware))
++ << attrTagT(_TreatLinkerWarningAsErrors, tool.TreatWarningsAsErrors)
++ << 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);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCMIDLTool &tool)
++ {
++ xml
++ << tag(_Midl)
++ << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";")
++ << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ")
++ << attrTagT(_ApplicationConfigurationMode, tool.ApplicationConfigurationMode)
++ << attrTagS(_ClientStubFile, tool.ClientStubFile)
++ << attrTagX(_CPreprocessOptions, tool.CPreprocessOptions, " ")
++ << attrTagS(_DefaultCharType, toString(tool.DefaultCharType))
++ << attrTagS(_DLLDataFileName, tool.DLLDataFileName)
++ << attrTagS(_EnableErrorChecks, toString(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, toString(tool.StructMemberAlignment))
++ << attrTagT(_SuppressCompilerWarnings, tool.SuppressCompilerWarnings)
++ << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner)
++ << attrTagS(_TargetEnvironment, toString(tool.TargetEnvironment))
++ << attrTagS(_TypeLibFormat, tool.TypeLibFormat)
++ << attrTagS(_TypeLibraryName, tool.TypeLibraryName)
++ << attrTagX(_UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions, ";")
++ << attrTagT(_ValidateAllParameters, tool.ValidateAllParameters)
++ << attrTagT(_WarnAsError, tool.WarnAsError)
++ << attrTagS(_WarningLevel, toString(tool.WarningLevel))
++ << closetag(_Midl);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
++ {
++ const QString condition = generateCondition(*tool.config);
++
++ if ( !tool.AdditionalDependencies.isEmpty() )
++ {
++ xml << tag("AdditionalInputs")
++ << attrTag("Condition", condition)
++ << valueTagDefX(tool.AdditionalDependencies, "AdditionalInputs", ";");
++ }
++
++ if( !tool.CommandLine.isEmpty() )
++ {
++ xml << tag("Command")
++ << attrTag("Condition", condition)
++ << valueTag(commandLinesForOutput(tool.CommandLine));
++ }
++
++ if ( !tool.Description.isEmpty() )
++ {
++ xml << tag("Message")
++ << attrTag("Condition", condition)
++ << valueTag(tool.Description);
++ }
++
++ if ( !tool.Outputs.isEmpty() )
++ {
++ xml << tag("Outputs")
++ << attrTag("Condition", condition)
++ << valueTagDefX(tool.Outputs, "Outputs", ";");
++ }
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
++ {
++ xml
++ << tag(_Lib)
++ << attrTagX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
++ << attrTagX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories, ";")
++ << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ")
++ << attrTagX(_ExportNamedFunctions, tool.ExportNamedFunctions, ";")
++ << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";")
++ << attrTagT(_IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries)
++ << attrTagX(_IgnoreSpecificDefaultLibraries, tool.IgnoreDefaultLibraryNames, ";")
++ << attrTagS(_ModuleDefinitionFile, tool.ModuleDefinitionFile)
++ << attrTagS(_OutputFile, tool.OutputFile)
++ << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner)
++ << closetag(_Lib);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCResourceCompilerTool &tool)
++ {
++ xml
++ << tag(_ResourceCompile)
++ << attrTagX(_AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories, ";")
++ << attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ")
++ << attrTagS(_Culture, toString(tool.Culture))
++ << attrTagT(_IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath)
++ << attrTagX(_PreprocessorDefinitions, tool.PreprocessorDefinitions, ";")
++ << attrTagS(_ResourceOutputFileName, tool.ResourceOutputFileName)
++ << attrTagT(_ShowProgress, toTriState(tool.ShowProgress))
++ << attrTagT(_SuppressStartupBanner, tool.SuppressStartupBanner)
++ << closetag(_ResourceCompile);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCEventTool &tool)
++ {
++ xml
++ << tag(tool.EventName)
++ << tag(_Command) << valueTag(commandLinesForOutput(tool.CommandLine))
++ << tag(_Message) << valueTag(tool.Description)
++ << closetag(tool.EventName);
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
++ {
++ Q_UNUSED(xml);
++ Q_UNUSED(tool);
++ // SmartDevice deployment not supported in VS 2010
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
++ {
++ const QString name = QStringLiteral("WinDeployQt_") + tool.config->Name;
++ xml << tag("Target")
++ << attrTag(_Name, name)
++ << attrTag("Condition", generateCondition(*tool.config))
++ << attrTag("Inputs", "$(OutDir)\\$(TargetName).exe")
++ << attrTag("Outputs", tool.Record)
++ << tag(_Message)
++ << attrTag("Text", tool.CommandLine)
++ << closetag()
++ << tag("Exec")
++ << attrTag("Command", tool.CommandLine)
++ << closetag()
++ << closetag()
++ << tag("Target")
++ << attrTag(_Name, QStringLiteral("PopulateWinDeployQtItems_") + tool.config->Name)
++ << attrTag("Condition", generateCondition(*tool.config))
++ << attrTag("AfterTargets", "Link")
++ << attrTag("DependsOnTargets", name)
++ << tag("ReadLinesFromFile")
++ << attrTag("File", tool.Record)
++ << tag("Output")
++ << attrTag("TaskParameter", "Lines")
++ << attrTag("ItemName", "DeploymentItems")
++ << closetag()
++ << closetag()
++ << tag(_ItemGroup)
++ << tag("None")
++ << attrTag("Include", "@(DeploymentItems)")
++ << attrTagT("DeploymentContent", _True)
++ << closetag()
++ << closetag()
++ << closetag();
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
++ {
++ xml << tag("PropertyGroup")
++ << attrTag("Condition", generateCondition(tool))
++ << attrTag("Label", "Configuration")
++ << attrTagS(_PlatformToolSet, tool.PlatformToolSet)
++ << attrTagS(_OutputDirectory, tool.OutputDirectory)
++ << attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
++ << attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation)
++ << attrTagS(_CharacterSet, toString(tool.CharacterSet))
++ << attrTagS(_ConfigurationType, toString(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, toString(tool.UseOfATL))
++ << attrTagS(_UseOfMfc, toString(tool.UseOfMfc))
++ << attrTagT(_WholeProgramOptimization, tool.WholeProgramOptimization)
++ << attrTagT(_EmbedManifest, tool.manifestTool.EmbedManifest)
++ << closetag();
++ }
++
++ void VCXProjectWriter::write(XmlOutput &xml, VCFilter &tool)
++ {
++ Q_UNUSED(xml);
++ Q_UNUSED(tool);
++ // unused in this generator
++ }
++
++ void VCXProjectWriter::addFilters(VCProject &project, XmlOutput &xmlFilter, const QString &filtername)
++ {
++ bool added = false;
++
++ for (int i = 0; i < project.SingleProjects.size(); ++i) {
++ const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername);
++ if(!filter.Files.isEmpty() && !added) {
++ xmlFilter << tag("Filter")
++ << attrTag("Include", filtername)
++ << attrTagS("UniqueIdentifier", filter.Guid)
++ << attrTagS("Extensions", filter.Filter)
++ << attrTagT("ParseFiles", filter.ParseFiles)
++ << closetag();
++ }
++ }
++ }
++
++ // outputs a given filter for all existing configurations of a project
++ void VCXProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filtername)
++ {
++ QScopedPointer<XNode> root;
++ if (project.SingleProjects.at(0).flat_files)
++ root.reset(new XFlatNode);
++ else
++ root.reset(new XTreeNode);
++
++ for (int i = 0; i < project.SingleProjects.size(); ++i) {
++ const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername);
++ // Merge all files in this filter to root tree
++ for (int x = 0; x < filter.Files.size(); ++x) {
++ const VCFilterFile &file = filter.Files.at(x);
++ root->addElement(filter.treePath(file.file), file);
++ }
++ }
++
++ if (!root->hasElements())
++ return;
++
++ root->generateXML(xml, xmlFilter, "", project, filtername); // output root tree
++ }
++
++ static QString stringBeforeFirstBackslash(const QString &str)
++ {
++ int idx = str.indexOf(QLatin1Char('\\'));
++ return idx == -1 ? str : str.left(idx);
++ }
++
++ // Output all configurations (by filtername) for a file (by info)
++ // A filters config output is in VCFilter.outputFileConfig()
++ void VCXProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter,
++ const VCFilterFile &info, const QString &filtername)
++ {
++ // In non-flat mode the filter names have directory suffixes, e.g. "Generated Files\subdir".
++ const QString cleanFilterName = stringBeforeFirstBackslash(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 hasCustomBuildStep = false;
++ QVarLengthArray<OutputFilterData, 8> data(project.SingleProjects.size());
++ for (int i = 0; i < project.SingleProjects.size(); ++i) {
++ data[i].filter = project.SingleProjects.at(i).filterByName(cleanFilterName);
++ if (!data[i].filter.Config) // only if the filter is not empty
++ continue;
++ VCFilter &filter = data[i].filter;
++
++ // Clearing each filter tool
++ filter.useCustomBuildTool = false;
++ filter.useCompilerTool = false;
++ filter.CustomBuildTool = VCCustomBuildTool();
++ filter.CustomBuildTool.config = filter.Config;
++ filter.CompilerTool = VCCLCompilerTool();
++ filter.CompilerTool.config = filter.Config;
++
++ VCFilterFile fileInFilter = filter.findFile(info.file, &data[i].inBuild);
++ data[i].info = fileInFilter;
++ data[i].inBuild &= !fileInFilter.excludeFromBuild;
++ if (data[i].inBuild && filter.addExtraCompiler(fileInFilter))
++ hasCustomBuildStep = true;
++ }
++
++ bool fileAdded = false;
++ for (int i = 0; i < project.SingleProjects.size(); ++i) {
++ OutputFilterData *d = &data[i];
++ if (!d->filter.Config) // only if the filter is not empty
++ continue;
++ if (outputFileConfig(d, xml, xmlFilter, info.file, filtername, fileAdded,
++ hasCustomBuildStep)) {
++ fileAdded = true;
++ }
++ }
++
++ if ( !fileAdded )
++ outputFileConfig(xml, xmlFilter, info.file, filtername);
++
++ xml << closetag();
++ xmlFilter << closetag();
++ }
++
++ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, XmlOutput &xmlFilter,
++ const QString &filename, const QString &fullFilterName,
++ bool fileAdded, bool hasCustomBuildStep)
++ {
++ VCFilter &filter = d->filter;
++ if (d->inBuild) {
++ if (filter.Project->usePCH)
++ filter.modifyPCHstage(filename);
++ } else {
++ // Excluded files uses an empty compiler stage
++ if (d->info.excludeFromBuild)
++ filter.useCompilerTool = true;
++ }
++
++ // Actual XML output ----------------------------------
++ if (hasCustomBuildStep || filter.useCustomBuildTool || filter.useCompilerTool
++ || !d->inBuild || filter.Name.startsWith("Deployment Files")) {
++
++ if (hasCustomBuildStep || filter.useCustomBuildTool)
++ {
++ if (!fileAdded) {
++ fileAdded = true;
++
++ xmlFilter << tag("CustomBuild")
++ << attrTag("Include", Option::fixPathToTargetOS(filename))
++ << attrTagS("Filter", fullFilterName);
++
++ xml << tag("CustomBuild")
++ << attrTag("Include", Option::fixPathToTargetOS(filename));
++
++ if (filter.Name.startsWith("Form Files")
++ || filter.Name.startsWith("Generated Files")
++ || filter.Name.startsWith("Resource Files")
++ || filter.Name.startsWith("Deployment Files"))
++ xml << attrTagS("FileType", "Document");
++ }
++
++ filter.Project->projectWriter->write(xml, filter.CustomBuildTool);
++ }
++
++ if (!fileAdded)
++ {
++ fileAdded = true;
++ outputFileConfig(xml, xmlFilter, filename, fullFilterName);
++ }
++
++ const QString condition = generateCondition(*filter.Config);
++ if (!d->inBuild) {
++ xml << tag("ExcludedFromBuild")
++ << attrTag("Condition", condition)
++ << valueTag("true");
++ }
++
++ if (filter.Name.startsWith("Deployment Files") && d->inBuild) {
++ xml << tag("DeploymentContent")
++ << attrTag("Condition", condition)
++ << valueTag("true");
++ }
++
++ if (filter.useCompilerTool) {
++
++ if ( !filter.CompilerTool.ForcedIncludeFiles.isEmpty() ) {
++ xml << tag("ForcedIncludeFiles")
++ << attrTag("Condition", condition)
++ << valueTagX(filter.CompilerTool.ForcedIncludeFiles);
++ }
++
++ if ( !filter.CompilerTool.PrecompiledHeaderThrough.isEmpty() ) {
++ xml << tag("PrecompiledHeaderFile")
++ << attrTag("Condition", condition)
++ << valueTag(filter.CompilerTool.PrecompiledHeaderThrough);
++ }
++
++ if (filter.CompilerTool.UsePrecompiledHeader != pchUnset) {
++ xml << tag("PrecompiledHeader")
++ << attrTag("Condition", condition)
++ << valueTag(toString(filter.CompilerTool.UsePrecompiledHeader));
++ }
++ }
++ }
++
++ return fileAdded;
++ }
++
++ static bool isFileClCompatible(const QString &filePath)
++ {
++ auto filePathEndsWith = [&filePath] (const QString &ext) {
++ return filePath.endsWith(ext, Qt::CaseInsensitive);
++ };
++ return std::any_of(Option::cpp_ext.cbegin(), Option::cpp_ext.cend(), filePathEndsWith)
++ || std::any_of(Option::c_ext.cbegin(), Option::c_ext.cend(), filePathEndsWith);
++ }
++
++ void VCXProjectWriter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter,
++ const QString &filePath, const QString &filterName)
++ {
++ const QString nativeFilePath = Option::fixPathToTargetOS(filePath);
++ if (filterName.startsWith("Source Files")) {
++ xmlFilter << tag("ClCompile")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("ClCompile")
++ << attrTag("Include", nativeFilePath);
++ } else if (filterName.startsWith("Header Files")) {
++ xmlFilter << tag("ClInclude")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("ClInclude")
++ << attrTag("Include", nativeFilePath);
++ } else if (filterName.startsWith("Generated Files") || filterName.startsWith("Form Files")) {
++ if (filePath.endsWith(".h")) {
++ xmlFilter << tag("ClInclude")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("ClInclude")
++ << attrTag("Include", nativeFilePath);
++ } else if (isFileClCompatible(filePath)) {
++ xmlFilter << tag("ClCompile")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("ClCompile")
++ << attrTag("Include", nativeFilePath);
++ } else if (filePath.endsWith(".res")) {
++ xmlFilter << tag("CustomBuild")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("CustomBuild")
++ << attrTag("Include", nativeFilePath);
++ } else {
++ xmlFilter << tag("CustomBuild")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("CustomBuild")
++ << attrTag("Include", nativeFilePath);
++ }
++ } else if (filterName.startsWith("Root Files")) {
++ if (filePath.endsWith(".rc")) {
++ xmlFilter << tag("ResourceCompile")
++ << attrTag("Include", nativeFilePath);
++ xml << tag("ResourceCompile")
++ << attrTag("Include", nativeFilePath);
++ }
++ } else {
++ xmlFilter << tag("None")
++ << attrTag("Include", nativeFilePath)
++ << attrTagS("Filter", filterName);
++ xml << tag("None")
++ << attrTag("Include", nativeFilePath);
++ }
++ }
++
++ QString VCXProjectWriter::generateCondition(const VCConfiguration &config)
++ {
++ return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\'');
++ }
++
++ XmlOutput::xml_output VCXProjectWriter::attrTagToolsVersion(const VCConfiguration &config)
++ {
++ if (config.CompilerVersion >= NET2013)
++ return noxml();
++ return attrTag("ToolsVersion", "4.0");
++ }
++
++ QT_END_NAMESPACE