Add QOperatingSystemVersion support for macOS Big Sur
Pick-to: 5.15 Pick-to: 5.12 Change-Id: Ide57f675b20b08210f301da5177df45d008423c4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>bb10
parent
3e71e2e851
commit
19d32f0a5f
|
|
@ -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>
|
||||
|
||||
|
|
@ -441,6 +445,27 @@ const QOperatingSystemVersion QOperatingSystemVersion::MacOSMojave =
|
|||
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).
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -233,6 +233,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
|
||||
|
|
@ -248,6 +251,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
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <cxxabi.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
|
|
@ -540,6 +541,88 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
);
|
||||
};
|
||||
|
||||
auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64);
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@
|
|||
|
||||
#include "private/qglobal_p.h"
|
||||
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
struct mach_header;
|
||||
|
||||
#ifndef __IMAGECAPTURE__
|
||||
# define __IMAGECAPTURE__
|
||||
#endif
|
||||
|
|
@ -415,6 +418,32 @@ private:
|
|||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#if QT_POINTER_SIZE == 4
|
||||
#error "32-bit builds are not supported"
|
||||
#endif
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
//
|
||||
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtGui/qpalette.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
|
|
@ -191,34 +190,6 @@ struct backwards_t {
|
|||
template<class R>
|
||||
constexpr backwards_t<R> backwards(R&& r) { return {std::forward<R>(r)}; }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#if QT_POINTER_SIZE == 4
|
||||
#error "32-bit builds are not supported"
|
||||
#endif
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -53,9 +53,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||
|
|
@ -368,88 +365,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)
|
||||
);
|
||||
};
|
||||
|
||||
auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64);
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue