diff options
author | Liang Qi <liang.qi@qt.io> | 2017-01-24 10:33:37 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-01-25 20:06:06 +0100 |
commit | 318b58562ae89453fb98e8145cd0440e14ba60b0 (patch) | |
tree | 622bc032cf076b4569621032f3a3315d95c3ae88 /qmake/generators/win32 | |
parent | c28fde3fdac19fd5a5f614bb7983080031c924b3 (diff) | |
parent | 79352528a1726b4551ea4d9285dd2394dd0d43da (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts:
.qmake.conf
mkspecs/common/msvc-desktop.conf
mkspecs/common/msvc-version.conf
mkspecs/common/winrt_winphone/qmake.conf
mkspecs/features/mac/default_post.prf
mkspecs/features/mac/sdk.prf
mkspecs/features/qt.prf
mkspecs/features/uikit/default_post.prf
mkspecs/features/winrt/default_pre.prf
mkspecs/winphone-arm-msvc2013/qmake.conf
mkspecs/winphone-x86-msvc2013/qmake.conf
mkspecs/winrt-arm-msvc2013/qmake.conf
mkspecs/winrt-x64-msvc2013/qmake.conf
mkspecs/winrt-x86-msvc2013/qmake.conf
qmake/generators/win32/msvc_vcproj.cpp
src/gui/kernel/qwindowsysteminterface.cpp
src/network/kernel/qhostaddress.cpp
src/plugins/platforms/mirclient/qmirclientplugin.cpp
src/plugins/platforms/mirclient/qmirclientplugin.h
src/widgets/util/qsystemtrayicon.cpp
tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
tools/configure/Makefile.mingw
tools/configure/Makefile.win32
Done-with: Jake Petroules <jake.petroules@qt.io>
Done-with: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Change-Id: I4be3262d3994e11929d3b1ded2c3379783797dbe
Diffstat (limited to 'qmake/generators/win32')
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.cpp | 22 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.h | 1 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 94 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.cpp | 3 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 25 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.h | 1 | ||||
-rw-r--r-- | qmake/generators/win32/registry.cpp | 158 | ||||
-rw-r--r-- | qmake/generators/win32/registry_p.h | 73 |
8 files changed, 348 insertions, 29 deletions
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 3f789405b2..129fb28e01 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -176,7 +176,7 @@ const char _Optimization[] = "Optimization"; const char _OptimizeReferences[] = "OptimizeReferences"; const char _OutputDirectory[] = "OutputDirectory"; const char _OutputFile[] = "OutputFile"; -const char _PlatformToolSet[] = "PlatformToolSet"; +const char _PlatformToolSet[] = "PlatformToolset"; const char _PrecompiledHeader[] = "PrecompiledHeader"; const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile"; const char _PrecompiledHeaderOutputFile[] = "PrecompiledHeaderOutputFile"; @@ -406,7 +406,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -550,7 +550,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) xmlFilter << decl("1.0", "utf-8") << tag("Project") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); xmlFilter << tag("ItemGroup"); @@ -587,6 +587,8 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x)); } + outputFilter(tempProj, xml, xmlFilter, "Root Files"); + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); xml << tag("ImportGroup") @@ -603,13 +605,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); - const QString toolsVersion = (tool.SdkVersion == QLatin1String("10.0")) ? QStringLiteral("14.0") - : QStringLiteral("4.0"); - xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", toolsVersion) + << attrTagToolsVersion(tool.SingleProjects.first().Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -794,7 +793,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xmlFilter << decl("1.0", "utf-8") << tag("Project") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.SingleProjects.first().Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); xmlFilter << tag("ItemGroup"); @@ -2054,4 +2053,11 @@ QString VCXProjectWriter::generateCondition(const VCConfiguration &config) return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\''); } +XmlOutput::xml_output VCXProjectWriter::attrTagToolsVersion(const VCConfiguration &config) +{ + if (config.CompilerVersion >= NET2013) + return noxml(); + return attrTag("ToolsVersion", "4.0"); +} + QT_END_NAMESPACE diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h index fe46430e60..2e77537916 100644 --- a/qmake/generators/win32/msbuild_objectmodel.h +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -182,6 +182,7 @@ private: bool fileAdded, bool hasCustomBuildStep); static void outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &fileName, const QString &filterName); static QString generateCondition(const VCConfiguration &config); + static XmlOutput::xml_output attrTagToolsVersion(const VCConfiguration &config); friend class XTreeNode; friend class XFlatNode; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 380ce60c5b..c19c101d43 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -34,7 +34,7 @@ #include <qdiriterator.h> #include <qset.h> -#include <windows/registry_p.h> +#include <registry_p.h> #include <time.h> @@ -75,25 +75,44 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); QString compiler; QString compilerArch; - if (arch == QLatin1String("arm")) { - compiler = QStringLiteral("x86_arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { + const QString msvcVer = project->first("MSVC_VER").toQString(); + if (msvcVer.isEmpty()) { + fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); + return false; + } + + if (msvcVer == QStringLiteral("15.0")) { const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); if (hostArch.contains("x86_64")) - compiler = QStringLiteral("amd64"); + compiler = QStringLiteral("HostX64/"); else - compiler = QStringLiteral("x86_amd64"); - compilerArch = QStringLiteral("amd64"); + compiler = QStringLiteral("HostX86/"); + if (arch == QLatin1String("arm")) { + compiler += QStringLiteral("arm"); + compilerArch = QStringLiteral("arm"); + } else if (arch == QLatin1String("x64")) { + compiler += QStringLiteral("x64"); + compilerArch = QStringLiteral("amd64"); + } else { + compiler += QStringLiteral("x86"); + compilerArch = QStringLiteral("amd64"); + } } else { - arch = QStringLiteral("x86"); + if (arch == QLatin1String("arm")) { + compiler = QStringLiteral("x86_arm"); + compilerArch = QStringLiteral("arm"); + } else if (arch == QLatin1String("x64")) { + const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); + if (hostArch.contains("x86_64")) + compiler = QStringLiteral("amd64"); + else + 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"); @@ -106,7 +125,11 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } #ifdef Q_OS_WIN - QString regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); + QString regKey; + if (msvcVer == QStringLiteral("15.0")) + regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\SxS\\VS7\\") + msvcVer; + else + regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); if (vcInstallDir.isEmpty()) { fprintf(stderr, "Failed to find the Visual Studio installation directory.\n"); @@ -128,7 +151,46 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (msvcVer == QStringLiteral("14.0")) { + if (msvcVer == QStringLiteral("15.0")) { + const QString toolsInstallDir = qgetenv("VCToolsInstallDir"); + if (toolsInstallDir.isEmpty()) { + fprintf(stderr, "Failed to access tools installation dir.\n"); + return false; + } + + binDirs << toolsInstallDir + QStringLiteral("bin/") + compiler; + if (arch == QStringLiteral("x64")) + binDirs << toolsInstallDir + QStringLiteral("bin/HostX86/X86"); + binDirs << kitDir + QStringLiteral("bin/x86"); + binDirs << vcInstallDir + QStringLiteral("Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("Common7/ide"); + binDirs << vcInstallDir + QStringLiteral("MSBuild/15.0/bin"); + + incDirs << toolsInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/include"); + + const QString crtVersion = qgetenv("UCRTVersion"); + if (crtVersion.isEmpty()) { + fprintf(stderr, "Failed to access CRT version.\n"); + return false; + } + const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; + const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; + incDirs << crtInclude + QStringLiteral("/ucrt"); + incDirs << crtInclude + QStringLiteral("/um"); + incDirs << crtInclude + QStringLiteral("/shared"); + incDirs << crtInclude + QStringLiteral("/winrt"); + + incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") + + crtVersion + QStringLiteral("/Include/WinRT"); + + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + + libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; + + libDirs << crtLib + QStringLiteral("/ucrt/") + arch; + libDirs << crtLib + QStringLiteral("/um/") + arch; + } else if (msvcVer == QStringLiteral("14.0")) { binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 33d96c146c..60734b4d1b 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -54,7 +54,8 @@ static DotNET vsVersionFromString(const char *versionString) "10.0", NET2010, "11.0", NET2012, "12.0", NET2013, - "14.0", NET2015 + "14.0", NET2015, + "15.0", NET2017 }; DotNET result = NETUnknown; for (const auto entry : mapping) { diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index b3da4db4c5..3d5b80e06d 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -670,6 +670,21 @@ bool VcprojGenerator::hasBuiltinCompiler(const QString &file) return false; } +void VcprojGenerator::createCustomBuildToolFakeFile(const QString &cbtFilePath, + const QString &realOutFilePath) +{ + QFile file(fileFixify(cbtFilePath, FileFixifyFromOutdir | FileFixifyAbsolute)); + if (file.exists()) + return; + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + warn_msg(WarnLogic, "Cannot create '%s'.", qPrintable(file.fileName())); + return; + } + file.write("This is a dummy file needed to create "); + file.write(qPrintable(realOutFilePath)); + file.write("\n"); +} + void VcprojGenerator::init() { is64Bit = (project->first("QMAKE_TARGET.arch") == "x86_64"); @@ -797,12 +812,14 @@ void VcprojGenerator::init() if (!hasBuiltinCompiler(file)) { extraCompilerSources[file] += quc.toQString(); } else { - // Use a fake file name foo.moc.cbt for the project view. + // Create a fake file foo.moc.cbt for the project view. // This prevents VS from complaining about a circular // dependency from foo.moc -> foo.moc. - QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables( - compiler_out, file, QString(), NoShell), false); - out += customBuildToolFilterFileSuffix; + QString realOut = replaceExtraCompilerVariables( + compiler_out, file, QString(), NoShell); + QString out = realOut + customBuildToolFilterFileSuffix; + createCustomBuildToolFakeFile(out, realOut); + out = Option::fixPathToTargetOS(out, false); extraCompilerSources[out] += quc.toQString(); extraCompilerOutputs[out] = file; } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index e3e67d64b9..4882296b46 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -130,6 +130,7 @@ private: bool isStandardSuffix(const QString &suffix) const; ProString firstInputFileName(const ProString &extraCompilerName) const; QString firstExpandedOutputFileName(const ProString &extraCompilerName); + void createCustomBuildToolFakeFile(const QString &cbtFilePath, const QString &realOutFilePath); friend class VCFilter; }; diff --git a/qmake/generators/win32/registry.cpp b/qmake/generators/win32/registry.cpp new file mode 100644 index 0000000000..74c912ca43 --- /dev/null +++ b/qmake/generators/win32/registry.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstringlist.h> +#include "registry_p.h" + +QT_BEGIN_NAMESPACE + +#ifdef Q_OS_WIN32 +/*! + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/*! + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == QLatin1String("Default") || res == QLatin1String(".")) + res = QString(); + return res; +} +#endif + +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned long options) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = 0; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, + KEY_READ | options, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast<unsigned char*>(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(QLatin1String(", ")); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType)); + break; + } + + RegCloseKey(handle); +#else + Q_UNUSED(parentHandle); + Q_UNUSED(rSubkey) + Q_UNUSED(options); +#endif + + return result; +} + +QT_END_NAMESPACE + diff --git a/qmake/generators/win32/registry_p.h b/qmake/generators/win32/registry_p.h new file mode 100644 index 0000000000..3526dffd45 --- /dev/null +++ b/qmake/generators/win32/registry_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_WINDOWS_REGISTRY_H +#define QT_WINDOWS_REGISTRY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +#include <QtCore/qglobal.h> + +#ifdef Q_OS_WIN32 + #include <QtCore/qt_windows.h> +#else + typedef void* HKEY; +#endif + +#include <QtCore/qstring.h> + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + * + * 32-bit code reads from the registry's 32 bit view (Wow6432Node), + * 64 bit code reads from the 64 bit view. + * Pass KEY_WOW64_32KEY to access the 32 bit view regardless of the + * application's architecture, KEY_WOW64_64KEY respectively. + */ +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, + unsigned long options = 0); + +QT_END_NAMESPACE + +#endif // QT_WINDOWS_REGISTRY_H + |