From fbbe8aba9d70a3c13d1cd7797eb4dbbd1f05ade5 Mon Sep 17 00:00:00 2001 From: Thomas Miller Date: Mon, 15 Oct 2018 11:20:10 -0700 Subject: Add Windows Desktop arm64 target to Qtbase Allows a qt build to be configured to target arm64 desktop apps cross platform and build them with nmake. Change-Id: I99fed12047b45a504a1644201bcc19b18c69f3e6 Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff --- mkspecs/win32-arm64-msvc2017/qmake.conf | 15 ++++++ mkspecs/win32-arm64-msvc2017/qplatformdefs.h | 40 ++++++++++++++ qmake/generators/win32/msvc_nmake.cpp | 46 +++++++++++----- src/3rdparty/angle/src/common/mathutil.h | 8 +-- src/3rdparty/angle/src/common/platform.h | 2 +- .../patches/0011-ANGLE-Fix-build-for-ARM64.patch | 63 ++++++++++++++++++++++ src/corelib/global/qprocessordetection.h | 9 ++-- 7 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 mkspecs/win32-arm64-msvc2017/qmake.conf create mode 100644 mkspecs/win32-arm64-msvc2017/qplatformdefs.h create mode 100644 src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch diff --git a/mkspecs/win32-arm64-msvc2017/qmake.conf b/mkspecs/win32-arm64-msvc2017/qmake.conf new file mode 100644 index 0000000000..ee10f9cc40 --- /dev/null +++ b/mkspecs/win32-arm64-msvc2017/qmake.conf @@ -0,0 +1,15 @@ +# +# qmake configuration for win32-arm64-msvc2017 +# +# Written for Microsoft C/C++ Optimizing Compiler targeting arm64. +# + +include(../common/msvc-desktop.conf) + +WINSDK_VER = 10.0 +VCPROJ_ARCH = ARM64 + +DEFINES += WIN64 +QMAKE_COMPILER_DEFINES += _WIN64 + +load(qt_config) diff --git a/mkspecs/win32-arm64-msvc2017/qplatformdefs.h b/mkspecs/win32-arm64-msvc2017/qplatformdefs.h new file mode 100644 index 0000000000..8a3afa7630 --- /dev/null +++ b/mkspecs/win32-arm64-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 "../win32-msvc/qplatformdefs.h" diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index f2cd7c633b..306ae57871 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -71,18 +71,28 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return MakefileGenerator::writeStubMakefile(t); #endif if (!project->isHostBuild()) { + const QString msvcVer = project->first("MSVC_VER").toQString(); + if (msvcVer.isEmpty()) { + fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); + return false; + } + + bool winrtBuild = false; + bool crossPlatformDesktopBuild = false; + QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); if (project->isActiveConfig(QStringLiteral("winrt"))) { - QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); + winrtBuild = true; + + // Only add explicit support for arm64 cross-platform desktop builds. + } else if ((arch == QLatin1String("arm64")) && (msvcVer == QStringLiteral("15.0"))) { + crossPlatformDesktopBuild = true; + } + + if (winrtBuild || crossPlatformDesktopBuild) { QString compiler; QString compilerArch; - 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 ProStringList hostArch = project->values("QMAKE_TARGET.arch"); if (msvcVer == QStringLiteral("15.0")) { - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); if (hostArch.contains("x86_64")) compiler = QStringLiteral("HostX64/"); else @@ -93,6 +103,9 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } else if (arch == QLatin1String("x64")) { compiler += QStringLiteral("x64"); compilerArch = QStringLiteral("amd64"); + } else if (arch == QLatin1String("arm64")) { + compiler += QStringLiteral("arm64"); + compilerArch = QStringLiteral("arm64"); } else { arch = QStringLiteral("x86"); compiler += QStringLiteral("x86"); @@ -119,7 +132,7 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return false; } const QString targetVer = project->first("WINTARGET_VER").toQString(); - if (targetVer.isEmpty()) { + if (targetVer.isEmpty() && winrtBuild) { fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n"); return false; } @@ -181,10 +194,19 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) incDirs << crtInclude + QStringLiteral("/shared"); incDirs << crtInclude + QStringLiteral("/winrt"); - incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") - + crtVersion + QStringLiteral("/Include/WinRT"); + if (winrtBuild) { + // Only use mobile-specific headers and link against store-specific libs for + // winrt builds. + incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") + + crtVersion + QStringLiteral("/Include/WinRT"); - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + } else { + // Desktop projects may require the atl headers and libs. + incDirs << toolsInstallDir + QStringLiteral("atlmfc/include"); + libDirs << toolsInstallDir + QStringLiteral("atlmfc/lib/") + compilerArch; + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch; + } libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h index 372e432066..88aedddfe8 100644 --- a/src/3rdparty/angle/src/common/mathutil.h +++ b/src/3rdparty/angle/src/common/mathutil.h @@ -150,7 +150,7 @@ inline bool supportsSSE2() return supports; } -#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) { int info[4]; __cpuid(info, 0); @@ -162,7 +162,7 @@ inline bool supportsSSE2() supports = (info[3] >> 26) & 1; } } -#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) checked = true; return supports; #else // defined(ANGLE_USE_SSE) @@ -884,14 +884,14 @@ inline uint32_t BitfieldReverse(uint32_t value) // Count the 1 bits. #if defined(ANGLE_PLATFORM_WINDOWS) -#if defined(_M_ARM) +#if defined(_M_ARM) || defined(_M_ARM64) inline int BitCount(uint32_t bits) { bits = bits - ((bits >> 1) & 0x55555555); bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; } -#else // _M_ARM +#else // _M_ARM || _M_ARM64 inline int BitCount(uint32_t bits) { return static_cast(__popcnt(bits)); diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index 47cd57b999..fb251da579 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -83,7 +83,7 @@ # undef far #endif -#if defined(_MSC_VER) && !defined(_M_ARM) +#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) #include #define ANGLE_USE_SSE #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) diff --git a/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch b/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch new file mode 100644 index 0000000000..3a43894a8a --- /dev/null +++ b/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch @@ -0,0 +1,63 @@ +From 416fb93dae5009bb51da9f6720a95918a2c79e78 Mon Sep 17 00:00:00 2001 +From: Thomas Miller +Date: Tue Oct 16 08:29:58 2018 -0700 +Subject: [PATCH] ANGLE: Fix build for ARM64 + +__popcnt, SSE, and intrin.h are not available when building for ARM64. +--- + src/3rdparty/angle/src/common/mathutil.h | 8 ++++---- + src/3rdparty/angle/src/common/platform.h | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h +index 372e432066..88aedddfe8 100644 +--- a/src/3rdparty/angle/src/common/mathutil.h ++++ b/src/3rdparty/angle/src/common/mathutil.h +@@ -150,7 +150,7 @@ inline bool supportsSSE2() + return supports; + } + +-#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) ++#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + { + int info[4]; + __cpuid(info, 0); +@@ -162,7 +162,7 @@ inline bool supportsSSE2() + supports = (info[3] >> 26) & 1; + } + } +-#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) ++#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + checked = true; + return supports; + #else // defined(ANGLE_USE_SSE) +@@ -884,14 +884,14 @@ inline uint32_t BitfieldReverse(uint32_t value) + + // Count the 1 bits. + #if defined(ANGLE_PLATFORM_WINDOWS) +-#if defined(_M_ARM) ++#if defined(_M_ARM) || defined(_M_ARM64) + inline int BitCount(uint32_t bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); + return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; + } +-#else // _M_ARM ++#else // _M_ARM || _M_ARM64 + inline int BitCount(uint32_t bits) + { + return static_cast(__popcnt(bits)); +diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h +index 47cd57b999..fb251da579 100644 +--- a/src/3rdparty/angle/src/common/platform.h ++++ b/src/3rdparty/angle/src/common/platform.h +@@ -83,7 +83,7 @@ + # undef far + #endif + +-#if defined(_MSC_VER) && !defined(_M_ARM) ++#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) + #include + #define ANGLE_USE_SSE + #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index aaa27dff4a..77b3ba36b0 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -94,8 +94,8 @@ ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to auto-detection implemented below. */ -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__) || defined(__ARM64__) -# if defined(__aarch64__) || defined(__ARM64__) +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) +# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) # define Q_PROCESSOR_ARM_64 # define Q_PROCESSOR_WORDSIZE 8 # else @@ -110,7 +110,8 @@ # elif defined(__ARM64_ARCH_8__) \ || defined(__aarch64__) \ || defined(__ARMv8__) \ - || defined(__ARMv8_A__) + || defined(__ARMv8_A__) \ + || defined(_M_ARM64) # define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ @@ -148,7 +149,7 @@ # else # error "ARM architecture too old" # endif -# if defined(__ARMEL__) +# if defined(__ARMEL__) || defined(_M_ARM64) # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # elif defined(__ARMEB__) # define Q_BYTE_ORDER Q_BIG_ENDIAN -- cgit v1.2.3