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>
This commit is contained in:
Alexandru Croitor 2019-04-08 17:23:57 +02:00
parent c800a62403
commit 55a15a1c1b
22 changed files with 558 additions and 35 deletions

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -0,0 +1,6 @@
# Generated from optional.pro.
if(APPLE_IOS)
add_subdirectory(nsphotolibrarysupport)
endif()

View File

@ -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:
#####################################################################

View File

@ -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()

View File

@ -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)

View File

@ -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": {