summaryrefslogtreecommitdiffstats
path: root/qmake/generators/win32
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
commit30fd22b9574def54726e7b193127cc0c901c1b4c (patch)
tree96dfc923044db0515064ba39d052d9ed577e3e40 /qmake/generators/win32
parentd7b0581c1c2ef60c08d238dae39298af6904918f (diff)
parent6aa09bbce59828d028f6d1e81d2bfc6ba537aae1 (diff)
Merge remote-tracking branch 'origin/dev' into stable
Diffstat (limited to 'qmake/generators/win32')
-rw-r--r--qmake/generators/win32/mingw_make.cpp60
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp103
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.h1
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp74
-rw-r--r--qmake/generators/win32/msvc_nmake.h2
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp50
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h24
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp45
-rw-r--r--qmake/generators/win32/msvc_vcproj.h1
-rw-r--r--qmake/generators/win32/winmakefile.cpp44
10 files changed, 284 insertions, 120 deletions
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 29b27cb7d7..6d5764f59c 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -101,7 +101,7 @@ bool MingwMakefileGenerator::findLibraries()
}
if (!out.isEmpty()) // We assume if it never finds it that its correct
(*it) = out;
- } else if((*it).startsWith("-L")) {
+ } else if ((*it).startsWith("-L")) {
dirs.append(QMakeLocalFileName((*it).mid(2).toQString()));
}
@@ -159,7 +159,7 @@ void createLdObjectScriptFile(const QString &fileName, const ProStringList &objL
t << path << endl;
}
t << ");\n";
- t.flush();
+ t.flush();
file.close();
}
}
@@ -175,7 +175,7 @@ void createArObjectScriptFile(const QString &fileName, const QString &target, co
t << "ADDMOD " << *it << endl;
}
t << "SAVE\n";
- t.flush();
+ t.flush();
file.close();
}
}
@@ -204,16 +204,16 @@ void MingwMakefileGenerator::writeMingwParts(QTextStream &t)
if (!preCompHeaderOut.isEmpty()) {
QString header = project->first("PRECOMPILED_HEADER").toQString();
- QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
- t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " "
+ QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
+ t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " "
<< escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
- << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
+ << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
<< "\n\t$(CC) -x c-header -c $(CFLAGS) $(INCPATH) -o " << cHeader << " " << header
<< endl << endl;
- QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
- t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " "
+ QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
+ t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " "
<< escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
- << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
+ << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
<< "\n\t$(CXX) -x c++-header -c $(CXXFLAGS) $(INCPATH) -o " << cppHeader << " " << header
<< endl << endl;
}
@@ -269,7 +269,7 @@ void MingwMakefileGenerator::init()
destDir = Option::fixPathToTargetOS(project->first("DESTDIR") + Option::dir_sep, false, false);
project->values("MINGW_IMPORT_LIB").prepend(destDir + "lib" + project->first("TARGET")
+ project->first("TARGET_VERSION_EXT") + ".a");
- project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + project->first("MINGW_IMPORT_LIB"));
+ project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + project->first("MINGW_IMPORT_LIB"));
}
if (!project->values("DEF_FILE").isEmpty()) {
@@ -287,21 +287,21 @@ void MingwMakefileGenerator::init()
&& project->isActiveConfig("precompile_header")) {
QString preCompHeader = var("PRECOMPILED_DIR")
+ QFileInfo(project->first("PRECOMPILED_HEADER").toQString()).fileName();
- preCompHeaderOut = preCompHeader + ".gch";
- project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c");
- project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++");
+ preCompHeaderOut = preCompHeader + ".gch";
+ project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c");
+ project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++");
- project->values("QMAKE_RUN_CC").clear();
- project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CC").clear();
+ project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader +
" $(CFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$obj $src");
project->values("QMAKE_RUN_CC_IMP").clear();
- project->values("QMAKE_RUN_CC_IMP").append("$(CC) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CC_IMP").append("$(CC) -c -include " + preCompHeader +
" $(CFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$@ $<");
project->values("QMAKE_RUN_CXX").clear();
- project->values("QMAKE_RUN_CXX").append("$(CXX) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CXX").append("$(CXX) -c -include " + preCompHeader +
" $(CXXFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$obj $src");
project->values("QMAKE_RUN_CXX_IMP").clear();
- project->values("QMAKE_RUN_CXX_IMP").append("$(CXX) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CXX_IMP").append("$(CXX) -c -include " + preCompHeader +
" $(CXXFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$@ $<");
}
@@ -321,12 +321,18 @@ void MingwMakefileGenerator::writeIncPart(QTextStream &t)
t << "-I" << pwd << " ";
}
+ QString isystem = var("QMAKE_CFLAGS_ISYSTEM");
const ProStringList &incs = project->values("INCLUDEPATH");
for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) {
QString inc = (*incit).toQString();
inc.replace(QRegExp("\\\\$"), "");
inc.replace(QRegExp("\""), "");
- t << "-I" << quote << inc << quote << " ";
+
+ if (!isystem.isEmpty() && isSystemInclude(inc))
+ t << isystem << ' ';
+ else
+ t << "-I";
+ t << quote << inc << quote << " ";
}
t << "-I" << quote << specdir() << quote
<< endl;
@@ -350,10 +356,10 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
objectsLinkLine = "$(OBJECTS)";
} else if (project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
- QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
- if (!var("BUILD_NAME").isEmpty()) {
- ar_script_file += "." + var("BUILD_NAME");
- }
+ QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
+ if (!var("BUILD_NAME").isEmpty()) {
+ ar_script_file += "." + var("BUILD_NAME");
+ }
// QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix.
if (project->isActiveConfig("rvct_linker")) {
createRvctObjectScriptFile(ar_script_file, project->values("OBJECTS"));
@@ -371,9 +377,9 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
}
} else {
QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
- if (!var("BUILD_NAME").isEmpty()) {
- ld_script_file += "." + var("BUILD_NAME");
- }
+ if (!var("BUILD_NAME").isEmpty()) {
+ ld_script_file += "." + var("BUILD_NAME");
+ }
if (project->isActiveConfig("rvct_linker")) {
createRvctObjectScriptFile(ld_script_file, project->values("OBJECTS"));
objectsLinkLine = QString::fromLatin1("--via ") + escapeFilePath(ld_script_file);
@@ -393,7 +399,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
if(!project->isEmpty("QMAKE_PRE_LINK"))
t << "\n\t" <<var("QMAKE_PRE_LINK");
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
- if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
+ if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ;
} else {
t << "\n\t" << objectsLinkLine << " " ;
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index fdb664f3f4..7702496f3c 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -614,12 +614,16 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< tag("ItemGroup")
<< attrTag("Label", "ProjectConfigurations");
+ bool isWinRT = false;
+ bool isPhone = 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;
+ isPhone = isPhone || tool.SingleProjects.at(i).Configuration.WinPhone;
}
xml << closetag()
@@ -629,18 +633,19 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< tagValue("RootNamespace", tool.Name)
<< tagValue("Keyword", tool.Keyword);
- if (tool.SingleProjects.at(0).Configuration.WinRT) {
- xml << tagValue("MinimumVisualStudioVersion", "11.0");
- if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ if (isWinRT) {
+ xml << tagValue("MinimumVisualStudioVersion", tool.Version);
+ if (isPhone) {
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");
+ if (tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) {
+ xml << tagValue("XapOutputs", "true");
+ xml << tagValue("XapFilename", "$(RootNamespace)_$(Configuration)_$(Platform).xap");
+ }
+ } else {
+ xml << tagValue("AppContainerApplication", "true")
+ << tagValue("ApplicationType", "Windows Store")
+ << tagValue("ApplicationTypeRevision", tool.SdkVersion);
+ }
}
xml << closetag();
@@ -769,6 +774,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
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.
@@ -824,9 +833,43 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< closetag();
}
+ // App manifest
+ if (isWinRT) {
+ QString manifest = isPhone ? QStringLiteral("WMAppManifest.xml") : 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(isPhone ? "Xml" : "AppxManifest")
+ << attrTag("Include", manifest)
+ << closetag();
+ foreach (const QString &icon, icons) {
+ xml << tag("Image")
+ << attrTag("Include", icon)
+ << closetag();
+ }
+ xml << closetag();
+ }
+
xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
- if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ if (isPhone)
xml << import("Project", "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v8.0\\Microsoft.Cpp.WindowsPhone.8.0.targets");
xml << tag("ImportGroup")
@@ -1695,6 +1738,42 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &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")
diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h
index 7fb83233f4..2f02e66eb9 100644
--- a/qmake/generators/win32/msbuild_objectmodel.h
+++ b/qmake/generators/win32/msbuild_objectmodel.h
@@ -174,6 +174,7 @@ public:
void write(XmlOutput &, const VCResourceCompilerTool &);
void write(XmlOutput &, const VCEventTool &);
void write(XmlOutput &, const VCDeploymentTool &);
+ void write(XmlOutput &, const VCWinDeployQtTool &);
void write(XmlOutput &, const VCConfiguration &);
void write(XmlOutput &, VCFilter &);
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 0abbd133cc..24465ad152 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -123,29 +123,64 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
} else if (arch == QStringLiteral("x64")) {
compiler = QStringLiteral("x86_amd64");
compilerArch = QStringLiteral("amd64");
+ } else {
+ arch = QStringLiteral("x86");
+ }
+
+ const QString msvcVer = project->first("MSVC_VER").toQString();
+ if (msvcVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n");
+ return false;
+ }
+ const QString winsdkVer = project->first("WINSDK_VER").toQString();
+ if (winsdkVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify WINSDK_VER. Cannot continue.\n");
+ return false;
}
+ const QString targetVer = project->first("WINTARGET_VER").toQString();
+ if (targetVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n");
+ return false;
+ }
+
+ const bool isPhone = project->isActiveConfig(QStringLiteral("winphone"));
#ifdef Q_OS_WIN
-#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");
+ QString regKeyPrefix;
+#if !defined(Q_OS_WIN64) && _WIN32_WINNT >= 0x0501
+ BOOL isWow64;
+ IsWow64Process(GetCurrentProcess(), &isWow64);
+ if (!isWow64)
+ regKeyPrefix = QStringLiteral("Software\\");
+ else
#endif
+ regKeyPrefix = QStringLiteral("Software\\Wow6432Node\\");
+
+ QString regKey = regKeyPrefix + QStringLiteral("Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir");
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");
+ fprintf(stderr, "Failed to find the Visual Studio installation directory.\n");
+ return false;
+ }
+
+ regKey = regKeyPrefix
+ + (isPhone ? QStringLiteral("Microsoft\\Microsoft SDKs\\WindowsPhone\\v")
+ : QStringLiteral("Microsoft\\Microsoft SDKs\\Windows\\v"))
+ + winsdkVer + QStringLiteral("\\InstallationFolder");
+ const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey);
+ if (kitDir.isEmpty()) {
+ fprintf(stderr, "Failed to find the Windows Kit installation directory.\n");
return false;
}
#else
const QString vcInstallDir = "/fake/vc_install_dir";
+ const QString kitDir = "/fake/sdk_install_dir";
#endif // Q_OS_WIN
QStringList incDirs;
QStringList libDirs;
QStringList binDirs;
- const bool isPhone = project->isActiveConfig(QStringLiteral("winphone"));
if (isPhone) {
- QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/WP80");
+ QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/") + targetVer;
if (!QDir(sdkDir).exists()) {
fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n"
"Check that it is properly installed.\n",
@@ -155,14 +190,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
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")
@@ -170,18 +197,11 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
<< kitDir + QStringLiteral("/include/minwin");
} else {
incDirs << vcInstallDir + QStringLiteral("/include");
- libDirs << vcInstallDir + QStringLiteral("/lib/") + compilerArch;
+ libDirs << vcInstallDir + QStringLiteral("/lib/store/") + compilerArch
+ << 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;
+ libDirs << kitDir + QStringLiteral("/Lib/") + targetVer + ("/um/") + arch;
incDirs << kitDir + QStringLiteral("/include/um")
<< kitDir + QStringLiteral("/include/shared")
<< kitDir + QStringLiteral("/include/winrt");
@@ -285,7 +305,7 @@ void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t)
}
}
-QString NmakeMakefileGenerator::var(const ProKey &value)
+QString NmakeMakefileGenerator::var(const ProKey &value) const
{
if (usePCH) {
if ((value == "QMAKE_RUN_CXX_IMP_BATCH"
diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h
index 7a47bb8cec..4d3c69bdd6 100644
--- a/qmake/generators/win32/msvc_nmake.h
+++ b/qmake/generators/win32/msvc_nmake.h
@@ -62,7 +62,7 @@ protected:
virtual QString getPdbTarget();
virtual QString defaultInstall(const QString &t);
virtual QStringList &findDependencies(const QString &file);
- QString var(const ProKey &value);
+ QString var(const ProKey &value) const;
QString precompH, precompObj, precompPch;
bool usePCH;
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index a2a441c6bf..633682baf4 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -1537,7 +1537,7 @@ bool VCLinkerTool::parseOption(const char* option)
AdditionalOptions.append(option);
}
break;
- case 0x379ED25:
+ case 0x379ED25:
case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
switch (elfHash(option+9)) {
// Very limited documentation on all options but X86,
@@ -1667,7 +1667,7 @@ bool VCLinkerTool::parseOption(const char* option)
else
AdditionalOptions += option;
break;
- case 0x9B3C00D:
+ case 0x9B3C00D:
case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
{
// Split up in subsystem, and version number
@@ -2253,7 +2253,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
CustomBuildTool.Description.clear();
CustomBuildTool.Outputs.clear();
CustomBuildTool.ToolPath.clear();
- CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
+ CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
for (int x = 0; x < extraCompilers.count(); ++x) {
const QString &extraCompilerName = extraCompilers.at(x);
@@ -2291,13 +2291,13 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
}
// Dependency for the output
- if(!tmp_dep.isEmpty())
- deps = tmp_dep;
- if(!tmp_dep_cmd.isEmpty()) {
+ if (!tmp_dep.isEmpty())
+ deps = tmp_dep;
+ if (!tmp_dep_cmd.isEmpty()) {
// Execute dependency command, and add every line as a dep
- char buff[256];
- QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
- Option::fixPathToLocalOS(inFile, true, false),
+ char buff[256];
+ QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
+ Option::fixPathToLocalOS(inFile, true, false),
out);
if(Project->canExecute(dep_cmd)) {
dep_cmd.prepend(QLatin1String("cd ")
@@ -2324,7 +2324,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
}
}
for (int i = 0; i < deps.count(); ++i)
- deps[i] = Option::fixPathToTargetOS(
+ deps[i] = Option::fixPathToTargetOS(
Project->replaceExtraCompilerVariables(deps.at(i), inFile, out),
false).trimmed();
// Command for file
@@ -2353,18 +2353,18 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
out);
}
// Name for command
- if(!tmp_cmd_name.isEmpty()) {
- cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
- } else {
- int space = cmd.indexOf(' ');
- if(space != -1)
- cmd_name = cmd.left(space);
- else
- cmd_name = cmd;
- if((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
- cmd_name[0] == cmd_name[cmd_name.length()-1])
- cmd_name = cmd_name.mid(1,cmd_name.length()-2);
- }
+ if (!tmp_cmd_name.isEmpty()) {
+ cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
+ } else {
+ int space = cmd.indexOf(' ');
+ if (space != -1)
+ cmd_name = cmd.left(space);
+ else
+ cmd_name = cmd;
+ if ((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
+ cmd_name[0] == cmd_name[cmd_name.length()-1])
+ cmd_name = cmd_name.mid(1,cmd_name.length()-2);
+ }
// Fixify paths
for (int i = 0; i < deps.count(); ++i)
@@ -2799,6 +2799,12 @@ void VCProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
<< closetag(tool.DeploymentTag);
}
+void VCProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
+{
+ Q_UNUSED(xml);
+ Q_UNUSED(tool);
+}
+
void VCProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
{
xml << tag(_Configuration)
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 58b528301c..0aa5736d2a 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -860,6 +860,24 @@ public:
~VCPreLinkEventTool(){}
};
+class VCWinDeployQtTool : public VCToolBase
+{
+public:
+ VCWinDeployQtTool() {}
+ ~VCWinDeployQtTool() {}
+
+protected:
+ bool parseOption(const char *) { return false; }
+
+public:
+ // Variables
+ QString Record;
+ QString CommandLine;
+ bool ExcludedFromBuild;
+
+ VCConfiguration * config;
+};
+
class VCConfiguration
{
public:
@@ -900,6 +918,7 @@ public:
VCDeploymentTool deployment;
VCPreLinkEventTool preLink;
VCResourceCompilerTool resource;
+ VCWinDeployQtTool windeployqt;
};
struct VCFilterFile
@@ -955,7 +974,7 @@ public:
VCConfiguration* Config;
QList<VCFilterFile> Files;
- customBuildCheck CustomBuild;
+ customBuildCheck CustomBuild;
bool useCustomBuildTool;
VCCustomBuildTool CustomBuildTool;
@@ -990,6 +1009,7 @@ public:
QString SccProjectName;
QString SccLocalPath;
QString PlatformName;
+ QString SdkVersion;
// XML sub-parts
VCConfiguration Configuration;
@@ -1129,6 +1149,7 @@ public:
QString SccProjectName;
QString SccLocalPath;
QString PlatformName;
+ QString SdkVersion;
// Single projects
QList<VCProjectSingleConfig> SingleProjects;
@@ -1154,6 +1175,7 @@ public:
virtual void write(XmlOutput &, const VCResourceCompilerTool &);
virtual void write(XmlOutput &, const VCEventTool &);
virtual void write(XmlOutput &, const VCDeploymentTool &);
+ virtual void write(XmlOutput &, const VCWinDeployQtTool &);
virtual void write(XmlOutput &, const VCConfiguration &);
virtual void write(XmlOutput &, VCFilter &);
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index f86c8512d4..ce9dc6d9ec 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -111,9 +111,10 @@ QT_END_NAMESPACE
#endif
QT_BEGIN_NAMESPACE
-DotNET which_dotnet_version()
+DotNET which_dotnet_version(const QByteArray &preferredVersion = QByteArray())
{
#ifndef Q_OS_WIN32
+ Q_UNUSED(preferredVersion);
return NET2002; // Always generate 7.0 versions on other platforms
#else
// Only search for the version once
@@ -135,6 +136,10 @@ DotNET which_dotnet_version()
installPaths.insert(lowestInstalledVersion->version, path);
++installed;
current_version = lowestInstalledVersion->version;
+ if (QByteArray(lowestInstalledVersion->versionStr).contains(preferredVersion)) {
+ installed = 1;
+ break;
+ }
}
}
@@ -286,6 +291,7 @@ bool VcprojGenerator::writeProjectMakefile()
mergedProjects.at(0)->writePrlFile();
mergedProject.Name = project->first("QMAKE_PROJECT_NAME").toQString();
mergedProject.Version = mergedProjects.at(0)->vcProject.Version;
+ mergedProject.SdkVersion = mergedProjects.at(0)->vcProject.SdkVersion;
mergedProject.ProjectGUID = project->isEmpty("QMAKE_UUID") ? getProjectUUID().toString().toUpper() : project->first("QMAKE_UUID").toQString();
mergedProject.Keyword = project->first("VCPROJ_KEYWORD").toQString();
mergedProject.SccProjectName = mergedProjects.at(0)->vcProject.SccProjectName;
@@ -585,7 +591,7 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
return;
}
- switch(which_dotnet_version()) {
+ switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) {
case NET2013:
t << _slnHeader120;
break;
@@ -874,12 +880,12 @@ void VcprojGenerator::initProject()
// Own elements -----------------------------
vcProject.Name = unescapeFilePath(project->first("QMAKE_ORIG_TARGET").toQString());
- switch(which_dotnet_version()) {
+ switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) {
case NET2013:
- vcProject.Version = "13.00";
+ vcProject.Version = "12.00";
break;
case NET2012:
- vcProject.Version = "12.00";
+ vcProject.Version = "11.00";
break;
case NET2010:
vcProject.Version = "10.00";
@@ -912,6 +918,7 @@ void VcprojGenerator::initProject()
} else {
vcProject.PlatformName = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
}
+ vcProject.SdkVersion = project->first("WINSDK_VER").toQString();
// These are not used by Qt, but may be used by customers
vcProject.SccProjectName = project->first("SCCPROJECTNAME").toQString();
vcProject.SccLocalPath = project->first("SCCLOCALPATH").toQString();
@@ -924,7 +931,7 @@ void VcprojGenerator::initConfiguration()
// - Do this first since main configuration elements may need
// - to know of certain compiler/linker options
VCConfiguration &conf = vcProject.Configuration;
- conf.CompilerVersion = which_dotnet_version();
+ conf.CompilerVersion = which_dotnet_version(project->first("MSVC_VER").toLatin1());
initCompilerTool();
@@ -970,8 +977,13 @@ void VcprojGenerator::initConfiguration()
if (conf.CompilerVersion >= NET2012) {
conf.WinRT = project->isActiveConfig("winrt");
- if (conf.WinRT)
+ if (conf.WinRT) {
conf.WinPhone = project->isActiveConfig("winphone");
+ // Saner defaults
+ conf.compiler.UsePrecompiledHeader = pchNone;
+ conf.compiler.CompileAsWinRT = _False;
+ conf.linker.GenerateWindowsMetadata = _False;
+ }
}
conf.Name = project->values("BUILD_NAME").join(' ');
@@ -988,7 +1000,7 @@ void VcprojGenerator::initConfiguration()
conf.ATLMinimizesCRunTimeLibraryUsage = (project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True);
conf.BuildBrowserInformation = triState(temp.isEmpty() ? (short)unset : temp.toShort());
temp = project->first("CharacterSet");
- conf.CharacterSet = charSet(temp.isEmpty() ? (short)charSetNotSet : temp.toShort());
+ conf.CharacterSet = charSet(temp.isEmpty() ? short(conf.WinRT ? charSetUnicode : charSetNotSet) : temp.toShort());
conf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean").toQString();
conf.ImportLibrary = conf.linker.ImportLibrary;
conf.IntermediateDirectory = project->first("OBJECTS_DIR").toQString();
@@ -1009,6 +1021,7 @@ void VcprojGenerator::initConfiguration()
if ((!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|| conf.WinRT)
initDeploymentTool();
+ initWinDeployQtTool();
initPreLinkEventTools();
if (!isDebug)
@@ -1311,6 +1324,22 @@ void VcprojGenerator::initDeploymentTool()
}
}
+void VcprojGenerator::initWinDeployQtTool()
+{
+ VCConfiguration &conf = vcProject.Configuration;
+ conf.windeployqt.ExcludedFromBuild = true;
+ if (project->isActiveConfig("windeployqt")) {
+ conf.windeployqt.Record = QStringLiteral("$(TargetName).windeployqt.$(Platform).$(Configuration)");
+ conf.windeployqt.CommandLine =
+ MakefileGenerator::shellQuote(QDir::toNativeSeparators(project->first("QMAKE_WINDEPLOYQT").toQString()))
+ + QLatin1Char(' ') + project->values("WINDEPLOYQT_OPTIONS").join(QLatin1Char(' '))
+ + QStringLiteral(" -list relative -dir \"$(MSBuildProjectDirectory)\" \"$(OutDir)\\$(TargetName).exe\" > ")
+ + MakefileGenerator::shellQuote(conf.windeployqt.Record);
+ conf.windeployqt.config = &vcProject.Configuration;
+ conf.windeployqt.ExcludedFromBuild = false;
+ }
+}
+
void VcprojGenerator::initPreLinkEventTools()
{
VCConfiguration &conf = vcProject.Configuration;
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index d531085307..4a25d11766 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -109,6 +109,7 @@ protected:
void initPreBuildEventTools();
void initPostBuildEventTools();
void initDeploymentTool();
+ void initWinDeployQtTool();
void initPreLinkEventTools();
void initRootFiles();
void initSourceFiles();
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 30d28e6e11..484062d56e 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -89,12 +89,12 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem
QRegExp regx(QString("((lib)?%1([0-9]*)).(%2|prl)$").arg(stem).arg(ext), Qt::CaseInsensitive);
for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) {
if(regx.exactMatch((*it))) {
- if (!regx.cap(3).isEmpty()) {
- bool ok = true;
- int num = regx.cap(3).toInt(&ok);
- biggest = qMax(biggest, (!ok ? -1 : num));
- }
- }
+ if (!regx.cap(3).isEmpty()) {
+ bool ok = true;
+ int num = regx.cap(3).toInt(&ok);
+ biggest = qMax(biggest, (!ok ? -1 : num));
+ }
+ }
}
}
if(libInfoRead
@@ -485,20 +485,20 @@ void Win32MakefileGenerator::processRcFileVar()
rcFile.close();
}
if (writeRcFile) {
- bool ok;
- ok = rcFile.open(QFile::WriteOnly);
- if (!ok) {
- // The file can't be opened... try creating the containing
- // directory first (needed for clean shadow builds)
- QDir().mkpath(QFileInfo(rcFile).path());
- ok = rcFile.open(QFile::WriteOnly);
- }
- if (!ok) {
- ::fprintf(stderr, "Cannot open for writing: %s", rcFile.fileName().toLatin1().constData());
- ::exit(1);
- }
- rcFile.write(rcString);
- rcFile.close();
+ bool ok;
+ ok = rcFile.open(QFile::WriteOnly);
+ if (!ok) {
+ // The file can't be opened... try creating the containing
+ // directory first (needed for clean shadow builds)
+ QDir().mkpath(QFileInfo(rcFile).path());
+ ok = rcFile.open(QFile::WriteOnly);
+ }
+ if (!ok) {
+ ::fprintf(stderr, "Cannot open for writing: %s", rcFile.fileName().toLatin1().constData());
+ ::exit(1);
+ }
+ rcFile.write(rcString);
+ rcFile.close();
}
if (project->values("QMAKE_WRITE_DEFAULT_RC").isEmpty())
project->values("RC_FILE").insert(0, rcFile.fileName());
@@ -530,7 +530,7 @@ void Win32MakefileGenerator::processRcFileVar()
}
project->values("RES_FILE").first() = Option::fixPathToTargetOS(
project->values("RES_FILE").first().toQString(), false, false);
- project->values("POST_TARGETDEPS") += project->values("RES_FILE");
+ project->values("POST_TARGETDEPS") += project->values("RES_FILE");
project->values("CLEAN_FILES") += project->values("RES_FILE");
}
}
@@ -565,7 +565,7 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t)
}
t << endl << endl;
- t << "distclean: clean";
+ t << "distclean: clean " << var("DISTCLEAN_DEPS");
{
const char *clean_targets[] = { "QMAKE_DISTCLEAN", 0 };
for(int i = 0; clean_targets[i]; ++i) {