summaryrefslogtreecommitdiffstats
path: root/qmake/generators
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/generators')
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp98
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h1
-rw-r--r--qmake/generators/makefile.cpp3
-rw-r--r--qmake/generators/makefiledeps.cpp11
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp74
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.h2
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp93
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp26
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h7
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp169
-rw-r--r--qmake/generators/win32/msvc_vcproj.h1
11 files changed, 379 insertions, 106 deletions
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index e634f6976e..b8e6d05728 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1381,24 +1381,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
!project->values("QMAKE_FRAMEWORKPATH").isEmpty() ? SettingsAsList : 0, 5) << ";\n";
{
- ProStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ ProStringList cflags = project->values("QMAKE_CFLAGS");
const ProStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
for (int i = 0; i < prl_defines.size(); ++i)
cflags += "-D" + prl_defines.at(i);
const ProStringList &defines = project->values("DEFINES");
for (int i = 0; i < defines.size(); ++i)
cflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";\n";
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", fixListForOutput(cflags), SettingsAsList, 5) << ";\n";
}
{
- ProStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ ProStringList cxxflags = project->values("QMAKE_CXXFLAGS");
const ProStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
for (int i = 0; i < prl_defines.size(); ++i)
cxxflags += "-D" + prl_defines.at(i);
const ProStringList &defines = project->values("DEFINES");
for (int i = 0; i < defines.size(); ++i)
cxxflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";\n";
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", fixListForOutput(cxxflags), SettingsAsList, 5) << ";\n";
}
if (!project->isActiveConfig("staticlib")) {
t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
@@ -1408,7 +1408,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
+ fixListForOutput("QMAKE_LIBS_PRIVATE"),
SettingsAsList, 6) << ";\n";
}
- const ProStringList &archs = project->values("QT_ARCH");
+ const ProStringList &archs = !project->values("QMAKE_XCODE_ARCHS").isEmpty() ?
+ project->values("QMAKE_XCODE_ARCHS") : project->values("QT_ARCH");
if (!archs.isEmpty())
t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";\n";
if (!project->isEmpty("OBJECTS_DIR"))
@@ -1518,19 +1519,20 @@ ProjectBuilderMakefileGenerator::fixForOutput(const QString &values)
project->values("QMAKE_PBX_VARS").append(reg_var.cap(1));
rep += reg_var.matchedLength();
}
- QString ret = values;
- ret = ret.replace(QRegExp("\\\\ "), " "); //unescape spaces
- ret = ret.replace(QRegExp("('|\\\\|\")"), "\\\\1"); //fix quotes
- ret = ret.replace("\t", " "); //fix tabs
- ret = ret.replace(QRegExp(" "), "\\ "); //escape spaces
- return ret;
+
+ return values;
}
ProStringList
ProjectBuilderMakefileGenerator::fixListForOutput(const char *where)
{
+ return fixListForOutput(project->values(where));
+}
+
+ProStringList
+ProjectBuilderMakefileGenerator::fixListForOutput(const ProStringList &l)
+{
ProStringList ret;
- const ProStringList &l = project->values(where);
for(int i = 0; i < l.count(); i++)
ret += fixForOutput(l[i].toQString());
return ret;
@@ -1747,37 +1749,81 @@ ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const
#endif
}
+static QString quotedStringLiteral(const QString &value)
+{
+ QString result;
+ const int len = value.length();
+ result.reserve(int(len * 1.1) + 2);
+
+ result += QLatin1Char('"');
+
+ // Escape
+ for (int i = 0; i < len; ++i) {
+ QChar character = value.at(i);;
+ ushort code = character.unicode();
+ switch (code) {
+ case '\\':
+ result += QLatin1String("\\\\");
+ break;
+ case '"':
+ result += QLatin1String("\\\"");
+ break;
+ case '\b':
+ result += QLatin1String("\\b");
+ break;
+ case '\n':
+ result += QLatin1String("\\n");
+ break;
+ case '\r':
+ result += QLatin1String("\\r");
+ break;
+ case '\t':
+ result += QLatin1String("\\t");
+ break;
+ default:
+ if (code >= 32 && code <= 127)
+ result += character;
+ else
+ result += QLatin1String("\\u") + QString::number(code, 16).rightJustified(4, '0');
+ }
+ }
+
+ result += QLatin1Char('"');
+
+ result.squeeze();
+ return result;
+}
+
QString
ProjectBuilderMakefileGenerator::writeSettings(const QString &var, const ProStringList &vals, int flags, int indent_level)
{
QString ret;
- const QString quote = (flags & SettingsNoQuote) ? "" : "\"";
- const QString escape_quote = quote.isEmpty() ? "" : QString("\\" + quote);
+ bool shouldQuote = !((flags & SettingsNoQuote));
+
QString newline = "\n";
for(int i = 0; i < indent_level; ++i)
newline += "\t";
+
+ ret += var + " = ";
+
if(flags & SettingsAsList) {
- ret += var + " = (" + newline;
+ ret += "(" + newline;
for(int i = 0, count = 0; i < vals.size(); ++i) {
QString val = vals.at(i).toQString();
if(!val.isEmpty()) {
if(count++ > 0)
ret += "," + newline;
- ret += quote + val.replace(quote, escape_quote) + quote;
+ if (shouldQuote)
+ val = quotedStringLiteral(val);
+ ret += val;
}
}
ret += ")";
} else {
- ret += var + " = " + quote;
- for(int i = 0; i < vals.size(); ++i) {
- QString val = vals.at(i).toQString();
-// if(val.isEmpty())
-// val = quote + quote;
- if(i)
- ret += " ";
- ret += val;
- }
- ret += quote;
+ QString val = vals.join(QLatin1Char(' '));
+ if (shouldQuote)
+ val = quotedStringLiteral(val);
+ ret += val;
}
return ret;
}
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h
index aef373b549..8813a190a9 100644
--- a/qmake/generators/mac/pbuilder_pbx.h
+++ b/qmake/generators/mac/pbuilder_pbx.h
@@ -61,6 +61,7 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
QString findProgram(const ProString &prog);
QString fixForOutput(const QString &file);
ProStringList fixListForOutput(const char *where);
+ ProStringList fixListForOutput(const ProStringList &list);
int reftypeForFile(const QString &where);
QString sourceTreeForFile(const QString &where);
QString projectSuffix() const;
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index f68e283862..766904cd60 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -2290,8 +2290,7 @@ MakefileGenerator::writeHeader(QTextStream &t)
{
t << "#############################################################################\n";
t << "# Makefile for building: " << escapeFilePath(var("TARGET")) << endl;
- t << "# Generated by qmake (" QMAKE_VERSION_STR ") (Qt " QT_VERSION_STR ") on: ";
- t << QDateTime::currentDateTime().toString() << endl;
+ t << "# Generated by qmake (" QMAKE_VERSION_STR ") (Qt " QT_VERSION_STR ")\n";
t << "# Project: " << fileFixify(project->projectFile()) << endl;
t << "# Template: " << var("TEMPLATE") << endl;
if(!project->isActiveConfig("build_pass"))
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 898903a423..df37957f9b 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -771,20 +771,15 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
}
if(Option::debug_level && qmake_endOfLine(*(buffer+x)))
++line_count;
- if(((buffer_len > x+2 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == '_')
- ||
- (buffer_len > x+4 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == 'O'
- && *(buffer+x+3) == 'M' && *(buffer+x+4) == '_'))
- &&
+ if (buffer_len > x + 2 && buffer[x + 1] == 'Q' && buffer[x + 2] == '_' &&
*(buffer + x) != '_' &&
(*(buffer + x) < 'a' || *(buffer + x) > 'z') &&
(*(buffer + x) < 'A' || *(buffer + x) > 'Z') &&
(*(buffer + x) < '0' || *(buffer + x) > '9')) {
++x;
int match = 0;
- static const char *interesting[] = { "OBJECT", "GADGET",
- "M_OBJECT" };
- for(int interest = 0, m1, m2; interest < 3; ++interest) {
+ static const char *interesting[] = { "OBJECT", "GADGET" };
+ for (int interest = 0, m1, m2; interest < 2; ++interest) {
if(interest == 0 && ignore_qobject)
continue;
else if(interest == 1 && ignore_qgadget)
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index b20f3c5ec4..ff7779f79f 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -89,6 +89,7 @@ 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";
@@ -138,6 +139,7 @@ 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";
@@ -254,6 +256,7 @@ const char _Version[] = "Version";
const char _WarnAsError[] = "WarnAsError";
const char _WarningLevel[] = "WarningLevel";
const char _WholeProgramOptimization[] = "WholeProgramOptimization";
+const char _WindowsMetadataFile[] = "WindowsMetadataFile";
const char _XMLDocumentationFileName[] = "XMLDocumentationFileName";
@@ -565,6 +568,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
addFilters(tempProj, xmlFilter, "Resource Files");
addFilters(tempProj, xmlFilter, "Source Files");
addFilters(tempProj, xmlFilter, "Translation Files");
+ addFilters(tempProj, xmlFilter, "Deployment Files");
for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x)
addFilters(tempProj, xmlFilter, tempProj.ExtraCompilers.at(x));
@@ -578,6 +582,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
outputFilter(tempProj, xml, xmlFilter, "Translation Files");
outputFilter(tempProj, xml, xmlFilter, "Form Files");
outputFilter(tempProj, xml, xmlFilter, "Resource Files");
+ outputFilter(tempProj, xml, xmlFilter, "Deployment Files");
for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) {
outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x));
@@ -620,8 +625,23 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< attrTag("Label", "Globals")
<< tagValue("ProjectGuid", tool.ProjectGUID)
<< tagValue("RootNamespace", tool.Name)
- << tagValue("Keyword", tool.Keyword)
- << closetag();
+ << tagValue("Keyword", tool.Keyword);
+
+ if (tool.SingleProjects.at(0).Configuration.WinRT) {
+ xml << tagValue("MinimumVisualStudioVersion", "11.0");
+ if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ xml << tagValue("WinMDAssembly", "true");
+ else
+ xml << tagValue("AppContainerApplication", "true");
+ }
+
+ if (tool.SingleProjects.at(0).Configuration.WinPhone
+ && tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) {
+ xml << tagValue("XapOutputs", "true");
+ xml << tagValue("XapFilename", "$(RootNamespace)_$(Configuration)_$(Platform).xap");
+ }
+
+ xml << closetag();
// config part.
xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
@@ -772,6 +792,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
addFilters(tool, xmlFilter, "Resource Files");
addFilters(tool, xmlFilter, "Source Files");
addFilters(tool, xmlFilter, "Translation Files");
+ addFilters(tool, xmlFilter, "Deployment Files");
for (int x = 0; x < tool.ExtraCompilers.count(); ++x)
addFilters(tool, xmlFilter, tool.ExtraCompilers.at(x));
@@ -785,13 +806,27 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
outputFilter(tool, xml, xmlFilter, "Translation Files");
outputFilter(tool, xml, xmlFilter, "Form Files");
outputFilter(tool, xml, xmlFilter, "Resource Files");
+ outputFilter(tool, xml, xmlFilter, "Deployment Files");
for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
outputFilter(tool, xml, xmlFilter, tool.ExtraCompilers.at(x));
}
outputFilter(tool, xml, xmlFilter, "Root Files");
+ if (tool.SingleProjects.at(0).Configuration.WinPhone) {
+ xml << tag("ItemGroup")
+ << tag("Reference")
+ << attrTag("Include", "platform")
+ << attrTagS("IsWinMDFile", "true")
+ << attrTagS("Private", "false")
+ << closetag()
+ << closetag();
+ }
+
xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
+ if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ xml << import("Project", "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v8.0\\Microsoft.Cpp.WindowsPhone.8.0.targets");
+
xml << tag("ImportGroup")
<< attrTag("Label", "ExtensionTargets")
<< closetag();
@@ -1361,6 +1396,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
<< 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))
<< attrTagT(_DisableLanguageExtensions, tool.DisableLanguageExtensions)
@@ -1449,6 +1485,8 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool)
<< attrTagS(_FunctionOrder, tool.FunctionOrder)
<< attrTagT(_GenerateDebugInformation, tool.GenerateDebugInformation)
<< 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)
@@ -1644,7 +1682,8 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
xml << tag("PropertyGroup")
<< attrTag("Condition", generateCondition(tool))
<< attrTag("Label", "Configuration")
- << attrTagS(_PlatformToolSet, platformToolSetVersion(tool.CompilerVersion))
+ << attrTagS(_PlatformToolSet, platformToolSetVersion(tool.CompilerVersion,
+ tool.WinPhone))
<< attrTagS(_OutputDirectory, tool.OutputDirectory)
<< attrTagT(_ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage)
<< attrTagT(_BuildBrowserInformation, tool.BuildBrowserInformation)
@@ -1693,6 +1732,8 @@ void VCXProjectWriter::addFilters(VCProject &project, XmlOutput &xmlFilter, cons
filter = singleCfg.FormFiles;
} else if (filtername == "Resource Files") {
filter = singleCfg.ResourceFiles;
+ } else if (filtername == "Deployment Files") {
+ filter = singleCfg.DeploymentFiles;
} else {
// ExtraCompilers
filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
@@ -1740,6 +1781,8 @@ void VCXProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, XmlOutpu
filter = singleCfg.FormFiles;
} else if (filtername == "Resource Files") {
filter = singleCfg.ResourceFiles;
+ } else if (filtername == "Deployment Files") {
+ filter = singleCfg.DeploymentFiles;
} else {
// ExtraCompilers
filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
@@ -1791,6 +1834,8 @@ void VCXProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, Xml
filter = singleCfg.FormFiles;
} else if (filtername.startsWith("Resource Files")) {
filter = singleCfg.ResourceFiles;
+ } else if (filtername.startsWith("Deployment Files")) {
+ filter = singleCfg.DeploymentFiles;
} else {
// ExtraCompilers
filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
@@ -1921,7 +1966,8 @@ bool VCXProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOut
}
// Actual XML output ----------------------------------
- if (filter.useCustomBuildTool || filter.useCompilerTool || !inBuild) {
+ if (filter.useCustomBuildTool || filter.useCompilerTool
+ || !inBuild || filtername.startsWith("Deployment Files")) {
if (filter.useCustomBuildTool)
{
@@ -1936,7 +1982,8 @@ bool VCXProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOut
xml << tag("CustomBuild")
<< attrTag("Include",Option::fixPathToLocalOS(filename));
- if ( filtername.startsWith("Form Files") || filtername.startsWith("Generated Files") || filtername.startsWith("Resource Files") )
+ if (filtername.startsWith("Form Files") || filtername.startsWith("Generated Files")
+ || filtername.startsWith("Resource Files") || filtername.startsWith("Deployment Files"))
xml << attrTagS("FileType", "Document");
}
@@ -2009,6 +2056,13 @@ bool VCXProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOut
xml << tag("ResourceCompile")
<< attrTag("Include",Option::fixPathToLocalOS(filename));
}
+ } else if (filtername.startsWith("Deployment Files")) {
+ xmlFilter << tag("None")
+ << attrTag("Include",Option::fixPathToLocalOS(filename))
+ << attrTagS("Filter", filtername);
+
+ xml << tag("None")
+ << attrTag("Include",Option::fixPathToLocalOS(filename));
}
}
@@ -2019,6 +2073,12 @@ bool VCXProjectWriter::outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOut
<< valueTag("true");
}
+ if (filtername.startsWith("Deployment Files") && inBuild) {
+ xml << tag("DeploymentContent")
+ << attrTag("Condition", condition)
+ << valueTag("true");
+ }
+
if (filter.useCompilerTool) {
if ( !filter.CompilerTool.ForcedIncludeFiles.isEmpty() ) {
@@ -2047,12 +2107,12 @@ QString VCXProjectWriter::generateCondition(const VCConfiguration &config)
return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\'');
}
-QString VCXProjectWriter::platformToolSetVersion(const DotNET version)
+QString VCXProjectWriter::platformToolSetVersion(const DotNET version, bool winphoneBuild)
{
switch (version)
{
case NET2012:
- return "v110";
+ return winphoneBuild ? "v110_wp80" : "v110";
case NET2013:
return "v120";
}
diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h
index 217705e388..7fb83233f4 100644
--- a/qmake/generators/win32/msbuild_objectmodel.h
+++ b/qmake/generators/win32/msbuild_objectmodel.h
@@ -183,7 +183,7 @@ private:
static void outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const VCFilterFile &info, const QString &filtername);
static bool outputFileConfig(VCFilter &filter, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filename, const QString &filtername, bool fileAllreadyAdded);
static QString generateCondition(const VCConfiguration &config);
- static QString platformToolSetVersion(const DotNET version);
+ static QString platformToolSetVersion(const DotNET version, bool winphoneBuild);
friend class XTreeNode;
friend class XFlatNode;
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index f7b85d3621..3185e68ecc 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -42,13 +42,27 @@
#include "msvc_nmake.h"
#include "option.h"
#include "cesdkhandler.h"
+
#include <qregexp.h>
#include <qhash.h>
#include <qdir.h>
+
+#include <windows/registry_p.h>
+
#include <time.h>
QT_BEGIN_NAMESPACE
+static QString nmakePathList(const QStringList &list)
+{
+ QStringList pathList;
+ foreach (const QString &path, list)
+ pathList.append(QDir::cleanPath(path));
+
+ return QDir::toNativeSeparators(pathList.join(QLatin1Char(';')))
+ .replace('#', QStringLiteral("^#")).replace('$', QStringLiteral("$$"));
+}
+
NmakeMakefileGenerator::NmakeMakefileGenerator() : Win32MakefileGenerator(), init_flag(false), usePCH(false)
{
@@ -100,6 +114,85 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
return false;
}
}
+#ifdef Q_OS_WIN
+ else if (project->isActiveConfig(QStringLiteral("winrt"))) {
+ QString arch = project->first("VCPROJ_ARCH").toQString().toLower();
+ QString compiler;
+ QString compilerArch;
+ if (arch == QStringLiteral("arm")) {
+ compiler = QStringLiteral("x86_arm");
+ compilerArch = QStringLiteral("arm");
+ } else if (arch == QStringLiteral("x64")) {
+ compiler = QStringLiteral("x86_amd64");
+ compilerArch = QStringLiteral("amd64");
+ }
+#ifdef Q_OS_WIN64
+ const QString regKey = QStringLiteral("Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir");
+#else
+ const QString regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir");
+#endif
+ const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey);
+ if (vcInstallDir.isEmpty()) {
+ fprintf(stderr, "Failed to find the Visual Studio 2012 installation directory.\n"
+ "Is it installed?.\n");
+ return false;
+ }
+
+ QStringList incDirs;
+ QStringList libDirs;
+ QStringList binDirs;
+ const bool isPhone = project->isActiveConfig(QStringLiteral("winphone"));
+ if (isPhone) {
+ QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/WP80");
+ if (!QDir(sdkDir).exists()) {
+ fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n"
+ "Check that it is properly installed.\n",
+ qPrintable(QDir::toNativeSeparators(sdkDir)));
+ return false;
+ }
+ incDirs << sdkDir + QStringLiteral("/include");
+ libDirs << sdkDir + QStringLiteral("/lib/") + compilerArch;
+ binDirs << sdkDir + QStringLiteral("/bin/") + compiler;
+
+ QString kitDir = vcInstallDir + QStringLiteral("/../../Windows Phone Kits/8.0");
+ if (!QDir(kitDir).exists()) {
+ fprintf(stderr, "Failed to find the Windows Phone Kit in %s.\n"
+ "Check that it is properly installed.\n",
+ qPrintable(QDir::toNativeSeparators(kitDir)));
+ return false;
+ }
+ libDirs << kitDir + QStringLiteral("/lib/") + arch;
+ incDirs << kitDir + QStringLiteral("/include")
+ << kitDir + QStringLiteral("/include/abi")
+ << kitDir + QStringLiteral("/include/mincore")
+ << kitDir + QStringLiteral("/include/minwin");
+ } else {
+ incDirs << vcInstallDir + QStringLiteral("/include");
+ libDirs << vcInstallDir + QStringLiteral("/lib/") + compilerArch;
+ binDirs << vcInstallDir + QStringLiteral("/bin/") + compiler
+ << vcInstallDir + QStringLiteral("/../Common7/IDE");
+
+ QString kitDir = vcInstallDir + QStringLiteral("/../../Windows Kits/8.0");
+ if (!QDir(kitDir).exists()) {
+ fprintf(stderr, "Failed to find the Windows Kit in %s.\n"
+ "Check that it is properly installed.\n",
+ qPrintable(QDir::toNativeSeparators(kitDir)));
+ return false;
+ }
+ libDirs << kitDir + QStringLiteral("/Lib/win8/um/") + arch;
+ incDirs << kitDir + QStringLiteral("/include/um")
+ << kitDir + QStringLiteral("/include/shared")
+ << kitDir + QStringLiteral("/include/winrt");
+ }
+
+ // Inherit PATH
+ binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';'));
+
+ t << "\nINCLUDE = " << nmakePathList(incDirs);
+ t << "\nLIB = " << nmakePathList(libDirs);
+ t << "\nPATH = " << nmakePathList(binDirs) << '\n';
+ }
+#endif // Q_OS_WIN
}
writeNmakeParts(t);
return MakefileGenerator::writeMakefile(t);
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index d6d40bcc68..09213bec8e 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -320,6 +320,7 @@ VCCLCompilerTool::VCCLCompilerTool()
CallingConvention(callConventionDefault),
CompileAs(compileAsDefault),
CompileAsManaged(managedDefault),
+ CompileAsWinRT(unset),
CompileOnly(unset),
DebugInformationFormat(debugDisabled),
DefaultCharIsUnsigned(unset),
@@ -942,6 +943,12 @@ bool VCCLCompilerTool::parseOption(const char* option)
found = false; break;
}
break;
+ case 'W':
+ if (third == '-')
+ CompileAsWinRT = _False;
+ else
+ CompileAsWinRT = _True;
+ break;
default:
found = false; break;
}
@@ -1191,6 +1198,7 @@ VCLinkerTool::VCLinkerTool()
TurnOffAssemblyGeneration(unset),
TypeLibraryResourceID(0),
GenerateManifest(unset),
+ GenerateWindowsMetadata(unset),
EnableUAC(unset),
UACUIAccess(unset),
SectionAlignment(-1),
@@ -1258,6 +1266,7 @@ bool VCLinkerTool::parseOption(const char* option)
displayHash("/SWAPRUN"); displayHash("/TLBID"); displayHash("/TLBOUT");
displayHash("/TSAWARE"); displayHash("/VERBOSE"); displayHash("/VERSION");
displayHash("/VXD"); displayHash("/WS "); displayHash("/libpath");
+ displayHash("/WINMD"); displayHash("/WINMDFILE:");
#endif
#ifdef USE_DISPLAY_HASH
@@ -1370,6 +1379,15 @@ bool VCLinkerTool::parseOption(const char* option)
else
GenerateManifest = _True;
break;
+ case 0x34be314: // /WINMD[:NO]
+ if ((*(option+6) == ':' && (*(option+7) == 'N' || *(option+7) == 'n')))
+ GenerateWindowsMetadata = _False;
+ else
+ GenerateWindowsMetadata = _True;
+ break;
+ case 0x31be7e5: // /WINMDFILE:filename
+ WindowsMetadataFile = option+11;
+ break;
case 0x8b64559: // /MANIFESTDEPENDENCY:manifest_dependency
AdditionalManifestDependencies += option+20;
break;
@@ -2102,6 +2120,8 @@ VCPreLinkEventTool::VCPreLinkEventTool()
VCConfiguration::VCConfiguration()
: ATLMinimizesCRunTimeLibraryUsage(unset),
+ WinRT(false),
+ WinPhone(false),
BuildBrowserInformation(unset),
CharacterSet(charSetNotSet),
ConfigurationType(typeApplication),
@@ -2455,6 +2475,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
outputFilter(tempProj, xml, "TranslationFiles");
outputFilter(tempProj, xml, "FormFiles");
outputFilter(tempProj, xml, "ResourceFiles");
+ outputFilter(tempProj, xml, "DeploymentFiles");
QSet<QString> extraCompilersInProject;
for (int i = 0; i < tool.ExtraCompilersFiles.count(); ++i) {
@@ -2507,6 +2528,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProject &tool)
outputFilter(tool, xml, "TranslationFiles");
outputFilter(tool, xml, "FormFiles");
outputFilter(tool, xml, "ResourceFiles");
+ outputFilter(tool, xml, "DeploymentFiles");
for (int x = 0; x < tool.ExtraCompilers.count(); ++x) {
outputFilter(tool, xml, tool.ExtraCompilers.at(x));
}
@@ -2858,6 +2880,8 @@ void VCProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, const QSt
filter = projectSingleConfig.FormFiles;
} else if (filtername == "ResourceFiles") {
filter = projectSingleConfig.ResourceFiles;
+ } else if (filtername == "DeploymentFiles") {
+ filter = projectSingleConfig.DeploymentFiles;
} else {
// ExtraCompilers
filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
@@ -2918,6 +2942,8 @@ void VCProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, cons
filter = projectSingleConfig.FormFiles;
} else if (filtername == "ResourceFiles") {
filter = projectSingleConfig.ResourceFiles;
+ } else if (filtername == "DeploymentFiles") {
+ filter = projectSingleConfig.DeploymentFiles;
} else {
// ExtraCompilers
filter = project.SingleProjects[i].filterForExtraCompiler(filtername);
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 034825ed44..4e19a43a8c 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -511,6 +511,7 @@ public:
callingConventionOption CallingConvention;
CompileAsOptions CompileAs;
compileAsManagedOptions CompileAsManaged;
+ triState CompileAsWinRT;
triState CompileOnly;
debugOption DebugInformationFormat;
triState DefaultCharIsUnsigned;
@@ -673,6 +674,10 @@ public:
QString KeyFile;
QString LinkErrorReporting;
+ // VS2012
+ triState GenerateWindowsMetadata;
+ QString WindowsMetadataFile;
+
VCConfiguration* config;
};
@@ -862,6 +867,7 @@ public:
~VCConfiguration(){}
DotNET CompilerVersion;
+ bool WinRT, WinPhone;
// Variables
triState ATLMinimizesCRunTimeLibraryUsage;
@@ -994,6 +1000,7 @@ public:
VCFilter TranslationFiles;
VCFilter FormFiles;
VCFilter ResourceFiles;
+ VCFilter DeploymentFiles;
VCFilterList ExtraCompilersFiles;
bool flat_files;
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index d550748c9b..7f4240f196 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -63,6 +63,7 @@ const char _GUIDLexYaccFiles[] = "{E12AE0D2-192F-4d59-BD23-7D3FA58D3183}
const char _GUIDTranslationFiles[] = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}";
const char _GUIDFormFiles[] = "{99349809-55BA-4b9d-BF79-8FDBB0286EB3}";
const char _GUIDExtraCompilerFiles[] = "{E0D8C965-CC5F-43d7-AD63-FAEF0BBC0F85}";
+const char _GUIDDeploymentFiles[] = "{D9D6E243-F8AF-46E4-B9FD-80ECBC20BA3E}";
QT_END_NAMESPACE
#ifdef Q_OS_WIN32
@@ -679,7 +680,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
}
}
QString slnConf = _slnSolutionConf;
- if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) {
+ if (!project->isEmpty("VCPROJ_ARCH")) {
+ slnConf.replace(QString("|Win32"), "|" + project->first("VCPROJ_ARCH"));
+ } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) {
QString slnPlatform = QString("|") + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
slnConf.replace(QString("|Win32"), slnPlatform);
} else if (is64Bit) {
@@ -694,8 +697,11 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
for(QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) {
QString platform = is64Bit ? "x64" : "Win32";
QString xplatform = platform;
- if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
+ if (!project->isEmpty("VCPROJ_ARCH")) {
+ xplatform = project->first("VCPROJ_ARCH").toQString();
+ } else if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) {
xplatform = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
+ }
if (!project->isHostBuild())
platform = xplatform;
t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag1).arg(xplatform) << platform;
@@ -907,7 +913,9 @@ void VcprojGenerator::initProject()
}
vcProject.Keyword = project->first("VCPROJ_KEYWORD").toQString();
- if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
+ if (!project->isEmpty("VCPROJ_ARCH")) {
+ vcProject.PlatformName = project->first("VCPROJ_ARCH").toQString();
+ } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
vcProject.PlatformName = (is64Bit ? "x64" : "Win32");
} else {
vcProject.PlatformName = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
@@ -968,11 +976,19 @@ void VcprojGenerator::initConfiguration()
conf.PrimaryOutput.append(project->first("TARGET_VERSION_EXT").toQString());
}
+ if (conf.CompilerVersion >= NET2012) {
+ conf.WinRT = project->isActiveConfig("winrt");
+ if (conf.WinRT)
+ conf.WinPhone = project->isActiveConfig("winphone");
+ }
+
conf.Name = project->values("BUILD_NAME").join(' ');
if (conf.Name.isEmpty())
conf.Name = isDebug ? "Debug" : "Release";
conf.ConfigurationName = conf.Name;
- if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
+ if (!project->isEmpty("VCPROJ_ARCH")) {
+ conf.Name += "|" + project->first("VCPROJ_ARCH");
+ } else if (project->isHostBuild() || project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) {
conf.Name += (is64Bit ? "|x64" : "|Win32");
} else {
conf.Name += "|" + project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
@@ -997,8 +1013,9 @@ void VcprojGenerator::initConfiguration()
initCustomBuildTool();
initPreBuildEventTools();
initPostBuildEventTools();
- // Only deploy for CE projects
- if (!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
+ // Only deploy for CE and WinRT projects
+ if (!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")
+ || conf.WinRT)
initDeploymentTool();
initPreLinkEventTools();
@@ -1158,11 +1175,19 @@ void VcprojGenerator::initPostBuildEventTools()
void VcprojGenerator::initDeploymentTool()
{
VCConfiguration &conf = vcProject.Configuration;
- QString targetPath = project->values("deploy.path").join(' ');
- if (targetPath.isEmpty())
- targetPath = QString("%CSIDL_PROGRAM_FILES%\\") + project->first("TARGET");
- if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
- targetPath.chop(1);
+ QString targetPath;
+ if (conf.WinRT) {
+ vcProject.DeploymentFiles.Name = "Deployment Files";
+ vcProject.DeploymentFiles.ParseFiles = _False;
+ vcProject.DeploymentFiles.Filter = "deploy";
+ vcProject.DeploymentFiles.Guid = _GUIDDeploymentFiles;
+ } else {
+ targetPath = project->values("deploy.path").join(' ');
+ if (targetPath.isEmpty())
+ targetPath = QString("%CSIDL_PROGRAM_FILES%\\") + project->first("TARGET");
+ if (targetPath.endsWith("/") || targetPath.endsWith("\\"))
+ targetPath.chop(1);
+ }
// Only deploy Qt libs for shared build
if (!project->values("QMAKE_QT_DLL").isEmpty()) {
@@ -1180,48 +1205,55 @@ void VcprojGenerator::initDeploymentTool()
continue;
dllName.replace(QLatin1String(".lib") , QLatin1String(".dll"));
QFileInfo info(dllName);
- conf.deployment.AdditionalFiles += info.fileName()
- + "|" + QDir::toNativeSeparators(info.absolutePath())
- + "|" + targetPath
- + "|0;";
+ if (conf.WinRT) {
+ QString absoluteFilePath(QDir::toNativeSeparators(info.absoluteFilePath()));
+ vcProject.DeploymentFiles.addFile(absoluteFilePath);
+ } else {
+ conf.deployment.AdditionalFiles += info.fileName()
+ + "|" + QDir::toNativeSeparators(info.absolutePath())
+ + "|" + targetPath
+ + "|0;";
+ }
}
}
}
- // C-runtime deployment
- QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1Char(' '));
- if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) {
- QString runtimeVersion = QLatin1String("msvcr");
- ProString mkspec = project->first("QMAKESPEC");
-
- if (!mkspec.isEmpty()) {
- if (mkspec.endsWith("2008"))
- runtimeVersion.append("90");
- else
- runtimeVersion.append("80");
- if (project->isActiveConfig("debug"))
- runtimeVersion.append("d");
- runtimeVersion.append(".dll");
-
- if (runtime == "yes") {
- // Auto-find C-runtime
- QString vcInstallDir = qgetenv("VCINSTALLDIR");
- if (!vcInstallDir.isEmpty()) {
- vcInstallDir += "\\ce\\dll\\";
- vcInstallDir += project->values("CE_ARCH").join(QLatin1Char(' '));
- if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists())
- runtime.clear();
- else
- runtime = vcInstallDir;
+ if (!conf.WinRT) {
+ // C-runtime deployment
+ QString runtime = project->values("QT_CE_C_RUNTIME").join(QLatin1Char(' '));
+ if (!runtime.isEmpty() && (runtime != QLatin1String("no"))) {
+ QString runtimeVersion = QLatin1String("msvcr");
+ ProString mkspec = project->first("QMAKESPEC");
+
+ if (!mkspec.isEmpty()) {
+ if (mkspec.endsWith("2008"))
+ runtimeVersion.append("90");
+ else
+ runtimeVersion.append("80");
+ if (project->isActiveConfig("debug"))
+ runtimeVersion.append("d");
+ runtimeVersion.append(".dll");
+
+ if (runtime == "yes") {
+ // Auto-find C-runtime
+ QString vcInstallDir = qgetenv("VCINSTALLDIR");
+ if (!vcInstallDir.isEmpty()) {
+ vcInstallDir += "\\ce\\dll\\";
+ vcInstallDir += project->values("CE_ARCH").join(QLatin1Char(' '));
+ if (!QFileInfo(vcInstallDir + QDir::separator() + runtimeVersion).exists())
+ runtime.clear();
+ else
+ runtime = vcInstallDir;
+ }
}
}
- }
- if (!runtime.isEmpty() && runtime != QLatin1String("yes")) {
- conf.deployment.AdditionalFiles += runtimeVersion
- + "|" + QDir::toNativeSeparators(runtime)
- + "|" + targetPath
- + "|0;";
+ if (!runtime.isEmpty() && runtime != QLatin1String("yes")) {
+ conf.deployment.AdditionalFiles += runtimeVersion
+ + "|" + QDir::toNativeSeparators(runtime)
+ + "|" + targetPath
+ + "|0;";
+ }
}
}
@@ -1229,14 +1261,16 @@ void VcprojGenerator::initDeploymentTool()
foreach (const ProString &item, project->values("DEPLOYMENT")) {
// get item.path
QString devicePath = project->first(ProKey(item + ".path")).toQString();
- if (devicePath.isEmpty())
- devicePath = targetPath;
- // check if item.path is relative (! either /,\ or %)
- if (!(devicePath.at(0) == QLatin1Char('/')
- || devicePath.at(0) == QLatin1Char('\\')
- || devicePath.at(0) == QLatin1Char('%'))) {
- // create output path
- devicePath = Option::fixPathToLocalOS(QDir::cleanPath(targetPath + QLatin1Char('\\') + devicePath));
+ if (!conf.WinRT) {
+ if (devicePath.isEmpty())
+ devicePath = targetPath;
+ // check if item.path is relative (! either /,\ or %)
+ if (!(devicePath.at(0) == QLatin1Char('/')
+ || devicePath.at(0) == QLatin1Char('\\')
+ || devicePath.at(0) == QLatin1Char('%'))) {
+ // create output path
+ devicePath = Option::fixPathToLocalOS(QDir::cleanPath(targetPath + QLatin1Char('\\') + devicePath));
+ }
}
// foreach d in item.files
foreach (const ProString &src, project->values(ProKey(item + ".files"))) {
@@ -1261,16 +1295,27 @@ void VcprojGenerator::initDeploymentTool()
// foreach dirIterator-entry in d
while(iterator.hasNext()) {
iterator.next();
- QString absoluteItemPath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absolutePath());
- // Identify if it is just another subdir
- int diffSize = absoluteItemPath.size() - pathSize;
- // write out rules
- conf.deployment.AdditionalFiles += iterator.fileName()
- + "|" + absoluteItemPath
- + "|" + itemDevicePath + (diffSize ? (absoluteItemPath.right(diffSize)) : QLatin1String(""))
- + "|0;";
+ if (conf.WinRT) {
+ QString absoluteItemFilePath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absoluteFilePath());
+ vcProject.DeploymentFiles.addFile(absoluteItemFilePath);
+ } else {
+ QString absoluteItemPath = Option::fixPathToLocalOS(QFileInfo(iterator.filePath()).absolutePath());
+ // Identify if it is just another subdir
+ int diffSize = absoluteItemPath.size() - pathSize;
+ // write out rules
+ conf.deployment.AdditionalFiles += iterator.fileName()
+ + "|" + absoluteItemPath
+ + "|" + itemDevicePath + (diffSize ? (absoluteItemPath.right(diffSize)) : QLatin1String(""))
+ + "|0;";
+ }
}
}
+
+ if (conf.WinRT) {
+ vcProject.DeploymentFiles.Project = this;
+ vcProject.DeploymentFiles.Config = &(vcProject.Configuration);
+ vcProject.DeploymentFiles.CustomBuild = none;
+ }
}
}
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index 62a2da9629..561e56d232 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -117,6 +117,7 @@ protected:
void initTranslationFiles();
void initFormFiles();
void initResourceFiles();
+ void initDeploymentFiles();
void initLexYaccFiles();
void initExtraCompilerOutputs();