summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-04-08 17:23:57 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-12-03 13:35:59 +0000
commit55a15a1c1b93d36d705fc69e44b5c806b807dd55 (patch)
tree5b98c29c723bda2f298a394ee46e63f3c23ec74f
parentc800a6240353eb54bd7a2ad06c455ac9374c2476 (diff)
Add initial support for cross-building to iOS
Tested locally with the following configurations: - iOS device builds (arm64) - iOS simulator builds (x86_64) - iOS simulator_and_device builds (fat arm64 and x86_64 archives) All iOS builds currently require a custom vcpkg fork which contains fixes for building the required 3rd party libraries. qtsvg, qtdeclarative, qtgraphicaleffects and qtquickcontrols2 have also been tested to build successfully. simulator_and_device builds are also supported, but require an umerged patch in upstream CMake as well as further patches to vcpkg. Task-number: QTBUG-75576 Change-Id: Icd29913fbbd52a60e07ea5253fd9c7af7f8ce44c Reviewed-by: Cristian Adam <cristian.adam@qt.io> Reviewed-by: Qt CMake Build Bot Reviewed-by: Leander Beernaert <leander.beernaert@qt.io>
-rw-r--r--cmake/FindGLESv2.cmake27
-rw-r--r--cmake/QtAutoDetect.cmake97
-rw-r--r--cmake/QtBaseConfigureTests.cmake43
-rw-r--r--cmake/QtBaseGlobalTargets.cmake31
-rw-r--r--cmake/QtBuild.cmake8
-rw-r--r--cmake/QtCompilerOptimization.cmake4
-rw-r--r--cmake/QtFeature.cmake61
-rw-r--r--cmake/QtInternalTargets.cmake12
-rw-r--r--cmake/QtPlatformSupport.cmake10
-rw-r--r--cmake/QtSetup.cmake15
-rw-r--r--cmake/README.md53
-rw-r--r--config.tests/arch/CMakeLists.txt6
-rw-r--r--configure.cmake2
-rw-r--r--src/gui/CMakeLists.txt10
-rw-r--r--src/plugins/platforms/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/ios/.prev_CMakeLists.txt81
-rw-r--r--src/plugins/platforms/ios/CMakeLists.txt72
-rw-r--r--src/plugins/platforms/ios/optional/CMakeLists.txt6
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/CMakeLists.txt30
-rw-r--r--tests/auto/CMakeLists.txt15
-rw-r--r--tests/manual/CMakeLists.txt7
-rwxr-xr-xutil/cmake/configurejson2cmake.py1
22 files changed, 558 insertions, 35 deletions
diff --git a/cmake/FindGLESv2.cmake b/cmake/FindGLESv2.cmake
index 02df910285..49e757ef55 100644
--- a/cmake/FindGLESv2.cmake
+++ b/cmake/FindGLESv2.cmake
@@ -5,8 +5,8 @@ include(CheckCXXSourceCompiles)
if(EMSCRIPTEN)
set(HAVE_GLESv2 ON)
else()
- find_library(GLESv2_LIBRARY NAMES GLESv2)
- find_path(GLESv2_INCLUDE_DIR NAMES "GLES2/gl2.h" DOC "The OpenGLES 2 include path")
+ find_library(GLESv2_LIBRARY NAMES GLESv2 OpenGLES)
+ find_path(GLESv2_INCLUDE_DIR NAMES "GLES2/gl2.h" "OpenGLES/ES2/gl.h" DOC "The OpenGLES 2 include path")
set(_libraries "${CMAKE_REQUIRED_LIBRARIES}")
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GLESv2_LIBRARY}")
set(_includes "${CMAKE_REQUIRED_INCLUDES}")
@@ -32,6 +32,20 @@ int main(int argc, char *argv[]) {
set(package_args GLESv2_INCLUDE_DIR GLESv2_LIBRARY HAVE_GLESv2)
endif()
+# Framework handling partially inspired by FindGLUT.cmake.
+if(GLESv2_LIBRARY MATCHES "/([^/]+)\\.framework$")
+ # TODO: Might need to handle non .tbd suffixes, but didn't find an
+ # example like that.
+ # TODO: Might need to handle INTERFACE_INCLUDE_DIRECTORIES differently.
+ set(_library_imported_location "${GLESv2_LIBRARY}/${CMAKE_MATCH_1}.tbd")
+ if(NOT EXISTS "${_library_imported_location}")
+ set(_library_imported_location "")
+ endif()
+else()
+ set(_library_imported_location "${GLESv2_LIBRARY}")
+endif()
+set(GLESv2_LIBRARY "${_library_imported_location}")
+
list(APPEND package_args HAVE_GLESv2)
include(FindPackageHandleStandardArgs)
@@ -40,8 +54,15 @@ find_package_handle_standard_args(GLESv2 DEFAULT_MSG ${package_args})
mark_as_advanced(${package_args})
if(GLESv2_FOUND AND NOT TARGET GLESv2::GLESv2)
- if(EMSCRIPTEN)
+ if(EMSCRIPTEN OR APPLE_UIKIT)
add_library(GLESv2::GLESv2 INTERFACE IMPORTED)
+ if(APPLE_UIKIT)
+ # For simulator_and_device builds we can't specify the full library path, because
+ # it's specific to either the device or the simulator. Resort to passing a link
+ # flag instead.
+ set_target_properties(GLESv2::GLESv2 PROPERTIES
+ INTERFACE_LINK_LIBRARIES "-framework OpenGLES")
+ endif()
else()
add_library(GLESv2::GLESv2 UNKNOWN IMPORTED)
set_target_properties(GLESv2::GLESv2 PROPERTIES
diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake
index 7864d40501..1823d1e572 100644
--- a/cmake/QtAutoDetect.cmake
+++ b/cmake/QtAutoDetect.cmake
@@ -59,6 +59,103 @@ function(qt_auto_detect_vpckg)
endif()
endfunction()
+function(qt_auto_detect_ios)
+ if(CMAKE_SYSTEM_NAME STREQUAL iOS
+ OR CMAKE_SYSTEM_NAME STREQUAL watchOS
+ OR CMAKE_SYSTEM_NAME STREQUAL tvOS)
+ message(STATUS "Using internal CMake ${CMAKE_SYSTEM_NAME} toolchain file.")
+ # The QT_UIKIT_SDK check simulates the input.sdk condition for simulator_and_device in
+ # configure.json.
+ # If the variable is explicitly provided, assume simulator_and_device to be off.
+ if(QT_UIKIT_SDK)
+ set(simulator_and_device OFF)
+ elseif(QT_FORCE_SIMULATOR_AND_DEVICE)
+ # TODO: Once we get simulator_and_device support in upstream CMake, only then allow
+ # usage of simulator_and_device without forcing.
+ set(simulator_and_device ON)
+ else()
+ # If QT_UIKIT_SDK is not provided, default to simulator.
+ set(simulator_and_device OFF)
+ set(QT_UIKIT_SDK "iphonesimulator" CACHE "STRING" "Chosen uikit SDK.")
+ endif()
+
+ message(STATUS "simulator_and_device set to: \"${simulator_and_device}\".")
+
+ # Choose relevant architectures.
+ # Using a non xcode generator requires explicit setting of the
+ # architectures, otherwise compilation fails with unknown defines.
+ if(CMAKE_SYSTEM_NAME STREQUAL iOS)
+ if(simulator_and_device)
+ set(osx_architectures "arm64;x86_64")
+ elseif(QT_UIKIT_SDK STREQUAL "iphoneos")
+ set(osx_architectures "arm64")
+ elseif(QT_UIKIT_SDK STREQUAL "iphonesimulator")
+ set(osx_architectures "x86_64")
+ else()
+ if(NOT DEFINED QT_UIKIT_SDK)
+ message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
+ " Possible values: iphoneos, iphonesimulator.")
+ else()
+ message(FATAL_ERROR
+ "Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
+ endif()
+ endif()
+ elseif(CMAKE_SYSTEM_NAME STREQUAL tvOS)
+ if(simulator_and_device)
+ set(osx_architectures "arm64;x86_64")
+ elseif(QT_UIKIT_SDK STREQUAL "appletvos")
+ set(osx_architectures "arm64")
+ elseif(QT_UIKIT_SDK STREQUAL "appletvsimulator")
+ set(osx_architectures "x86_64")
+ else()
+ if(NOT DEFINED QT_UIKIT_SDK)
+ message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
+ " Possible values: appletvos, appletvsimulator.")
+ else()
+ message(FATAL_ERROR
+ "Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
+ endif()
+ endif()
+ elseif(CMAKE_SYSTEM_NAME STREQUAL watchOS)
+ if(simulator_and_device)
+ set(osx_architectures "armv7k;i386")
+ elseif(QT_UIKIT_SDK STREQUAL "watchos")
+ set(osx_architectures "armv7k")
+ elseif(QT_UIKIT_SDK STREQUAL "watchsimulator")
+ set(osx_architectures "i386")
+ else()
+ if(NOT DEFINED QT_UIKIT_SDK)
+ message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
+ " Possible values: watchos, watchsimulator.")
+ else()
+ message(FATAL_ERROR
+ "Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
+ endif()
+ endif()
+ endif()
+
+ # For non simulator_and_device builds, we need to explicitly set the SYSROOT aka the sdk
+ # value.
+ if(QT_UIKIT_SDK)
+ set(CMAKE_OSX_SYSROOT "${QT_UIKIT_SDK}" CACHE STRING "")
+ endif()
+ message(STATUS "CMAKE_OSX_SYSROOT set to: \"${CMAKE_OSX_SYSROOT}\".")
+
+ message(STATUS "CMAKE_OSX_ARCHITECTURES set to: \"${osx_architectures}\".")
+ set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "")
+
+ if(NOT DEFINED BUILD_SHARED_LIBS)
+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Qt statically or dynamically" FORCE)
+ endif()
+
+ if(BUILD_SHARED_LIBS)
+ message(FATAL_ERROR
+ "Building Qt for ${CMAKE_SYSTEM_NAME} as shared libraries is not supported.")
+ endif()
+ endif()
+endfunction()
+
+qt_auto_detect_ios()
qt_auto_detect_android()
qt_auto_detect_vpckg()
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index 6b46ed26b2..777adb7b5f 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -1,27 +1,41 @@
include(CheckCXXSourceCompiles)
+
function(qt_run_config_test_architecture)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT
"" CACHE INTERNAL "Test variables that should be exported" FORCE)
- # Test architecture
- set(_arch_file "${CMAKE_CURRENT_BINARY_DIR}/architecture_test")
- set(saved_executable_suffix "${CMAKE_EXECUTABLE_SUFFIX}")
- # With emscripten the application entry point is a .js file (to be run with node for example), but the
- # real "data" is in the .wasm file, so that's where we need to look for the ABI, etc. information.
- if (EMSCRIPTEN)
- set(CMAKE_EXECUTABLE_SUFFIX ".wasm")
- endif()
+ # Compile test to find the target architecture and sub-architectures.
+ set(flags "")
+ qt_get_platform_try_compile_vars(platform_try_compile_vars)
+ list(APPEND flags ${platform_try_compile_vars})
- try_compile(_arch_result "${CMAKE_CURRENT_BINARY_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/arch/arch.cpp"
- COPY_FILE "${_arch_file}")
-
- set(CMAKE_EXECUTABLE_SUFFIX "${saved_executable_suffix}")
+ try_compile(
+ _arch_result
+ "${CMAKE_CURRENT_BINARY_DIR}/config.tests/arch"
+ "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/arch"
+ arch
+ CMAKE_FLAGS ${flags}
+ )
if (NOT _arch_result)
message(FATAL_ERROR "Failed to compile architecture detection file.")
endif()
+ set(_arch_file_suffix "${CMAKE_EXECUTABLE_SUFFIX}")
+ # With emscripten the application entry point is a .js file (to be run with node for example),
+ # but the real "data" is in the .wasm file, so that's where we need to look for the ABI, etc.
+ # information.
+ if (EMSCRIPTEN)
+ set(_arch_file_suffix ".wasm")
+ endif()
+ set(_arch_file
+ "${CMAKE_CURRENT_BINARY_DIR}/config.tests/arch/architecture_test${_arch_file_suffix}")
+ if (NOT EXISTS "${_arch_file}")
+ message(FATAL_ERROR
+ "Failed to find compiled architecture detection executable at ${_arch_file}.")
+ endif()
+ message(STATUS "Extracting architecture info from ${_arch_file}.")
+
file(STRINGS "${_arch_file}" _arch_lines LENGTH_MINIMUM 16 LENGTH_MAXIMUM 1024 ENCODING UTF-8)
foreach (_line ${_arch_lines})
@@ -60,6 +74,9 @@ function(qt_run_config_test_architecture)
set(TEST_buildAbi "${_build_abi}" CACHE INTERNAL "Target machine buildAbi")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_buildAbi)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT} CACHE INTERNAL "Test variables that should be exported")
+
+ list(JOIN _sub_architecture " " subarch_summary)
+ message(STATUS "Building for: ${QT_QMAKE_TARGET_MKSPEC} (${TEST_architecture_arch}, CPU features: ${subarch_summary})")
endfunction()
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 66ec2c73e4..ad15207005 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -91,11 +91,27 @@ list(APPEND init_platform "set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACH
list(APPEND init_platform "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE STRING \"\")")
if(APPLE)
- if(CMAKE_OSX_SYSROOT)
+ # For simulator_and_device build, we should not explicitly set the sysroot.
+ list(LENGTH CMAKE_OSX_ARCHITECTURES _qt_osx_architectures_count)
+ if(CMAKE_OSX_SYSROOT AND NOT _qt_osx_architectures_count GREATER 1 AND APPLE_UIKIT)
list(APPEND init_platform "set(CMAKE_OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\" CACHE PATH \"\")")
endif()
+ unset(_qt_osx_architectures_count)
+
if(CMAKE_OSX_DEPLOYMENT_TARGET)
- list(APPEND init_platform "set(CMAKE_OSX_DEPLOYMENT_TARGET \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" CACHE STRING \"\")")
+ list(APPEND init_platform
+ "set(CMAKE_OSX_DEPLOYMENT_TARGET \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" CACHE STRING \"\")")
+ endif()
+
+ if(APPLE_UIKIT)
+ list(APPEND init_platform
+ "set(CMAKE_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\" CACHE STRING \"\")")
+ set(_qt_osx_architectures_escaped "${CMAKE_OSX_ARCHITECTURES}")
+ string(REPLACE ";" "LITERAL_SEMICOLON"
+ _qt_osx_architectures_escaped "${_qt_osx_architectures_escaped}")
+ list(APPEND init_platform
+ "set(CMAKE_OSX_ARCHITECTURES \"${_qt_osx_architectures_escaped}\" CACHE STRING \"\")")
+ unset(_qt_osx_architectures_escaped)
endif()
elseif(ANDROID)
list(APPEND init_platform "set(ANDROID_NATIVE_API_LEVEL \"${ANDROID_NATIVE_API_LEVEL}\" CACHE STRING \"\")")
@@ -108,6 +124,7 @@ endif()
string(REPLACE ";" "\n" init_vcpkg "${init_vcpkg}")
string(REPLACE ";" "\n" init_platform "${init_platform}")
+string(REPLACE "LITERAL_SEMICOLON" ";" init_platform "${init_platform}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt.toolchain.cmake.in" "${__GlobalConfig_build_dir}/qt.toolchain.cmake" @ONLY)
qt_install(FILES "${__GlobalConfig_build_dir}/qt.toolchain.cmake" DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel)
@@ -135,6 +152,16 @@ qt_feature_module_begin(NO_MODULE
PRIVATE_FILE src/corelib/global/qconfig_p.h
)
include("${CMAKE_CURRENT_SOURCE_DIR}/configure.cmake")
+
+# Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for
+# simulator_and_device_builds.
+if(APPLE_UIKIT AND NOT QT_UIKIT_SDK)
+ set(__QtFeature_custom_enabled_cache_variables
+ TEST_subarch_sse2
+ FEATURE_sse2
+ QT_FEATURE_sse2)
+endif()
+
qt_feature_module_end(GlobalConfig OUT_VAR_PREFIX "__GlobalConfig_")
qt_generate_global_config_pri_file()
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake
index 13e954cd57..a1b044b97d 100644
--- a/cmake/QtBuild.cmake
+++ b/cmake/QtBuild.cmake
@@ -1895,6 +1895,8 @@ function(qt_add_plugin target)
"${ARGN}"
)
+ qt_get_sanitized_plugin_type("${arg_TYPE}" arg_TYPE)
+
set(output_directory_default "${QT_BUILD_DIR}/${INSTALL_PLUGINSDIR}/${arg_TYPE}")
set(install_directory_default "${INSTALL_PLUGINSDIR}/${arg_TYPE}")
set(archive_install_directory_default "${INSTALL_LIBDIR}/${arg_TYPE}")
@@ -2760,7 +2762,7 @@ function(qt_add_cmake_library target)
### Define Targets:
if(${arg_INTERFACE})
add_library("${target}" INTERFACE)
- elseif(${arg_STATIC})
+ elseif(${arg_STATIC} OR (${arg_MODULE} AND NOT BUILD_SHARED_LIBS))
add_library("${target}" STATIC)
elseif(${arg_SHARED})
add_library("${target}" SHARED)
@@ -3376,10 +3378,14 @@ endfunction()
macro(qt_find_apple_system_frameworks)
if(APPLE)
find_library(FWAppKit AppKit)
+ find_library(FWAssetsLibrary AssetsLibrary)
+ find_library(FWAudioToolbox AudioToolbox)
find_library(FWApplicationServices ApplicationServices)
find_library(FWCarbon Carbon)
find_library(FWCoreFoundation CoreFoundation)
find_library(FWCoreServices CoreServices)
+ find_library(FWCoreGraphics CoreGraphics)
+ find_library(FWCoreText CoreText)
find_library(FWCoreVideo CoreVideo)
find_library(FWcups cups)
find_library(FWDiskArbitration DiskArbitration)
diff --git a/cmake/QtCompilerOptimization.cmake b/cmake/QtCompilerOptimization.cmake
index 5ca28c4de4..f1ebafc009 100644
--- a/cmake/QtCompilerOptimization.cmake
+++ b/cmake/QtCompilerOptimization.cmake
@@ -62,7 +62,9 @@ if(GCC OR CLANG)
set(QT_CFLAGS_AVX512VBMI "-mavx512vbmi")
set(QT_CFLAGS_AESNI "-maes")
set(QT_CFLAGS_SHANI "-msha")
- set(QT_CFLAGS_NEON "-mfpu=neon")
+ if(NOT APPLE_UIKIT)
+ set(QT_CFLAGS_NEON "-mfpu=neon")
+ endif()
set(QT_CFLAGS_MIPS_DSP "-mdsp")
set(QT_CFLAGS_MIPS_DSPR2 "-mdspr2")
endif()
diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake
index 9849390922..b3e5eb9b8a 100644
--- a/cmake/QtFeature.cmake
+++ b/cmake/QtFeature.cmake
@@ -360,6 +360,14 @@ function(qt_feature_module_end)
qt_evaluate_feature(${feature})
endforeach()
+ # Evaluate custom cache assignments.
+ foreach(cache_var_name ${__QtFeature_custom_enabled_cache_variables})
+ set(${cache_var_name} ON CACHE BOOL "Force enabled by platform." FORCE)
+ endforeach()
+ foreach(cache_var_name ${__QtFeature_custom_disabled_cache_variables})
+ set(${cache_var_name} OFF CACHE BOOL "Force disabled by platform." FORCE)
+ endforeach()
+
set(enabled_public_features "")
set(disabled_public_features "")
set(enabled_private_features "")
@@ -445,6 +453,8 @@ function(qt_feature_module_end)
unset(__QtFeature_public_extra PARENT_SCOPE)
unset(__QtFeature_define_definitions PARENT_SCOPE)
+ unset(__QtFeature_custom_enabled_features PARENT_SCOPE)
+ unset(__QtFeature_custom_disabled_features PARENT_SCOPE)
endfunction()
function(qt_feature_copy_global_config_features_to_core target)
@@ -527,18 +537,65 @@ function(qt_config_compile_test name)
set(TEST_${name} "${HAVE_${name}}" CACHE INTERNAL "${arg_LABEL}")
endfunction()
+# This function should be used for passing required try compile platform variables to the
+# project-based try_compile() call.
+# out_var will be a list of -Dfoo=bar strings, suitable to pass to CMAKE_FLAGS.
+function(qt_get_platform_try_compile_vars out_var)
+ # Use the regular variables that are used for source-based try_compile() calls.
+ set(flags "${CMAKE_TRY_COMPILE_PLATFORM_VARIABLES}")
+
+ # Pass toolchain files.
+ if(CMAKE_TOOLCHAIN_FILE)
+ list(APPEND flags "CMAKE_TOOLCHAIN_FILE")
+ endif()
+ if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
+ list(APPEND flags "VCPKG_CHAINLOAD_TOOLCHAIN_FILE")
+ endif()
+
+ # Assemble the list with regular options.
+ set(flags_cmd_line "")
+ foreach(flag ${flags})
+ if(${flag})
+ list(APPEND flags_cmd_line "-D${flag}=${${flag}}")
+ endif()
+ endforeach()
+
+ # Pass darwin specific options.
+ if(APPLE_UIKIT)
+ if(CMAKE_OSX_ARCHITECTURES)
+ list(GET CMAKE_OSX_ARCHITECTURES 0 osx_first_arch)
+
+ # Do what qmake does, aka when doing a simulator_and_device build, build the
+ # target architecture test only with the first given architecture, which should be the
+ # device architecture, aka some variation of "arm" (armv7, arm64).
+ list(APPEND flags_cmd_line "-DCMAKE_OSX_ARCHITECTURES:STRING=${osx_first_arch}")
+ endif()
+ # Also specify the sysroot, but only if not doing a simulator_and_device build.
+ # So keep the sysroot empty for simulator_and_device builds.
+ if(QT_UIKIT_SDK)
+ list(APPEND flags_cmd_line "-DCMAKE_OSX_SYSROOT:STRING=${QT_UIKIT_SDK}")
+ endif()
+ endif()
+
+ set("${out_var}" "${flags_cmd_line}" PARENT_SCOPE)
+endfunction()
+
function(qt_config_compile_test_x86simd extension label)
if (DEFINED TEST_X86SIMD_${extension})
return()
endif()
+ set(flags "-DSIMD:string=${extension}")
+
+ qt_get_platform_try_compile_vars(platform_try_compile_vars)
+ list(APPEND flags ${platform_try_compile_vars})
+
message(STATUS "Performing SIMD Test ${label}")
try_compile("TEST_X86SIMD_${extension}"
"${CMAKE_CURRENT_BINARY_DIR}/config.tests/x86_simd_${extension}"
"${CMAKE_CURRENT_SOURCE_DIR}/config.tests/x86_simd"
x86_simd
- CMAKE_FLAGS "-DSIMD:string=${extension}")
-
+ CMAKE_FLAGS ${flags})
if(${TEST_X86SIMD_${extension}})
set(status_label "Success")
else()
diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake
index 2db065fbf5..54e7f4f50e 100644
--- a/cmake/QtInternalTargets.cmake
+++ b/cmake/QtInternalTargets.cmake
@@ -100,3 +100,15 @@ endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
target_compile_definitions(PlatformCommonInternal INTERFACE QT_NO_DEBUG)
endif()
+
+if(APPLE_UIKIT)
+ # Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for
+ # simulator_and_device_builds.
+ if(FEATURE_simulator_and_device)
+ # Setting the definition on PlatformCommonInternal behaves slightly differently from what
+ # is done in qmake land. This way the define is not propagated to tests, examples, or
+ # user projects built with qmake, but only modules, plugins and tools.
+ # TODO: Figure out if this ok or not (sounds ok to me).
+ target_compile_definitions(PlatformCommonInternal INTERFACE QT_COMPILER_SUPPORTS_SSE2)
+ endif()
+endif()
diff --git a/cmake/QtPlatformSupport.cmake b/cmake/QtPlatformSupport.cmake
index ac8e8f6ad2..b54d52eba4 100644
--- a/cmake/QtPlatformSupport.cmake
+++ b/cmake/QtPlatformSupport.cmake
@@ -22,11 +22,11 @@ qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
qt_set01(WINRT WIN32 AND CMAKE_VS_PLATFORM_TOOSLET STREQUAL "winrt") # FIXME: How to identify this?
-qt_set01(APPLE_OSX APPLE) # FIXME: How to identify this? For now assume that always building for macOS.
-qt_set01(APPLE_UIKIT APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "uikit") # FIXME: How to identify this?
-qt_set01(APPLE_IOS APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "ios") # FIXME: How to identify this?
-qt_set01(APPLE_TVOS APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "tvos") # FIXME: How to identify this?
-qt_set01(APPLE_WATCHOS APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "watchos") # FIXME: How to identify this?
+qt_set01(APPLE_IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
+qt_set01(APPLE_TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS")
+qt_set01(APPLE_WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS")
+qt_set01(APPLE_UIKIT APPLE AND (APPLE_IOS OR APPLE_TVOS OR APPLE_WATCHOS))
+qt_set01(APPLE_OSX APPLE AND NOT APPLE_UIKIT)
qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
qt_set01(CLANG CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake
index 1f209e8076..65bd5b9a21 100644
--- a/cmake/QtSetup.cmake
+++ b/cmake/QtSetup.cmake
@@ -75,6 +75,12 @@ if(FEATURE_developer_build)
set(QT_BUILD_TESTING ON)
set(__build_benchmarks ON)
+ # Tests are not built by default with qmake for iOS and friends, and thus the overall build
+ # tends to fail. Disable them by default when targeting uikit.
+ if(APPLE_UIKIT)
+ set(QT_BUILD_TESTING OFF)
+ endif()
+
# Disable benchmarks for single configuration generators which do not build
# with release configuration.
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL Release)
@@ -104,7 +110,14 @@ include(CTest)
enable_testing()
# Set up building of examples.
-option(BUILD_EXAMPLES "Build Qt examples" ON)
+set(QT_BUILD_EXAMPLES ON)
+# Examples are not built by default with qmake for iOS and friends, and thus the overall build
+# tends to fail. Disable them by default when targeting uikit.
+if(APPLE_UIKIT)
+ set(QT_BUILD_EXAMPLES OFF)
+endif()
+
+option(BUILD_EXAMPLES "Build Qt examples" ${QT_BUILD_EXAMPLES})
option(QT_NO_MAKE_EXAMPLES "Should examples be built as part of the default 'all' target." OFF)
# Build Benchmarks
diff --git a/cmake/README.md b/cmake/README.md
index 5739b900f7..6c27bc9300 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -201,7 +201,7 @@ When running cmake in qtbase, pass
``-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DQT_HOST_PATH=/path/to/your/host/build -DANDROID_SDK_ROOT=$ANDROID_SDK_HOME -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH``
If you don't supply the configuration argument ``-DANDROID_ABI=...``, it will default to
-``armeabi-v7a``. To target other architectures, use on of the following values:
+``armeabi-v7a``. To target other architectures, use one of the following values:
* arm64: ``-DANDROID_ABI=arm64-v8``
* x86: ``-DANDROID_ABI=x86``
* x86_64: ``-DANDROID_ABI=x86_64``
@@ -209,6 +209,57 @@ If you don't supply the configuration argument ``-DANDROID_ABI=...``, it will de
By default we set the android API level to 21. Should you need to change this supply the following
configuration argument to the above CMake call: ``-DANDROID_NATIVE_API_LEVEL=${API_LEVEL}``
+### Cross compiling for iOS
+
+In order to cross-compile Qt to iOS, you need a host macOS build.
+In addition, it is necessary to install a custom version of vcpkg. Vcpkg is
+needed to supply third-party libraries that Qt requires, but that are not part of the iOS SDK.
+
+Vcpkg for iOS can be set up using the following steps:
+
+ * ```git clone -b qt https://github.com/alcroito/vcpkg```
+ * Run ```bootstrap-vcpkg.sh```
+ * Set the ``VCPKG_DEFAULT_TRIPLET`` environment variable to one of the following values:
+ * ``x64-ios`` (simulator x86_64)
+ * ``x86-ios`` (simulator i386)
+ * ``arm64-ios`` (device arm64)
+ * ``arm-ios`` (device armv7)
+ * ``fat-ios`` (simulator_and_device x86_64 and arm64* - special considedrations)
+ * Set the ``VCPKG_ROOT`` environment variable to the path where you cloned vcpkg
+ * Build Qt dependencies: ``vcpkg install @qt-packages-ios.txt``
+
+When running cmake in qtbase, pass
+``-DCMAKE_SYSTEM_NAME=iOS -DQT_HOST_PATH=/path/to/your/host/build -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH``
+
+If you don't supply the configuration argument ``-DQT_UIKIT_SDK=...``, it will default to
+``iphonesimulator``. To target another SDK / device type, use one of the following values:
+ * iphonesimulator: ``-DQT_UIKIT_SDK=iphonesimulator``
+ * iphoneos: ``-DQT_UIKIT_SDK=iphoneos``
+ * simulator_and_device: ``-DQT_FORCE_SIMULATOR_AND_DEVICE=ON -DQT_UIKIT_SDK=``
+
+Depending on what value you pass to ``-DQT_UIKIT_SDK=`` a list of target architectures is chosen
+by default:
+ * iphonesimulator: ``x86_64``
+ * iphoneos: ``arm64``
+ * simulator_and_device: ``arm64;x86_64``
+
+You can try choosing a different list of architectures by passing
+``-DCMAKE_OSX_ARCHITECTURES=x86_64;i386``.
+Note that if you choose different architectures compared to the default ones, the build might fail.
+Only do it if you know what you are doing.
+
+#### simulator_and_device special considerations
+To do a simulator_and_device build, a custom version of CMake is required in addition to the vcpkg
+fork. The merge request can be found here:
+https://gitlab.kitware.com/cmake/cmake/merge_requests/3617
+
+After you build your own copy of CMake using this merge request, you need to use it for both
+vcpkg and Qt.
+
+Note that vcpkg prefers its own version of CMake when building packages.
+Make sure to put your custom built CMake in PATH, and force vcpkg to use this CMake by running
+``export VCPKG_FORCE_SYSTEM_BINARIES=1`` in your shell.
+
# Debugging CMake files
CMake allows specifying the ``--trace`` and ``--trace-expand`` options, which work like
diff --git a/config.tests/arch/CMakeLists.txt b/config.tests/arch/CMakeLists.txt
new file mode 100644
index 0000000000..c0873a984f
--- /dev/null
+++ b/config.tests/arch/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.15.0)
+project(arch LANGUAGES CXX)
+
+add_executable(architecture_test)
+set_property(TARGET architecture_test PROPERTY MACOSX_BUNDLE FALSE)
+target_sources(architecture_test PRIVATE arch.cpp)
diff --git a/configure.cmake b/configure.cmake
index 8ac9749663..4118f57f22 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -333,7 +333,7 @@ qt_feature("appstore_compliant" PUBLIC
)
qt_feature("simulator_and_device" PUBLIC
LABEL "Build for both simulator and device"
- CONDITION APPLE_UIKIT AND INPUT_sdk STREQUAL ''
+ CONDITION APPLE_UIKIT AND NOT QT_UIKIT_SDK
)
qt_feature("force_asserts" PUBLIC
LABEL "Force assertions"
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index f081979aff..9f146721c0 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -594,6 +594,16 @@ qt_extend_target(Gui CONDITION QT_FEATURE_harfbuzz
WrapHarfbuzz::WrapHarfbuzz
)
+# special case begin
+# Replicate what src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro does, which is link CoreText
+# when targeting uikit.
+
+qt_extend_target(Gui CONDITION QT_FEATURE_harfbuzz AND APPLE_UIKIT
+ LIBRARIES
+ ${FWCoreText}
+)
+# special case end
+
qt_extend_target(Gui CONDITION QT_FEATURE_textodfwriter
SOURCES
text/qtextodfwriter.cpp text/qtextodfwriter_p.h
diff --git a/src/plugins/platforms/CMakeLists.txt b/src/plugins/platforms/CMakeLists.txt
index aba67bd59b..57c3952e4c 100644
--- a/src/plugins/platforms/CMakeLists.txt
+++ b/src/plugins/platforms/CMakeLists.txt
@@ -13,7 +13,7 @@ if(QT_FEATURE_xcb)
add_subdirectory(xcb)
endif()
if(APPLE_UIKIT AND NOT APPLE_WATCHOS)
- # add_subdirectory(ios) special case TODO
+ add_subdirectory(ios)
endif()
if(APPLE_OSX)
add_subdirectory(cocoa)
diff --git a/src/plugins/platforms/ios/.prev_CMakeLists.txt b/src/plugins/platforms/ios/.prev_CMakeLists.txt
new file mode 100644
index 0000000000..f23cf8c300
--- /dev/null
+++ b/src/plugins/platforms/ios/.prev_CMakeLists.txt
@@ -0,0 +1,81 @@
+# Generated from ios.pro.
+
+#####################################################################
+## qios Plugin:
+#####################################################################
+
+add_qt_plugin(qios
+ TYPE platforms
+ CLASS_NAME QIOSIntegrationPlugin
+ SOURCES
+ plugin.mm
+ qiosapplicationdelegate.h qiosapplicationdelegate.mm
+ qiosapplicationstate.h qiosapplicationstate.mm
+ qiosbackingstore.h qiosbackingstore.mm
+ qioscontext.h qioscontext.mm
+ qioseventdispatcher.h qioseventdispatcher.mm
+ qiosglobal.h qiosglobal.mm
+ qiosinputcontext.h qiosinputcontext.mm
+ qiosintegration.h qiosintegration.mm
+ qiosplatformaccessibility.h qiosplatformaccessibility.mm
+ qiosscreen.h qiosscreen.mm
+ qiosservices.h qiosservices.mm
+ qiostextresponder.h qiostextresponder.mm
+ qiostheme.h qiostheme.mm
+ qiosviewcontroller.h qiosviewcontroller.mm
+ qioswindow.h qioswindow.mm
+ quiaccessibilityelement.h quiaccessibilityelement.mm
+ quiview.h quiview.mm
+ LIBRARIES
+ Qt::ClipboardSupportPrivate
+ Qt::CorePrivate
+ Qt::FontDatabaseSupportPrivate
+ Qt::GraphicsSupportPrivate
+ Qt::GuiPrivate
+ PUBLIC_LIBRARIES
+ ${FWAudioToolbox}
+ ${FWFoundation}
+ ${FWQuartzCore}
+ ${FWUIKit}
+ Qt::ClipboardSupport
+ Qt::Core
+ Qt::FontDatabaseSupport
+ Qt::GraphicsSupport
+ Qt::Gui
+)
+
+#### Keys ignored in scope 2:.:.:kernel.pro:<TRUE>:
+# OTHER_FILES = "quiview_textinput.mm" "quiview_accessibility.mm"
+# PLUGIN_CLASS_NAME = "QIOSIntegrationPlugin"
+# PLUGIN_TYPE = "platforms"
+# _LOADED = "qt_plugin"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 3:.:.:kernel.pro:QT_FEATURE_shared:
+# CONFIG = "static"
+
+extend_target(qios CONDITION NOT APPLE_TVOS
+ SOURCES
+ qiosclipboard.h qiosclipboard.mm
+ qiosfiledialog.h qiosfiledialog.mm
+ qiosmenu.h qiosmenu.mm
+ qiosmessagedialog.h qiosmessagedialog.mm
+ qiostextinputoverlay.h qiostextinputoverlay.mm
+ PUBLIC_LIBRARIES
+ ${FWAssetsLibrary}
+)
+
+#### Keys ignored in scope 5:.:.:kernel.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN:
+# PLUGIN_EXTENDS = "-"
+add_subdirectory(optional)
+
+ if(QT_FEATURE_shared)
+ endif()
+
+ if(NOT APPLE_TVOS)
+ endif()
+
+ if(NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN)
+ endif()
diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt
new file mode 100644
index 0000000000..4c9cac2bee
--- /dev/null
+++ b/src/plugins/platforms/ios/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Generated from ios.pro.
+
+#####################################################################
+## qios Plugin:
+#####################################################################
+
+add_qt_plugin(qios
+ TYPE platforms
+ CLASS_NAME QIOSIntegrationPlugin
+ SOURCES
+ plugin.mm
+ qiosapplicationdelegate.h qiosapplicationdelegate.mm
+ qiosapplicationstate.h qiosapplicationstate.mm
+ qiosbackingstore.h qiosbackingstore.mm
+ qioscontext.h qioscontext.mm
+ qioseventdispatcher.h qioseventdispatcher.mm
+ qiosglobal.h qiosglobal.mm
+ qiosinputcontext.h qiosinputcontext.mm
+ qiosintegration.h qiosintegration.mm
+ qiosplatformaccessibility.h qiosplatformaccessibility.mm
+ qiosscreen.h qiosscreen.mm
+ qiosservices.h qiosservices.mm
+ qiostextresponder.h qiostextresponder.mm
+ qiostheme.h qiostheme.mm
+ qiosviewcontroller.h qiosviewcontroller.mm
+ qioswindow.h qioswindow.mm
+ quiaccessibilityelement.h quiaccessibilityelement.mm
+ quiview.h quiview.mm
+ LIBRARIES
+ Qt::ClipboardSupportPrivate
+ Qt::CorePrivate
+ Qt::FontDatabaseSupportPrivate
+ Qt::GraphicsSupportPrivate
+ Qt::GuiPrivate
+ PUBLIC_LIBRARIES
+ ${FWAudioToolbox}
+ ${FWFoundation}
+ ${FWQuartzCore}
+ ${FWUIKit}
+ Qt::ClipboardSupport
+ Qt::Core
+ Qt::FontDatabaseSupport
+ Qt::GraphicsSupport
+ Qt::Gui
+)
+
+#### Keys ignored in scope 2:.:.:kernel.pro:<TRUE>:
+# OTHER_FILES = "quiview_textinput.mm" "quiview_accessibility.mm"
+# PLUGIN_CLASS_NAME = "QIOSIntegrationPlugin"
+# PLUGIN_TYPE = "platforms"
+# _LOADED = "qt_plugin"
+
+## Scopes:
+#####################################################################
+
+#### Keys ignored in scope 3:.:.:kernel.pro:QT_FEATURE_shared:
+# CONFIG = "static"
+
+extend_target(qios CONDITION NOT APPLE_TVOS
+ SOURCES
+ qiosclipboard.h qiosclipboard.mm
+ qiosfiledialog.h qiosfiledialog.mm
+ qiosmenu.h qiosmenu.mm
+ qiosmessagedialog.h qiosmessagedialog.mm
+ qiostextinputoverlay.h qiostextinputoverlay.mm
+ PUBLIC_LIBRARIES
+ ${FWAssetsLibrary}
+)
+
+#### Keys ignored in scope 5:.:.:kernel.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN:
+# PLUGIN_EXTENDS = "-"
+add_subdirectory(optional)
diff --git a/src/plugins/platforms/ios/optional/CMakeLists.txt b/src/plugins/platforms/ios/optional/CMakeLists.txt
new file mode 100644
index 0000000000..a3807bee6c
--- /dev/null
+++ b/src/plugins/platforms/ios/optional/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Generated from optional.pro.
+
+
+if(APPLE_IOS)
+ add_subdirectory(nsphotolibrarysupport)
+endif()
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/CMakeLists.txt b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/CMakeLists.txt
new file mode 100644
index 0000000000..5adac3cabb
--- /dev/null
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Generated from nsphotolibrarysupport.pro.
+
+#####################################################################
+## qiosnsphotolibrarysupport Plugin:
+#####################################################################
+
+add_qt_plugin(qiosnsphotolibrarysupport
+ TYPE platforms/darwin
+ CLASS_NAME QIosOptionalPlugin_NSPhotoLibrary
+ SOURCES
+ plugin.mm
+ qiosfileengineassetslibrary.h qiosfileengineassetslibrary.mm
+ qiosfileenginefactory.h
+ qiosimagepickercontroller.h qiosimagepickercontroller.mm
+ LIBRARIES
+ Qt::GuiPrivate
+ PUBLIC_LIBRARIES
+ ${FWAssetsLibrary}
+ ${FWFoundation}
+ ${FWUIKit}
+ Qt::Core
+ Qt::Gui
+)
+
+#### Keys ignored in scope 1:.:.:nsphotolibrarysupport.pro:<TRUE>:
+# OTHER_FILES = "plugin.json"
+# PLUGIN_EXTENDS = "-"
+
+## Scopes:
+#####################################################################
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index 0bd3b47d92..c03838bee1 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -1,8 +1,6 @@
# Generated from auto.pro.
-if (NOT APPLE_UIKIT)
- add_subdirectory(corelib)
-endif()
+add_subdirectory(corelib)
if (QT_FEATURE_dbus)
set(run_dbus_tests ON)
if(NOT CMAKE_CROSSCOMPILING AND TARGET Qt::DBus)
@@ -22,9 +20,18 @@ if (QT_FEATURE_dbus)
add_subdirectory(dbus)
endif()
endif()
-if (NOT APPLE_UIKIT AND TARGET Qt::Gui)
+if (TARGET Qt::Gui)
add_subdirectory(gui)
endif()
+
+# special case begin
+# Build only corelib and gui tests when targeting uikit (iOS),
+# because the script can't handle the SUBDIRS assignment well.
+if (APPLE_UIKIT)
+ return()
+endif()
+# special case end
+
if (TARGET Qt::Network AND NOT WINRT)
add_subdirectory(network)
endif()
diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt
index 31547f6df7..9d5a3effaa 100644
--- a/tests/manual/CMakeLists.txt
+++ b/tests/manual/CMakeLists.txt
@@ -1,5 +1,12 @@
# Generated from manual.pro.
+# special case begn
+# Don't build manual tests when targeting iOS.
+if(APPLE_UIKIT)
+ return()
+endif()
+# special case end
+
add_subdirectory(bearerex)
add_subdirectory(filetest)
add_subdirectory(embeddedintoforeignwindow)
diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py
index 70d28c276b..481701eaed 100755
--- a/util/cmake/configurejson2cmake.py
+++ b/util/cmake/configurejson2cmake.py
@@ -708,6 +708,7 @@ def parseFeature(ctx, feature, data, cm_fh):
"opengles2": { # special case to disable implicit feature on WIN32, until ANGLE is ported
"condition": "NOT WIN32 AND ( NOT APPLE_WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND )"
},
+ "simulator_and_device": {"condition": "APPLE_UIKIT AND NOT QT_UIKIT_SDK"},
"pkg-config": None,
"posix_fallocate": None, # Only needed for sqlite, which we do not want to build
"posix-libiconv": {