diff options
Diffstat (limited to 'qmake/generators/win32')
-rw-r--r-- | qmake/generators/win32/mingw_make.cpp | 60 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.cpp | 103 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.h | 1 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 74 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.h | 2 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.cpp | 50 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.h | 24 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 45 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.h | 1 | ||||
-rw-r--r-- | qmake/generators/win32/winmakefile.cpp | 44 |
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 8159cf58e2..1a92b79a09 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1532,7 +1532,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, @@ -1662,7 +1662,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 @@ -2248,7 +2248,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); @@ -2286,13 +2286,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 ") @@ -2319,7 +2319,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 @@ -2348,18 +2348,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) @@ -2794,6 +2794,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) { |