diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-02-13 16:12:06 +0100 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-02-18 18:20:25 +0100 |
commit | d05f2fb2d567617730d7d4757fff39ddc3e903ce (patch) | |
tree | 21408f793ffee0791e156e4fe303738c87a8f3d2 /src/corelib/global/qoperatingsystemversion_darwin.mm | |
parent | fb09c82a2c7c44d41a0a36d8fe6d6d22e792668a (diff) |
Resolve actual macOS version despite process running in compatibility mode
If the application executable was built against a pre-macOS 11 SDK, macOS
will report its version as 10.16 on every OS from macOS 11 and up, for
compatibility reasons.
From Qt 6.2 and up, we require at least Xcode 12 with the macOS 11 SDK
to build Qt applications, so normally this should not be an issue, but
in the case where the Qt 'app' is a plugin library hosted by a third
party host application, the host application determines the behavior,
and we might end up in the compatibility situation after all.
However, since the Qt app was built against at least the macOS 11 SDK,
we know that it can/should handle the new version number scheme, and
we can resolve the real version number for QOperatingSystemVersion.
We do that by launching the sysctl binary with the SYSTEM_VERSION_COMPAT
environment variable set to 0, which is the supported way of disabling
the compatibility mode.
Now that we have the real version number we can use that for the
deployment target check via qt_apple_check_os_version(), but we
still need to account for possible failures in reading the plist
file.
We can also simplify the QOperatingSystemVersion::MacOSBigSur
definition, now that we always know the app the should be able
to handle major versions above 10.
Pick-to: 6.5 6.4 6.2
Task-number: QTBUG-111114
Change-Id: I2a2756381c31b195f7b8800c5008a87b37114080
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/global/qoperatingsystemversion_darwin.mm')
-rw-r--r-- | src/corelib/global/qoperatingsystemversion_darwin.mm | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/src/corelib/global/qoperatingsystemversion_darwin.mm b/src/corelib/global/qoperatingsystemversion_darwin.mm index 6581244821..99f38ea430 100644 --- a/src/corelib/global/qoperatingsystemversion_darwin.mm +++ b/src/corelib/global/qoperatingsystemversion_darwin.mm @@ -2,19 +2,56 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qoperatingsystemversion_p.h" + #import <Foundation/Foundation.h> +#include <QtCore/qfile.h> +#include <QtCore/qversionnumber.h> + +#if !defined(QT_BOOTSTRAPPED) +#include <QtCore/qprocess.h> +#endif + QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + QOperatingSystemVersionBase QOperatingSystemVersionBase::current_impl() { NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion; - QOperatingSystemVersionBase v; - v.m_os = currentType(); - v.m_major = osv.majorVersion; - v.m_minor = osv.minorVersion; - v.m_micro = osv.patchVersion; - return v; + QVersionNumber versionNumber(osv.majorVersion, osv.minorVersion, osv.patchVersion); + + if (versionNumber.majorVersion() == 10 && versionNumber.minorVersion() >= 16) { + // The process is running in system version compatibility mode, + // due to the executable being built against a pre-macOS 11 SDK. + // This might happen even if we require a more recent SDK for + // building Qt applications, as the Qt 'app' might be a plugin + // hosted inside a host that used an earlier SDK. But, since we + // require a recent SDK for the Qt app itself, the application + // should be prepared for versions numbers beyond 10, and we can + // resolve the real version number here. +#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(process) + QProcess sysctl; + QProcessEnvironment nonCompatEnvironment; + nonCompatEnvironment.insert("SYSTEM_VERSION_COMPAT", "0"); + sysctl.setProcessEnvironment(nonCompatEnvironment); + sysctl.start("/usr/sbin/sysctl"_L1, QStringList() << "-b"_L1 << "kern.osproductversion"_L1); + if (sysctl.waitForFinished()) { + auto versionString = QString::fromLatin1(sysctl.readAll()); + auto nonCompatSystemVersion = QVersionNumber::fromString(versionString); + if (!nonCompatSystemVersion.isNull()) + versionNumber = nonCompatSystemVersion; + } +#endif + } + + QOperatingSystemVersionBase operatingSystemVersion; + operatingSystemVersion.m_os = currentType(); + operatingSystemVersion.m_major = versionNumber.majorVersion(); + operatingSystemVersion.m_minor = versionNumber.minorVersion(); + operatingSystemVersion.m_micro = versionNumber.microVersion(); + + return operatingSystemVersion; } QT_END_NAMESPACE |