qt5base-lts/qmake/generators/win32/msbuild_objectmodel.cpp
Joerg Bornemann f65cfadd04 Improve readability of commands in VS project files
The commands are separated by "if errorlevel 1 goto VCEnd" lines to
make sure we abort on the first failure. However, we also insert magic
comments starting with "Rem" for IncrediBuild. These do not need
error checking. Also, the last command does not need error checking.

The XML line ending entities are also unneeded. By using proper line
endings we ensure that commands appear on separate lines in Visual
Studio's property editor.

Change-Id: Ifbf7525281e892c820034fafc64b555fff3dc756
Reviewed-by: Miguel Costa <miguel.costa@qt.io>
2019-08-22 18:15:08 +02:00

2057 lines
79 KiB
C++

/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#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 <qregexp.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 _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.count() - 2; i >= 0; --i) {
if (!commands.at(i).startsWith("rem", Qt::CaseInsensitive))
commands.insert(i + 1, errchk);
}
return commands.join('\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.count(); ++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)
<< 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");
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"));
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")
<< attrTagToolsVersion(tool.Configuration)
<< attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
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.count(); ++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.count(); ++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.count() == 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)
<< attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003")
<< tag("ItemGroup")
<< attrTag("Label", "ProjectConfigurations");
bool isWinRT = false;
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();
isWinRT = isWinRT || tool.SingleProjects.at(i).Configuration.WinRT;
}
xml << closetag()
<< tag("PropertyGroup")
<< attrTag("Label", "Globals")
<< tagValue("ProjectGuid", tool.ProjectGUID)
<< tagValue("RootNamespace", tool.Name)
<< tagValue("Keyword", tool.Keyword);
if (isWinRT) {
xml << tagValue("MinimumVisualStudioVersion", tool.Version)
<< tagValue("DefaultLanguage", "en")
<< tagValue("AppContainerApplication", "true")
<< tagValue("ApplicationType", "Windows Store")
<< tagValue("ApplicationTypeRevision", tool.SdkVersion);
}
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.count(); ++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.count(); ++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.count(); ++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.count(); ++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"));
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")
<< attrTagToolsVersion(tool.SingleProjects.first().Configuration)
<< attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
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.count(); ++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.count(); ++x) {
outputFilter(tool, xml, xmlFilter, tool.ExtraCompilers.at(x));
}
outputFilter(tool, xml, xmlFilter, "Root Files");
// App manifest
if (isWinRT) {
const QString manifest = QStringLiteral("Package.appxmanifest");
// Find all icons referenced in the manifest
QSet<QString> icons;
QFile manifestFile(Option::output_dir + QLatin1Char('/') + manifest);
if (manifestFile.open(QFile::ReadOnly)) {
const QString contents = manifestFile.readAll();
QRegExp regexp("[\\\\/a-zA-Z0-9_\\-\\!]*\\.(png|jpg|jpeg)");
int pos = 0;
while (pos > -1) {
pos = regexp.indexIn(contents, pos);
if (pos >= 0) {
const QString match = regexp.cap(0);
icons.insert(match);
pos += match.length();
}
}
}
// Write out manifest + icons as content items
xml << tag(_ItemGroup)
<< tag("AppxManifest")
<< attrTag("Include", manifest)
<< closetag();
for (const QString &icon : qAsConst(icons)) {
xml << tag("Image")
<< attrTag("Include", icon)
<< closetag();
}
xml << closetag();
}
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 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";
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(_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.count(); ++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.count(); ++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.count(); ++x)
root->addElement(filter.Files.at(x));
}
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> data(project.SingleProjects.count());
for (int i = 0; i < project.SingleProjects.count(); ++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.count(); ++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