summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2017-07-19 23:45:18 -0700
committerJake Petroules <jake.petroules@qt.io>2017-07-21 04:58:07 +0000
commit8418a6335b3f8a029f48ee9b0a18500ddc760852 (patch)
treeb5e05638b3dff69c70bdbc48e24f4f7bf223127d /src/corelib
parent854fdaaf76873a4f5c6d5a5046b35bc8152fcc24 (diff)
Add a safety check to prevent apps from running on unsupported OSes
Although Qt declares its minimum supported OS version to the compiler and linker, the OS ignores this information when loading shared libraries, so instead of failing with a useful error message, the program will simply crash at runtime. This attempts to bring that failure as early in the lifecycle as possible, and provide a better error message as well. Change-Id: Ic58b44f8895eac718c94e62cad6e2506dbea8a7e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm30
-rw-r--r--src/corelib/kernel/qcore_mac_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp3
3 files changed, 35 insertions, 0 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 02e1232c64..ce4f01625e 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -280,6 +280,36 @@ Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
#endif // Q_OS_OSX
+void qt_apple_check_os_version()
+{
+#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+ const char *os = "iOS";
+ const int version = __IPHONE_OS_VERSION_MIN_REQUIRED;
+#elif defined(__TV_OS_VERSION_MIN_REQUIRED)
+ const char *os = "tvOS";
+ const int version = __TV_OS_VERSION_MIN_REQUIRED;
+#elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)
+ const char *os = "watchOS";
+ const int version = __WATCH_OS_VERSION_MIN_REQUIRED;
+#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+ const char *os = "macOS";
+ const int version = __MAC_OS_X_VERSION_MIN_REQUIRED;
+#endif
+ const NSOperatingSystemVersion required = version >= 100000
+ ? (NSOperatingSystemVersion){version / 10000, version / 100 % 100, version % 100}
+ : (NSOperatingSystemVersion){version / 100, version / 10 % 10, version % 10};
+ const NSOperatingSystemVersion current = NSProcessInfo.processInfo.operatingSystemVersion;
+ if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:required]) {
+ fprintf(stderr, "You can't use this version of %s with this version of %s. "
+ "You have %s %ld.%ld.%ld. Qt requires %s %ld.%ld.%ld or later.\n",
+ ((NSString *)NSBundle.mainBundle.infoDictionary[@"CFBundleName"]).UTF8String,
+ os,
+ os, current.majorVersion, current.minorVersion, current.patchVersion,
+ os, required.majorVersion, required.minorVersion, required.patchVersion);
+ abort();
+ }
+}
+
// -------------------------------------------------------------------------
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 12e9518979..5be8df1a48 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -152,6 +152,8 @@ Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
#endif
+Q_CORE_EXPORT void qt_apple_check_os_version();
+
QT_END_NAMESPACE
#endif // QCORE_MAC_P_H
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6141a73966..1f736d7bf6 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -437,6 +437,9 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
, q_ptr(0)
#endif
{
+#if defined(Q_OS_DARWIN)
+ qt_apple_check_os_version();
+#endif
app_compile_version = flags & 0xffffff;
static const char *const empty = "";
if (argc == 0 || argv == 0) {