summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2023-11-28 15:04:16 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2023-11-29 16:00:57 +0100
commita29bff3d80219f54d0837b0e6e0577192011dea1 (patch)
tree504e37b115e0ec8b30ba472852eeb596309c1369
parentba9d45088f966430a814e7af36a8e7657d61e6db (diff)
CMake: Warn when configuring Qt with an unsupported Apple SDK or Xcode
The warnings are shown when configuring any Qt submodule or top-level. The warnings are NOT shown when configuring a user project with CMake. Opt out CMake cache variables can be set to silence any of the warnings: - QT_NO_APPLE_SDK_AND_XCODE_CHECK - QT_NO_APPLE_SDK_MIN_VERSION_CHECK - QT_NO_XCODE_MIN_VERSION_CHECK - QT_NO_APPLE_SDK_MAX_VERSION_CHECK The warnings can be upgraded into errors by configuring with -DQT_FORCE_FATAL_APPLE_SDK_AND_XCODE_CHECK=ON The platform version requirements that qtbase specifies in .cmake.conf are saved in Qt6ConfigExtras.cmake so that they can be used when configuring other non-qtbase submodules. The code is added to the public CMake files, so that in the future we don't need to move code around if we enable the checks for public CMake projects as well. The version extraction helpers were moved out of QtAutoDetectHelpers into QtPublicAppleHelpers. Task-number: QTBUG-119490 Change-Id: Ic840e1013aeb607bf23247a9cb43471dde802e9d Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Amir Masoud Abdol <amir.abdol@qt.io>
-rw-r--r--.cmake.conf10
-rw-r--r--cmake/QtAutoDetectHelpers.cmake41
-rw-r--r--cmake/QtBaseGlobalTargets.cmake2
-rw-r--r--cmake/QtBuildHelpers.cmake1
-rw-r--r--cmake/QtConfigExtras.cmake.in2
-rw-r--r--cmake/QtPublicAppleHelpers.cmake176
-rw-r--r--mkspecs/features/mac/default_post.prf1
7 files changed, 197 insertions, 36 deletions
diff --git a/.cmake.conf b/.cmake.conf
index 9e1d227e1c..96c28affff 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -36,3 +36,13 @@ set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_APPLE "3.21")
# in sync.
set(QT_MIN_NEW_POLICY_CMAKE_VERSION "3.16")
set(QT_MAX_NEW_POLICY_CMAKE_VERSION "3.21")
+
+# These should be updated together with the documentation in
+# qtdoc/doc/src/platforms/supported-platforms.qdocinc
+set(QT_SUPPORTED_MIN_MACOS_SDK_VERSION "13")
+set(QT_SUPPORTED_MAX_MACOS_SDK_VERSION "14")
+set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "14")
+
+set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "16")
+set(QT_SUPPORTED_MAX_IOS_SDK_VERSION "17")
+set(QT_SUPPORTED_MIN_IOS_XCODE_VERSION "14")
diff --git a/cmake/QtAutoDetectHelpers.cmake b/cmake/QtAutoDetectHelpers.cmake
index 7a56b62727..095a8d06bf 100644
--- a/cmake/QtAutoDetectHelpers.cmake
+++ b/cmake/QtAutoDetectHelpers.cmake
@@ -282,38 +282,6 @@ function(qt_auto_detect_cyclic_toolchain)
endif()
endfunction()
-function(qt_internal_get_darwin_sdk_version out_var)
- if(APPLE)
- if(CMAKE_SYSTEM_NAME STREQUAL iOS)
- set(sdk_name "iphoneos")
- else()
- # Default to macOS
- set(sdk_name "macosx")
- endif()
- set(xcrun_version_arg "--show-sdk-version")
- execute_process(COMMAND /usr/bin/xcrun --sdk ${sdk_name} ${xcrun_version_arg}
- OUTPUT_VARIABLE sdk_version
- ERROR_VARIABLE xcrun_error)
- if(NOT sdk_version)
- message(FATAL_ERROR
- "Can't determine darwin ${sdk_name} SDK version. Error: ${xcrun_error}")
- endif()
- string(STRIP "${sdk_version}" sdk_version)
- set(${out_var} "${sdk_version}" PARENT_SCOPE)
- endif()
-endfunction()
-
-function(qt_internal_get_xcode_version out_var)
- if(APPLE)
- execute_process(COMMAND /usr/bin/xcrun xcodebuild -version
- OUTPUT_VARIABLE xcode_version
- ERROR_VARIABLE xcrun_error)
- string(REPLACE "\n" " " xcode_version "${xcode_version}")
- string(STRIP "${xcode_version}" xcode_version)
- set(${out_var} "${xcode_version}" PARENT_SCOPE)
- endif()
-endfunction()
-
function(qt_auto_detect_darwin)
if(APPLE)
# If no CMAKE_OSX_DEPLOYMENT_TARGET is provided, default to a value that Qt defines.
@@ -334,11 +302,11 @@ function(qt_auto_detect_darwin)
endif()
endif()
- qt_internal_get_darwin_sdk_version(darwin_sdk_version)
- set(QT_MAC_SDK_VERSION "${darwin_sdk_version}" CACHE STRING "Darwin SDK version.")
+ _qt_internal_get_apple_sdk_version(apple_sdk_version)
+ set(QT_MAC_SDK_VERSION "${apple_sdk_version}" CACHE STRING "Darwin SDK version.")
- qt_internal_get_xcode_version(xcode_version)
- set(QT_MAC_XCODE_VERSION "${xcode_version}" CACHE STRING "Xcode version.")
+ _qt_internal_get_xcode_version_raw(xcode_version_raw)
+ set(QT_MAC_XCODE_VERSION "${xcode_version_raw}" CACHE STRING "Xcode version.")
list(LENGTH CMAKE_OSX_ARCHITECTURES arch_count)
if(NOT CMAKE_SYSTEM_NAME STREQUAL iOS AND arch_count GREATER 0)
@@ -497,6 +465,7 @@ macro(qt_internal_setup_autodetect)
# This needs to be here because QtAutoDetect loads before any other modules
option(QT_USE_VCPKG "Enable the use of vcpkg" OFF)
+ include("${CMAKE_CURRENT_LIST_DIR}/QtPublicAppleHelpers.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicWasmToolchainHelpers.cmake")
# Let CMake load our custom platform modules.
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 032f3f7b30..9a18cdd8a2 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -183,6 +183,8 @@ configure_package_config_file(
INSTALL_DESTINATION "${__GlobalConfig_install_dir}"
)
+_qt_internal_export_apple_sdk_and_xcode_version_requirements(QT_CONFIG_EXTRAS_CODE)
+
configure_file(
"${PROJECT_SOURCE_DIR}/cmake/QtConfigExtras.cmake.in"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigExtras.cmake"
diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake
index bc5854cd3c..327c0a536e 100644
--- a/cmake/QtBuildHelpers.cmake
+++ b/cmake/QtBuildHelpers.cmake
@@ -416,6 +416,7 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_setup_platform_definitions_and_mkspec()
qt_internal_check_macos_host_version()
+ _qt_internal_check_apple_sdk_and_xcode_versions()
qt_internal_check_host_path_set_for_cross_compiling()
qt_internal_setup_android_platform_specifics()
qt_internal_setup_find_host_info_package()
diff --git a/cmake/QtConfigExtras.cmake.in b/cmake/QtConfigExtras.cmake.in
index bde3460cdc..59010626ad 100644
--- a/cmake/QtConfigExtras.cmake.in
+++ b/cmake/QtConfigExtras.cmake.in
@@ -1,2 +1,4 @@
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT "@supported_min_version_for_using_qt@")
set(QT_COMPUTED_MIN_CMAKE_VERSION_FOR_USING_QT "@computed_min_version_for_using_qt@")
+
+@QT_CONFIG_EXTRAS_CODE@
diff --git a/cmake/QtPublicAppleHelpers.cmake b/cmake/QtPublicAppleHelpers.cmake
index fff797b689..d04f57c0b6 100644
--- a/cmake/QtPublicAppleHelpers.cmake
+++ b/cmake/QtPublicAppleHelpers.cmake
@@ -669,6 +669,182 @@ function(_qt_internal_set_ios_simulator_arch target)
"x86_64")
endfunction()
+# Export Apple platform sdk and xcode version requirements to Qt6ConfigExtras.cmake.
+function(_qt_internal_export_apple_sdk_and_xcode_version_requirements out_var)
+ if(NOT APPLE)
+ return()
+ endif()
+
+ if(IOS)
+ set(vars_to_assign
+ QT_SUPPORTED_MIN_IOS_SDK_VERSION
+ QT_SUPPORTED_MAX_IOS_SDK_VERSION
+ QT_SUPPORTED_MIN_IOS_XCODE_VERSION
+ )
+ else()
+ set(vars_to_assign
+ QT_SUPPORTED_MIN_MACOS_SDK_VERSION
+ QT_SUPPORTED_MAX_MACOS_SDK_VERSION
+ QT_SUPPORTED_MIN_MACOS_XCODE_VERSION
+ )
+ endif()
+
+ set(assignments "")
+ foreach(var IN LISTS vars_to_assign)
+ set(value "${${var}}")
+ list(APPEND assignments "set(${var} \"${value}\")")
+ endforeach()
+
+ list(JOIN assignments "\n" assignments)
+ set(${out_var} "${assignments}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_get_apple_sdk_version out_var)
+ if(APPLE)
+ if(CMAKE_SYSTEM_NAME STREQUAL iOS)
+ set(sdk_name "iphoneos")
+ else()
+ # Default to macOS
+ set(sdk_name "macosx")
+ endif()
+ set(xcrun_version_arg "--show-sdk-version")
+ execute_process(COMMAND /usr/bin/xcrun --sdk ${sdk_name} ${xcrun_version_arg}
+ OUTPUT_VARIABLE sdk_version
+ ERROR_VARIABLE xcrun_error)
+ if(NOT sdk_version)
+ message(FATAL_ERROR
+ "Can't determine darwin ${sdk_name} SDK version. Error: ${xcrun_error}")
+ endif()
+ string(STRIP "${sdk_version}" sdk_version)
+ set(${out_var} "${sdk_version}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_get_xcode_version_raw out_var)
+ if(APPLE)
+ execute_process(COMMAND /usr/bin/xcrun xcodebuild -version
+ OUTPUT_VARIABLE xcode_version
+ ERROR_VARIABLE xcrun_error)
+ string(REPLACE "\n" " " xcode_version "${xcode_version}")
+ string(STRIP "${xcode_version}" xcode_version)
+ set(${out_var} "${xcode_version}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_get_xcode_version out_var)
+ if(APPLE)
+ _qt_internal_get_xcode_version_raw(xcode_version_raw)
+
+ # The raw output is something like after the newlines are replaced with spaces:
+ # Xcode 14.3 Build version 14E222b
+ # We want only the '14.3' part. We could be more specific with the regex to match only
+ # digits separated by dots, but you never know how Apple might change the format.
+ string(REGEX REPLACE "Xcode (([^ ])+)" "\\2" xcode_version "${xcode_version_raw}")
+ if(xcode_version_raw MATCHES "Xcode ([^ ]+)")
+ set(xcode_version "${CMAKE_MATCH_1}")
+ else()
+ message(DEBUG "Failed to extract Xcode version from '${xcode_version_raw}'")
+ set(xcode_version "${xcode_version_raw}")
+ endif()
+
+ set(${out_var} "${xcode_version}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(_qt_internal_get_cached_apple_sdk_version out_var)
+ if(QT_INTERNAL_APPLE_SDK_VERSION)
+ set(sdk_version "${QT_INTERNAL_APPLE_SDK_VERSION}")
+ else()
+ _qt_internal_get_apple_sdk_version(sdk_version)
+ set(QT_INTERNAL_APPLE_SDK_VERSION "${sdk_version}" CACHE STRING "Apple SDK version")
+ endif()
+
+ set(${out_var} "${sdk_version}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_get_cached_xcode_version out_var)
+ if(QT_INTERNAL_XCODE_VERSION)
+ set(xcode_version "${QT_INTERNAL_XCODE_VERSION}")
+ else()
+ _qt_internal_get_xcode_version(xcode_version)
+ set(QT_INTERNAL_XCODE_VERSION "${xcode_version}" CACHE STRING "Xcode version")
+ endif()
+
+ set(${out_var} "${xcode_version}" PARENT_SCOPE)
+endfunction()
+
+# Warn when the platform SDK or Xcode version are not supported.
+#
+# The warnings are currently only shown when building Qt, not when building user projects
+# with CMake.
+# The warnings ARE shown for qmake user projects.
+#
+# The qmake equivalent for user projects is in mkspecs/features/mac/default_post.prf.
+function(_qt_internal_check_apple_sdk_and_xcode_versions)
+ if(QT_NO_APPLE_SDK_AND_XCODE_CHECK)
+ return()
+ endif()
+
+ # Only show the warnings once in a top-level build.
+ get_property(warnings_shown GLOBAL PROPERTY _qt_internal_apple_sdk_and_xcode_warnings_shown)
+ if(warnings_shown)
+ return()
+ endif()
+ set_property(GLOBAL PROPERTY _qt_internal_apple_sdk_and_xcode_warnings_shown "TRUE")
+
+ # Allow upgrading the warning into an error.
+ if(QT_FORCE_FATAL_APPLE_SDK_AND_XCODE_CHECK)
+ set(message_type FATAL_ERROR)
+ else()
+ set(message_type WARNING)
+ endif()
+
+ if(IOS)
+ set(min_sdk_version "${QT_SUPPORTED_MIN_IOS_SDK_VERSION}")
+ set(max_sdk_version "${QT_SUPPORTED_MAX_IOS_SDK_VERSION}")
+ set(min_xcode_version "${QT_SUPPORTED_MIN_IOS_XCODE_VERSION}")
+ else()
+ set(min_sdk_version "${QT_SUPPORTED_MIN_MACOS_SDK_VERSION}")
+ set(max_sdk_version "${QT_SUPPORTED_MAX_MACOS_SDK_VERSION}")
+ set(min_xcode_version "${QT_SUPPORTED_MIN_MACOS_XCODE_VERSION}")
+ endif()
+
+ _qt_internal_get_cached_apple_sdk_version(sdk_version)
+ _qt_internal_get_cached_xcode_version(xcode_version)
+
+ if(sdk_version VERSION_LESS min_sdk_version AND NOT QT_NO_APPLE_SDK_MIN_VERSION_CHECK)
+ message(${message_type}
+ "Qt requires at least version ${min_sdk_version} of the platform SDK, "
+ "you're building against version ${sdk_version}. Please upgrade."
+ )
+ endif()
+
+ if(xcode_version VERSION_LESS min_xcode_version AND NOT QT_NO_XCODE_MIN_VERSION_CHECK)
+ message(${message_type}
+ "Qt requires at least version ${min_xcode_version} of Xcode, "
+ "you're building against version ${xcode_version}. Please upgrade."
+ )
+ endif()
+
+ if(QT_NO_APPLE_SDK_MAX_VERSION_CHECK)
+ return()
+ endif()
+
+ if(sdk_version VERSION_GREATER_EQUAL max_sdk_version)
+ message(${message_type}
+ "Qt has only been tested with version ${max_sdk_version} "
+ "of the platform SDK, you're using ${sdk_version}. "
+ "This is an unsupported configuration. You may experience build issues, "
+ "and by using "
+ "the ${sdk_version} SDK you are opting in to new features "
+ "that Qt has not been prepared for. "
+ "Please downgrade the SDK you use to build your app to version "
+ "${max_sdk_version}, or configure "
+ "with -DQT_NO_APPLE_SDK_MAX_VERSION_CHECK=ON to silence this warning."
+ )
+ endif()
+endfunction()
+
function(_qt_internal_finalize_apple_app target)
# Shared between macOS and iOS apps
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index f364716717..0b64a586b9 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -17,6 +17,7 @@ contains(TEMPLATE, .*app) {
}
# Detect incompatible SDK versions
+ # The CMake equivalent is in cmake/QtPublicAppleHelpers.cmake.
isEmpty(QT_MAC_SDK_VERSION_MIN): \
QT_MAC_SDK_VERSION_MIN = $$QT_MAC_SDK_VERSION