From d9203fa534f31509e87bb6c6c702c1b7149372e3 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 22 Nov 2016 13:14:53 +0100 Subject: [PATCH] winrt: Add support for Visual Studio 2017 Tested with RC Task-number: QTBUG-57086 Change-Id: I57ecfd0751538dcba41ebaf028de1bc5b4debbb7 Reviewed-by: Maurice Kalinowski --- mkspecs/features/winrt/default_pre.prf | 2 +- mkspecs/features/winrt/package_manifest.prf | 6 +- mkspecs/winrt-x64-msvc2017/qmake.conf | 20 +++++ mkspecs/winrt-x64-msvc2017/qplatformdefs.h | 40 +++++++++ mkspecs/winrt-x86-msvc2017/qmake.conf | 19 +++++ mkspecs/winrt-x86-msvc2017/qplatformdefs.h | 40 +++++++++ qmake/generators/win32/msvc_nmake.cpp | 92 +++++++++++++++++---- 7 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 mkspecs/winrt-x64-msvc2017/qmake.conf create mode 100644 mkspecs/winrt-x64-msvc2017/qplatformdefs.h create mode 100644 mkspecs/winrt-x86-msvc2017/qmake.conf create mode 100644 mkspecs/winrt-x86-msvc2017/qplatformdefs.h diff --git a/mkspecs/features/winrt/default_pre.prf b/mkspecs/features/winrt/default_pre.prf index f397ef3d618..f79d04ce41b 100644 --- a/mkspecs/features/winrt/default_pre.prf +++ b/mkspecs/features/winrt/default_pre.prf @@ -1,4 +1,4 @@ -*msvc2015 { +*msvc2015|*msvc2017 { # Note that the order is important - ucrt(d) has to be first. # Otherwise, the linker might use malloc from a different library, # but free_dbg() from the runtime, causing an assertion failure diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index e7859a7caee..e0e421ed9ab 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -94,7 +94,7 @@ isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en - *-msvc2015 { + *-msvc2015|*-msvc2017 { isEmpty(WINRT_MANIFEST.minVersion): WINRT_MANIFEST.minVersion = $$(UCRTVersion) isEmpty(WINRT_MANIFEST.minVersion): error("No UCRTVersion found in environment.")) isEmpty(WINRT_MANIFEST.maxVersionTested): WINRT_MANIFEST.maxVersionTested = $$WINRT_MANIFEST.minVersion @@ -118,7 +118,7 @@ # All Windows 10 applications need to have internetClient. It is also not marked as additional # capability anymore and is assumed to be standard. - *-msvc2015: WINRT_MANIFEST.capabilities += internetClient + *-msvc2015|*-msvc2017: WINRT_MANIFEST.capabilities += internetClient contains(WINRT_MANIFEST.capabilities, defaults) { WINRT_MANIFEST.capabilities -= defaults @@ -145,7 +145,7 @@ } # Dependencies are given as a string list. The CRT dependency is added automatically above. - # For MSVC2015 the dependencies are added in conjunction with TargetDeviceFamily + # For MSVC2015/2017 the dependencies are added in conjunction with TargetDeviceFamily # Due to the hard coded dependency on "Windows.Universal" the tag # is already inside the MSVC2015 manifest. WINRT_MANIFEST.dependencies = $$unique(WINRT_MANIFEST.dependencies) diff --git a/mkspecs/winrt-x64-msvc2017/qmake.conf b/mkspecs/winrt-x64-msvc2017/qmake.conf new file mode 100644 index 00000000000..cb2209fa23b --- /dev/null +++ b/mkspecs/winrt-x64-msvc2017/qmake.conf @@ -0,0 +1,20 @@ +# +# qmake configuration for winrt-x64-msvc2017 +# +# Written for Microsoft Visual C++ 2017 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib + +VCPROJ_ARCH = x64 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2017/qplatformdefs.h b/mkspecs/winrt-x64-msvc2017/qplatformdefs.h new file mode 100644 index 00000000000..2a1aef5e88c --- /dev/null +++ b/mkspecs/winrt-x64-msvc2017/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2017/qmake.conf b/mkspecs/winrt-x86-msvc2017/qmake.conf new file mode 100644 index 00000000000..3c9506bbad0 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2017/qmake.conf @@ -0,0 +1,19 @@ +# +# qmake configuration for winrt-x86-msvc2017 +# +# Written for Microsoft Visual C++ 2017 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib +VCPROJ_ARCH = Win32 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2017/qplatformdefs.h b/mkspecs/winrt-x86-msvc2017/qplatformdefs.h new file mode 100644 index 00000000000..2a1aef5e88c --- /dev/null +++ b/mkspecs/winrt-x86-msvc2017/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 5b5eecd3735..92043e829fc 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -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"); @@ -107,7 +126,11 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) const bool isPhone = project->isActiveConfig(QStringLiteral("winphone")); #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"); @@ -134,7 +157,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);