summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2020-07-28 16:45:07 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2020-08-05 22:15:39 +0200
commit25e0e6273d9e9ba20147aa3c7479830fd12a254d (patch)
tree31788f4f97cfc926d2e5d225aa8659f203839ab4
parent512c2cf2fb9d3f2a530769540adfe84387b57f07 (diff)
Add QOperatingSystemVersion support for macOS Big Sur
Change-Id: Ide57f675b20b08210f301da5177df45d008423c4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit 19d32f0a5fc8b12e03a84ab6e18845337fd3b70f) Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp25
-rw-r--r--src/corelib/global/qoperatingsystemversion.h1
-rw-r--r--src/corelib/global/qsystemdetection.h6
-rw-r--r--src/corelib/kernel/qcore_mac.cpp88
-rw-r--r--src/corelib/kernel/qcore_mac_p.h26
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h22
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm87
7 files changed, 146 insertions, 109 deletions
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index bc6adb54dc..a0ea801ba1 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -42,6 +42,10 @@
#include "qoperatingsystemversion_p.h"
#endif
+#if defined(Q_OS_DARWIN)
+#include <QtCore/private/qcore_mac_p.h>
+#endif
+
#include <qversionnumber.h>
#include <qdebug.h>
@@ -446,6 +450,27 @@ const QOperatingSystemVersion QOperatingSystemVersion::MacOSCatalina =
QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 15);
/*!
+ \variable QOperatingSystemVersion::MacOSBigSur
+ \brief a version corresponding to macOS Big Sur
+
+ The actual version number depends on whether the application was built
+ using the Xcode 12 SDK. If it was, the version number corresponds
+ to macOS 11.0. If not it will correspond to macOS 10.16.
+
+ By comparing QOperatingSystemVersion::current() to this constant
+ you will always end up comparing to the right version number.
+ \since 6.0
+ */
+const QOperatingSystemVersion QOperatingSystemVersion::MacOSBigSur = [] {
+#if defined(Q_OS_DARWIN)
+ if (QMacVersion::buildSDK(QMacVersion::ApplicationBinary) >= QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 16))
+ return QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 11, 0);
+ else
+#endif
+ return QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 16);
+}();
+
+/*!
\variable QOperatingSystemVersion::AndroidJellyBean
\brief a version corresponding to Android Jelly Bean (version 4.1, API level 16).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index 89c60c4960..db4da1a9ae 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -72,6 +72,7 @@ public:
static const QOperatingSystemVersion MacOSHighSierra;
static const QOperatingSystemVersion MacOSMojave;
static const QOperatingSystemVersion MacOSCatalina;
+ static const QOperatingSystemVersion MacOSBigSur;
static const QOperatingSystemVersion AndroidJellyBean;
static const QOperatingSystemVersion AndroidJellyBean_MR1;
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index 3e38e6790b..d87e181e5c 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -234,6 +234,9 @@
# if !defined(__MAC_10_15)
# define __MAC_10_15 101500
# endif
+# if !defined(__MAC_10_16)
+# define __MAC_10_16 101600
+# endif
# if !defined(MAC_OS_X_VERSION_10_11)
# define MAC_OS_X_VERSION_10_11 __MAC_10_11
# endif
@@ -249,6 +252,9 @@
# if !defined(MAC_OS_X_VERSION_10_15)
# define MAC_OS_X_VERSION_10_15 __MAC_10_15
# endif
+# if !defined(MAC_OS_X_VERSION_10_16)
+# define MAC_OS_X_VERSION_10_16 __MAC_10_16
+# endif
#
# if !defined(__IPHONE_10_0)
# define __IPHONE_10_0 100000
diff --git a/src/corelib/kernel/qcore_mac.cpp b/src/corelib/kernel/qcore_mac.cpp
index b048576f5b..bef50d8d9b 100644
--- a/src/corelib/kernel/qcore_mac.cpp
+++ b/src/corelib/kernel/qcore_mac.cpp
@@ -45,6 +45,9 @@
#include "qmutex.h"
#include "qvarlengtharray.h"
+#include <dlfcn.h>
+#include <mach-o/dyld.h>
+
QT_BEGIN_NAMESPACE
QCFString::operator QString() const
@@ -159,4 +162,89 @@ os_log_t AppleUnifiedLogger::cachedLog(const QString &subsystem, const QString &
// --------------------------------------------------------------------------
+QOperatingSystemVersion QMacVersion::buildSDK(VersionTarget target)
+{
+ switch (target) {
+ case ApplicationBinary: return applicationVersion().second;
+ case QtLibraries: return libraryVersion().second;
+ }
+ Q_UNREACHABLE();
+}
+
+QOperatingSystemVersion QMacVersion::deploymentTarget(VersionTarget target)
+{
+ switch (target) {
+ case ApplicationBinary: return applicationVersion().first;
+ case QtLibraries: return libraryVersion().first;
+ }
+ Q_UNREACHABLE();
+}
+
+QOperatingSystemVersion QMacVersion::currentRuntime()
+{
+ return QOperatingSystemVersion::current();
+}
+
+QMacVersion::VersionTuple QMacVersion::versionsForImage(const mach_header *machHeader)
+{
+ static auto makeVersionTuple = [](uint32_t dt, uint32_t sdk) {
+ return qMakePair(
+ QOperatingSystemVersion(QOperatingSystemVersion::currentType(),
+ dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff),
+ QOperatingSystemVersion(QOperatingSystemVersion::currentType(),
+ sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff)
+ );
+ };
+
+ const bool is64Bit = machHeader->magic == MH_MAGIC_64 || machHeader->magic == MH_CIGAM_64;
+ auto commandCursor = uintptr_t(machHeader) + (is64Bit ? sizeof(mach_header_64) : sizeof(mach_header));
+
+ for (uint32_t i = 0; i < machHeader->ncmds; ++i) {
+ load_command *loadCommand = reinterpret_cast<load_command *>(commandCursor);
+ if (loadCommand->cmd == LC_VERSION_MIN_MACOSX || loadCommand->cmd == LC_VERSION_MIN_IPHONEOS
+ || loadCommand->cmd == LC_VERSION_MIN_TVOS || loadCommand->cmd == LC_VERSION_MIN_WATCHOS) {
+ auto versionCommand = reinterpret_cast<version_min_command *>(loadCommand);
+ return makeVersionTuple(versionCommand->version, versionCommand->sdk);
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
+ } else if (loadCommand->cmd == LC_BUILD_VERSION) {
+ auto versionCommand = reinterpret_cast<build_version_command *>(loadCommand);
+ return makeVersionTuple(versionCommand->minos, versionCommand->sdk);
+#endif
+ }
+ commandCursor += loadCommand->cmdsize;
+ }
+ Q_ASSERT_X(false, "QMacVersion", "Could not find any version load command");
+ Q_UNREACHABLE();
+}
+
+QMacVersion::VersionTuple QMacVersion::applicationVersion()
+{
+ static VersionTuple version = []() {
+ const mach_header *executableHeader = nullptr;
+ for (uint32_t i = 0; i < _dyld_image_count(); ++i) {
+ auto header = _dyld_get_image_header(i);
+ if (header->filetype == MH_EXECUTE) {
+ executableHeader = header;
+ break;
+ }
+ }
+ Q_ASSERT_X(executableHeader, "QMacVersion", "Failed to resolve Mach-O header of executable");
+ return versionsForImage(executableHeader);
+ }();
+ return version;
+}
+
+QMacVersion::VersionTuple QMacVersion::libraryVersion()
+{
+ static VersionTuple version = []() {
+ Dl_info qtCoreImage;
+ dladdr((const void *)&QMacVersion::libraryVersion, &qtCoreImage);
+ Q_ASSERT_X(qtCoreImage.dli_fbase, "QMacVersion", "Failed to resolve Mach-O header of QtCore");
+ return versionsForImage(static_cast<mach_header*>(qtCoreImage.dli_fbase));
+ }();
+ return version;
+}
+
+// -------------------------------------------------------------------------
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 168e0418e4..b78bc3207d 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -53,6 +53,9 @@
#include "private/qglobal_p.h"
+#include <QtCore/qoperatingsystemversion.h>
+struct mach_header;
+
#ifndef __IMAGECAPTURE__
# define __IMAGECAPTURE__
#endif
@@ -72,6 +75,7 @@
#include "qstring.h"
#include "qscopedpointer.h"
+#include "qpair.h"
#if defined( __OBJC__) && defined(QT_NAMESPACE)
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__) @compatibility_alias __KLASS__ QT_MANGLE_NAMESPACE(__KLASS__)
@@ -397,6 +401,28 @@ private:
// -------------------------------------------------------------------------
+class Q_CORE_EXPORT QMacVersion
+{
+public:
+ enum VersionTarget {
+ ApplicationBinary,
+ QtLibraries
+ };
+
+ static QOperatingSystemVersion buildSDK(VersionTarget target = ApplicationBinary);
+ static QOperatingSystemVersion deploymentTarget(VersionTarget target = ApplicationBinary);
+ static QOperatingSystemVersion currentRuntime();
+
+private:
+ QMacVersion() = default;
+ using VersionTuple = QPair<QOperatingSystemVersion, QOperatingSystemVersion>;
+ static VersionTuple versionsForImage(const mach_header *machHeader);
+ static VersionTuple applicationVersion();
+ static VersionTuple libraryVersion();
+};
+
+// -------------------------------------------------------------------------
+
QT_END_NAMESPACE
#endif // QCORE_MAC_P_H
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 22ea569c67..1d8461d5f2 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -178,28 +178,6 @@ T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &pro
// -------------------------------------------------------------------------
-class QMacVersion
-{
-public:
- enum VersionTarget {
- ApplicationBinary,
- QtLibraries
- };
-
- static QOperatingSystemVersion buildSDK(VersionTarget target = ApplicationBinary);
- static QOperatingSystemVersion deploymentTarget(VersionTarget target = ApplicationBinary);
- static QOperatingSystemVersion currentRuntime();
-
-private:
- QMacVersion() = default;
- using VersionTuple = QPair<QOperatingSystemVersion, QOperatingSystemVersion>;
- static VersionTuple versionsForImage(const mach_header *machHeader);
- static VersionTuple applicationVersion();
- static VersionTuple libraryVersion();
-};
-
-// -------------------------------------------------------------------------
-
QT_END_NAMESPACE
// @compatibility_alias doesn't work with protocols
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 2048bccf65..5374199360 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -55,9 +55,6 @@
#include <algorithm>
-#include <mach-o/dyld.h>
-#include <dlfcn.h>
-
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
@@ -370,90 +367,6 @@ QString qt_mac_removeAmpersandEscapes(QString s)
return QPlatformTheme::removeMnemonics(s).trimmed();
}
-// -------------------------------------------------------------------------
-
-QOperatingSystemVersion QMacVersion::buildSDK(VersionTarget target)
-{
- switch (target) {
- case ApplicationBinary: return applicationVersion().second;
- case QtLibraries: return libraryVersion().second;
- }
- Q_UNREACHABLE();
-}
-
-QOperatingSystemVersion QMacVersion::deploymentTarget(VersionTarget target)
-{
- switch (target) {
- case ApplicationBinary: return applicationVersion().first;
- case QtLibraries: return libraryVersion().first;
- }
- Q_UNREACHABLE();
-}
-
-QOperatingSystemVersion QMacVersion::currentRuntime()
-{
- return QOperatingSystemVersion::current();
-}
-
-QMacVersion::VersionTuple QMacVersion::versionsForImage(const mach_header *machHeader)
-{
- static auto makeVersionTuple = [](uint32_t dt, uint32_t sdk) {
- return qMakePair(
- QOperatingSystemVersion(QOperatingSystemVersion::MacOS,
- dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff),
- QOperatingSystemVersion(QOperatingSystemVersion::MacOS,
- sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff)
- );
- };
-
- const bool is64Bit = machHeader->magic == MH_MAGIC_64 || machHeader->magic == MH_CIGAM_64;
- auto commandCursor = uintptr_t(machHeader) + (is64Bit ? sizeof(mach_header_64) : sizeof(mach_header));
-
- for (uint32_t i = 0; i < machHeader->ncmds; ++i) {
- load_command *loadCommand = reinterpret_cast<load_command *>(commandCursor);
- if (loadCommand->cmd == LC_VERSION_MIN_MACOSX) {
- auto versionCommand = reinterpret_cast<version_min_command *>(loadCommand);
- return makeVersionTuple(versionCommand->version, versionCommand->sdk);
-#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13)
- } else if (loadCommand->cmd == LC_BUILD_VERSION) {
- auto versionCommand = reinterpret_cast<build_version_command *>(loadCommand);
- return makeVersionTuple(versionCommand->minos, versionCommand->sdk);
-#endif
- }
- commandCursor += loadCommand->cmdsize;
- }
- Q_ASSERT_X(false, "QCocoaIntegration", "Could not find any version load command");
- Q_UNREACHABLE();
-}
-
-QMacVersion::VersionTuple QMacVersion::applicationVersion()
-{
- static VersionTuple version = []() {
- const mach_header *executableHeader = nullptr;
- for (uint32_t i = 0; i < _dyld_image_count(); ++i) {
- auto header = _dyld_get_image_header(i);
- if (header->filetype == MH_EXECUTE) {
- executableHeader = header;
- break;
- }
- }
- Q_ASSERT_X(executableHeader, "QCocoaIntegration", "Failed to resolve Mach-O header of executable");
- return versionsForImage(executableHeader);
- }();
- return version;
-}
-
-QMacVersion::VersionTuple QMacVersion::libraryVersion()
-{
- static VersionTuple version = []() {
- Dl_info cocoaPluginImage;
- dladdr((const void *)&QMacVersion::libraryVersion, &cocoaPluginImage);
- Q_ASSERT_X(cocoaPluginImage.dli_fbase, "QCocoaIntegration", "Failed to resolve Mach-O header of Cocoa plugin");
- return versionsForImage(static_cast<mach_header*>(cocoaPluginImage.dli_fbase));
- }();
- return version;
-}
-
QT_END_NAMESPACE
/*! \internal