summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake')
-rw-r--r--cmake/3rdparty/extra-cmake-modules/find-modules/FindWaylandScanner.cmake12
-rw-r--r--cmake/3rdparty/kwin/FindLibdrm.cmake8
-rw-r--r--cmake/3rdpartyConfig.cmake.in4
-rw-r--r--cmake/FindGLESv2.cmake27
-rw-r--r--cmake/FindMtdev.cmake2
-rw-r--r--cmake/FindWrapDBus1.cmake4
-rw-r--r--cmake/FindWrapHarfbuzz.cmake45
-rw-r--r--cmake/FindWrapPCRE2.cmake5
-rw-r--r--cmake/ModuleDescription.json.in11
-rw-r--r--cmake/Qt3rdPartyLibraryConfig.cmake.in26
-rw-r--r--cmake/QtAutoDetect.cmake126
-rw-r--r--cmake/QtBaseConfigureTests.cmake89
-rw-r--r--cmake/QtBaseGlobalTargets.cmake72
-rw-r--r--cmake/QtBuild.cmake1646
-rw-r--r--cmake/QtBuildInformation.cmake35
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake4
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake161
-rw-r--r--cmake/QtBuildInternalsExtra.cmake.in8
-rw-r--r--cmake/QtCompilerOptimization.cmake4
-rw-r--r--cmake/QtConfig.cmake.in7
-rw-r--r--cmake/QtFeature.cmake191
-rw-r--r--cmake/QtInternalTargets.cmake34
-rw-r--r--cmake/QtModuleConfig.cmake.in30
-rw-r--r--cmake/QtModuleToolsConfig.cmake.in3
-rw-r--r--cmake/QtModuleToolsDependencies.cmake.in4
-rw-r--r--cmake/QtModuleToolsVersionlessTargets.cmake.in23
-rw-r--r--cmake/QtPlatformAndroid.cmake67
-rw-r--r--cmake/QtPlatformSupport.cmake46
-rw-r--r--cmake/QtPluginConfig.cmake.in2
-rw-r--r--cmake/QtPlugins.cmake.in50
-rw-r--r--cmake/QtPostProcess.cmake97
-rw-r--r--cmake/QtProperties.cmake2
-rw-r--r--cmake/QtResource.cmake.in46
-rw-r--r--cmake/QtSetup.cmake65
-rw-r--r--cmake/QtStandaloneTestsConfig.cmake.in2
-rw-r--r--cmake/README.md63
36 files changed, 2332 insertions, 689 deletions
diff --git a/cmake/3rdparty/extra-cmake-modules/find-modules/FindWaylandScanner.cmake b/cmake/3rdparty/extra-cmake-modules/find-modules/FindWaylandScanner.cmake
index ed9c4c4c9a..13291afcda 100644
--- a/cmake/3rdparty/extra-cmake-modules/find-modules/FindWaylandScanner.cmake
+++ b/cmake/3rdparty/extra-cmake-modules/find-modules/FindWaylandScanner.cmake
@@ -129,11 +129,15 @@ function(ecm_add_wayland_client_protocol out_var)
add_custom_command(OUTPUT "${_client_header}"
COMMAND ${WaylandScanner_EXECUTABLE} client-header ${_infile} ${_client_header}
- DEPENDS ${_infile} VERBATIM)
+ DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile}
+ VERBATIM
+ )
add_custom_command(OUTPUT "${_code}"
COMMAND ${WaylandScanner_EXECUTABLE} code ${_infile} ${_code}
- DEPENDS ${_infile} ${_client_header} VERBATIM)
+ DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile} ${_client_header}
+ VERBATIM
+ )
list(APPEND ${out_var} "${_client_header}" "${_code}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
@@ -160,7 +164,9 @@ function(ecm_add_wayland_server_protocol out_var)
add_custom_command(OUTPUT "${_server_header}"
COMMAND ${WaylandScanner_EXECUTABLE} server-header ${_infile} ${_server_header}
- DEPENDS ${_infile} VERBATIM)
+ DEPENDS ${WaylandScanner_EXECUTABLE} ${_infile}
+ VERBATIM
+ )
list(APPEND ${out_var} "${_server_header}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
diff --git a/cmake/3rdparty/kwin/FindLibdrm.cmake b/cmake/3rdparty/kwin/FindLibdrm.cmake
index 9936e07eee..10822e693a 100644
--- a/cmake/3rdparty/kwin/FindLibdrm.cmake
+++ b/cmake/3rdparty/kwin/FindLibdrm.cmake
@@ -105,13 +105,19 @@ if(NOT WIN32)
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}"
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}/libdrm"
)
+ if(EXISTS "${Libdrm_INCLUDE_DIR}/drm")
+ set_property(TARGET Libdrm::Libdrm APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}/drm"
+ )
+ endif()
+
endif()
mark_as_advanced(Libdrm_LIBRARY Libdrm_INCLUDE_DIR)
# compatibility variables
set(Libdrm_LIBRARIES ${Libdrm_LIBRARY})
- set(Libdrm_INCLUDE_DIRS ${Libdrm_INCLUDE_DIR} "${Libdrm_INCLUDE_DIR}/libdrm")
+ set(Libdrm_INCLUDE_DIRS ${Libdrm_INCLUDE_DIR} "${Libdrm_INCLUDE_DIR}/libdrm" "${Libdrm_INCLUDE_DIR}/drm")
set(Libdrm_VERSION_STRING ${Libdrm_VERSION})
else()
diff --git a/cmake/3rdpartyConfig.cmake.in b/cmake/3rdpartyConfig.cmake.in
index fe15a1efc6..6af3792333 100644
--- a/cmake/3rdpartyConfig.cmake.in
+++ b/cmake/3rdpartyConfig.cmake.in
@@ -10,4 +10,6 @@ set(CMAKE_MODULE_PATH "${_import_prefix}" ${CMAKE_MODULE_PATH} )
set(CMAKE_MODULE_PATH "${old_CMAKE_MODULE_PATH}")
-include("${CMAKE_CURRENT_LIST_DIR}/@target@Targets.cmake")
+if (NOT QT_NO_CREATE_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@target@Targets.cmake")
+endif()
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/FindMtdev.cmake b/cmake/FindMtdev.cmake
index c852a77c1c..6184fe9b3c 100644
--- a/cmake/FindMtdev.cmake
+++ b/cmake/FindMtdev.cmake
@@ -2,6 +2,6 @@ find_package(PkgConfig)
pkg_check_modules(Mtdev mtdev IMPORTED_TARGET)
-if (NOT TARGET PkgConfig::MtDev)
+if (NOT TARGET PkgConfig::Mtdev)
set(Mtdev_FOUND 0)
endif()
diff --git a/cmake/FindWrapDBus1.cmake b/cmake/FindWrapDBus1.cmake
index c2668d6cc8..55f9757c45 100644
--- a/cmake/FindWrapDBus1.cmake
+++ b/cmake/FindWrapDBus1.cmake
@@ -2,6 +2,10 @@
# Work around that:-/
# See https://gitlab.freedesktop.org/dbus/dbus/issues/267 for more information
+if(DBus1_FOUND OR WrapDBus1_FOUND)
+ return()
+endif()
+
if(DEFINED ENV{PKG_CONFIG_DIR})
set(__qt_dbus_pcd "$ENV{PKG_CONFIG_DIR}")
endif()
diff --git a/cmake/FindWrapHarfbuzz.cmake b/cmake/FindWrapHarfbuzz.cmake
new file mode 100644
index 0000000000..f7845b28bd
--- /dev/null
+++ b/cmake/FindWrapHarfbuzz.cmake
@@ -0,0 +1,45 @@
+# We can't create the same interface imported target multiple times, CMake will complain if we do
+# that. This can happen if the find_package call is done in multiple different subdirectories.
+if(TARGET WrapHarfbuzz::WrapHarfbuzz)
+ set(WrapHarfbuzz_FOUND ON)
+ return()
+endif()
+
+set(WrapHarfbuzz_FOUND OFF)
+
+find_package(harfbuzz)
+
+# Gentoo has some buggy version of a harfbuzz Config file. Check if include paths are valid.
+set(__harfbuzz_target_name "harfbuzz::harfbuzz")
+if(harfbuzz_FOUND AND TARGET "${__harfbuzz_target_name}")
+ get_property(__harfbuzz_include_paths TARGET "${__harfbuzz_target_name}"
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+ foreach(__harfbuzz_include_dir ${__harfbuzz_include_paths})
+ if(NOT EXISTS "${__harfbuzz_include_dir}")
+ # Must be the broken Gentoo harfbuzzConfig.cmake file. Try to use pkg-config instead.
+ set(__harfbuzz_broken_config_file TRUE)
+ break()
+ endif()
+ endforeach()
+endif()
+
+if(__harfbuzz_broken_config_file)
+ find_package(PkgConfig)
+
+ pkg_check_modules(harfbuzz harfbuzz IMPORTED_TARGET)
+ set(__harfbuzz_target_name "PkgConfig::harfbuzz")
+
+ if (NOT TARGET "${__harfbuzz_target_name}")
+ set(harfbuzz_FOUND 0)
+ endif()
+endif()
+
+if(TARGET "${__harfbuzz_target_name}")
+ set(WrapHarfbuzz_FOUND ON)
+
+ add_library(WrapHarfbuzz::WrapHarfbuzz INTERFACE IMPORTED)
+ target_link_libraries(WrapHarfbuzz::WrapHarfbuzz INTERFACE ${__harfbuzz_target_name})
+endif()
+unset(__harfbuzz_target_name)
+unset(__harfbuzz_include_dir)
+unset(__harfbuzz_broken_config_file)
diff --git a/cmake/FindWrapPCRE2.cmake b/cmake/FindWrapPCRE2.cmake
index b69c5078a5..08f660bdfc 100644
--- a/cmake/FindWrapPCRE2.cmake
+++ b/cmake/FindWrapPCRE2.cmake
@@ -1,4 +1,7 @@
-include_guard(GLOBAL) # pragma once equivalent
+if(TARGET WrapPCRE2::WrapPCRE2)
+ set(WrapPCRE2_FOUND TRUE)
+ return()
+endif()
find_package(PCRE2 CONFIG QUIET)
diff --git a/cmake/ModuleDescription.json.in b/cmake/ModuleDescription.json.in
new file mode 100644
index 0000000000..e29f3f176d
--- /dev/null
+++ b/cmake/ModuleDescription.json.in
@@ -0,0 +1,11 @@
+{
+ "module_name": "${target}",
+ "version": "${CMAKE_PROJECT_VERSION}",
+ "built_with": {
+ "compiler_id": "${CMAKE_CXX_COMPILER_ID}",
+ "compiler_target": "${CMAKE_CXX_COMPILER_TARGET}",
+ "compiler_version": "${CMAKE_CXX_COMPILER_VERSION}",
+ "cross_compiled": ${cross_compilation},
+ "target_system": "${CMAKE_SYSTEM_NAME}"
+ }
+}
diff --git a/cmake/Qt3rdPartyLibraryConfig.cmake.in b/cmake/Qt3rdPartyLibraryConfig.cmake.in
new file mode 100644
index 0000000000..0facce906f
--- /dev/null
+++ b/cmake/Qt3rdPartyLibraryConfig.cmake.in
@@ -0,0 +1,26 @@
+@PACKAGE_INIT@
+
+include(CMakeFindDependencyMacro)
+
+get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
+
+# Extra cmake code begin
+@extra_cmake_code@
+# Extra cmake code end
+
+# Find required dependencies, if any.
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
+endif()
+
+if (NOT QT_NO_CREATE_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
+ if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
+ endif()
+endif()
+
+foreach(extra_cmake_include @extra_cmake_includes@)
+ include("${CMAKE_CURRENT_LIST_DIR}/${extra_cmake_include}")
+endforeach()
diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake
index a1e66ffcbe..95ace249ad 100644
--- a/cmake/QtAutoDetect.cmake
+++ b/cmake/QtAutoDetect.cmake
@@ -2,9 +2,12 @@
# Collection of auto dection routines to improve the user eperience when
# building Qt from source.
#
+# Make sure to not run detection when building standalone tests, because the detection was already
+# done when initially configuring qtbase.
function(qt_auto_detect_android)
- if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT DEFINED QT_AUTODETECT_ANDROID)
+ if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT DEFINED QT_AUTODETECT_ANDROID
+ AND NOT QT_BUILD_STANDALONE_TESTS)
file(READ ${CMAKE_TOOLCHAIN_FILE} toolchain_file_content OFFSET 0 LIMIT 80)
string(FIND ${toolchain_file_content} "The Android Open Source Project" find_result REVERSE)
@@ -31,7 +34,7 @@ function(qt_auto_detect_android)
endfunction()
function(qt_auto_detect_vpckg)
- if(DEFINED ENV{VCPKG_ROOT})
+ if(DEFINED ENV{VCPKG_ROOT} AND NOT QT_BUILD_STANDALONE_TESTS)
set(vcpkg_toolchain_file "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
get_filename_component(vcpkg_toolchain_file "${vcpkg_toolchain_file}" ABSOLUTE)
@@ -49,9 +52,128 @@ function(qt_auto_detect_vpckg)
message(STATUS "Using vcpkg triplet ${VCPKG_TARGET_TRIPLET}")
endif()
unset(vcpkg_toolchain_file)
+ message(STATUS "CMAKE_TOOLCHAIN_FILE is: ${CMAKE_TOOLCHAIN_FILE}")
+ if(DEFINED VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
+ message(STATUS "VCPKG_CHAINLOAD_TOOLCHAIN_FILE is: ${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
+ endif()
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()
+
+function(qt_auto_detect_cmake_config)
+ if(CMAKE_CONFIGURATION_TYPES)
+ # Allow users to specify this option.
+ if(NOT QT_MULTI_CONFIG_FIRST_CONFIG)
+ list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
+ set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}")
+ set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}" PARENT_SCOPE)
+ endif()
+
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
+ if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
+ set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE ON PARENT_SCOPE)
+ set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+qt_auto_detect_cmake_config()
+qt_auto_detect_ios()
qt_auto_detect_android()
qt_auto_detect_vpckg()
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index 34e4e6e6f1..0d6bb1407b 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -1,26 +1,47 @@
include(CheckCXXSourceCompiles)
-function(run_config_test_architecture)
- set(qt_base_configure_tests_vars_to_export)
- # 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()
- try_compile(_arch_result "${CMAKE_CURRENT_BINARY_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/arch/arch.cpp"
- COPY_FILE "${_arch_file}")
+function(qt_run_config_test_architecture)
+ set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT
+ "" CACHE INTERNAL "Test variables that should be exported" FORCE)
+
+ # 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})
- 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_test_location "config.tests/arch")
+ if(QT_MULTI_CONFIG_FIRST_CONFIG)
+ string(APPEND arch_test_location "/${QT_MULTI_CONFIG_FIRST_CONFIG}")
+ endif()
+
+ set(_arch_file
+ "${CMAKE_CURRENT_BINARY_DIR}/${arch_test_location}/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})
@@ -49,20 +70,23 @@ function(run_config_test_architecture)
set(TEST_architecture 1 CACHE INTERNAL "Ran the architecture test")
set(TEST_architecture_arch "${_architecture}" CACHE INTERNAL "Target machine architecture")
- list(APPEND qt_base_configure_tests_vars_to_export TEST_architecture_arch)
+ list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_architecture_arch)
set(TEST_subarch 1 CACHE INTERNAL "Ran machine subArchitecture test")
foreach(it ${_sub_architecture})
# Equivalent to qmake's QT_CPU_FEATURES.$arch.
set(TEST_arch_${TEST_architecture_arch}_subarch_${it} 1 CACHE INTERNAL "Target sub architecture result")
- list(APPEND qt_base_configure_tests_vars_to_export TEST_arch_${TEST_architecture_arch}_subarch_${it})
+ list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_arch_${TEST_architecture_arch}_subarch_${it})
endforeach()
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(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()
-function(run_config_test_posix_iconv)
+function(qt_run_config_test_posix_iconv)
set(source "#include <iconv.h>
int main(int, char **)
@@ -94,7 +118,7 @@ int main(int, char **)
endfunction()
-function(run_config_test_sun_iconv)
+function(qt_run_config_test_sun_iconv)
set(source "#include <iconv.h>
int main(int, char **)
@@ -120,7 +144,7 @@ int main(int, char **)
set(TEST_sun_iconv "${HAVE_SUN_ICONV}" CACHE INTERNAL "SUN libiconv")
endfunction()
-function(run_linker_version_script_support)
+function(qt_run_linker_version_script_support)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/version_flag.map" "VERS_1 { global: sym; };
VERS_2 { global: sym; }
VERS_1;
@@ -147,8 +171,8 @@ VERS_1;
set(TEST_ld_version_script "${HAVE_LD_VERSION_SCRIPT}" CACHE INTERNAL "linker version script support")
endfunction()
-function(run_config_tests)
- run_config_test_posix_iconv()
+function(qt_run_qtbase_config_tests)
+ qt_run_config_test_posix_iconv()
add_library(Iconv INTERFACE)
if(TEST_iconv_needlib)
@@ -156,10 +180,19 @@ function(run_config_tests)
endif()
if(NOT TEST_posix_iconv)
- run_config_test_sun_iconv()
+ qt_run_config_test_sun_iconv()
endif()
- run_config_test_architecture()
- run_linker_version_script_support()
+ qt_run_config_test_architecture()
+ qt_run_linker_version_script_support()
endfunction()
-run_config_tests()
+# The qmake build of android does not perform the right architecture tests and
+# forcefully disables sse4 on android x86. We have to mimic this behavior
+# for now
+if (CMAKE_ANDROID_ARCH_ABI STREQUAL x86)
+ set(QT_FEATURE_sse4_1 OFF CACHE BOOL INTERNAL FORCE)
+ set(QT_FEATURE_sse4_2 OFF CACHE BOOL INTERNAL FORCE)
+ set(TEST_subarch_sse4_1 FALSE CACHE BOOL INTERNAL FORCE)
+ set(TEST_subarch_sse4_2 FALSE CACHE BOOL INTERNAL FORCE)
+endif()
+qt_run_qtbase_config_tests()
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index df3ceb88c0..fb27618499 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -3,9 +3,9 @@ add_library(Platform INTERFACE)
add_library(Qt::Platform ALIAS Platform)
target_include_directories(Platform
INTERFACE
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/${QT_PLATFORM_DEFINITION_DIR}>
- $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
- $<INSTALL_INTERFACE:${INSTALL_DATADIR}/${QT_PLATFORM_DEFINITION_DIR}>
+ $<BUILD_INTERFACE:${QT_PLATFORM_DEFINITION_DIR_ABSOLUTE}>
+ $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${INSTALL_INCLUDEDIR}>
+ $<INSTALL_INTERFACE:${QT_PLATFORM_DEFINITION_DIR}>
$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}>
)
target_compile_definitions(Platform INTERFACE ${QT_PLATFORM_DEFINITIONS})
@@ -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,18 +124,39 @@ 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)
# Also provide a convenience cmake wrapper
if(UNIX)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in" "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" @ONLY)
- qt_install(PROGRAMS "${QT_BUILD_DIR}/bin/qt-cmake" DESTINATION "${INSTALL_BINDIR}")
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" DESTINATION "${INSTALL_BINDIR}")
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in" "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" @ONLY)
- qt_install(PROGRAMS "${QT_BUILD_DIR}/bin/qt-cmake.bat" DESTINATION "${INSTALL_BINDIR}")
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" DESTINATION "${INSTALL_BINDIR}")
endif()
+# Provide a private convenience wrapper with options which should not be propagated via the public
+# qt-cmake wrapper e.g. CMAKE_GENERATOR.
+# These options can not be set in a toolchain file, but only on the command line.
+# These options should not be in the public wrapper, because a consumer of Qt might want to build
+# their CMake app with the Unix Makefiles generator, while Qt should be built with the Ninja
+# generator.
+# The private wrapper is more conveient for building Qt itself, because a developer doesn't need
+# to specify the same options for each qt module built.
+set(__qt_cmake_extra "-G\"${CMAKE_GENERATOR}\"")
+if(UNIX)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in"
+ "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private" @ONLY)
+qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private" DESTINATION "${INSTALL_BINDIR}")
+else()
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in"
+ "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" @ONLY)
+qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" DESTINATION "${INSTALL_BINDIR}")
+endif()
+unset(__qt_cmake_extra)
+
## Library to hold global features:
## These features are stored and accessed via Qt::GlobalConfig, but the
## files always lived in Qt::Core, so we keep it that way
@@ -135,6 +172,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()
@@ -174,7 +221,9 @@ qt_internal_export_modern_cmake_config_targets_file(TARGETS ${__export_targets}
## Install some QtBase specific CMake files:
qt_copy_or_install(FILES
+ cmake/ModuleDescription.json.in
cmake/QtBuild.cmake
+ cmake/QtBuildInformation.cmake
cmake/QtCompilerFlags.cmake
cmake/QtCompilerOptimization.cmake
cmake/QtFeature.cmake
@@ -186,18 +235,15 @@ qt_copy_or_install(FILES
cmake/QtModuleDependencies.cmake.in
cmake/QtModuleToolsDependencies.cmake.in
cmake/QtModuleToolsConfig.cmake.in
+ cmake/QtModuleToolsVersionlessTargets.cmake.in
+ cmake/QtStandaloneTestsConfig.cmake.in
cmake/QtPlugins.cmake.in
cmake/QtPluginConfig.cmake.in
cmake/QtPluginDependencies.cmake.in
DESTINATION "${__GlobalConfig_install_dir}"
)
-if(QT_WILL_INSTALL)
- # NOTE: QtFeature.cmake is included by the Qt module config files unconditionally
- # In a prefix build, QtFeature.cmake is not copied to the build dir by default
- # Thus do it explicitly in that case so we can use the module config files in the examples
- file(COPY cmake/QtFeature.cmake DESTINATION "${__GlobalConfig_install_dir}")
-endif()
+file(COPY cmake/QtFeature.cmake DESTINATION "${__GlobalConfig_build_dir}")
# TODO: Check whether this is the right place to install these
qt_copy_or_install(DIRECTORY cmake/3rdparty DESTINATION "${__GlobalConfig_install_dir}")
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake
index 537979ad8a..4456ea99f1 100644
--- a/cmake/QtBuild.cmake
+++ b/cmake/QtBuild.cmake
@@ -1,11 +1,12 @@
include(CMakePackageConfigHelpers)
# Install locations:
-set(INSTALL_BINDIR "bin" CACHE PATH "Executables [PREFIX/bin]")
-set(INSTALL_INCLUDEDIR "include" CACHE PATH "Header files [PREFIX/include]")
-set(INSTALL_LIBDIR "lib" CACHE PATH "Libraries [PREFIX/lib]")
-set(INSTALL_ARCHDATADIR "." CACHE PATH "Arch-dependent data [PREFIX]")
-set(INSTALL_PLUGINSDIR "${INSTALL_ARCHDATADIR}/plugins" CACHE PATH
+set(INSTALL_BINDIR "bin" CACHE STRING "Executables [PREFIX/bin]")
+set(INSTALL_INCLUDEDIR "include" CACHE STRING "Header files [PREFIX/include]")
+set(INSTALL_LIBDIR "lib" CACHE STRING "Libraries [PREFIX/lib]")
+set(INSTALL_MKSPECSDIR "mkspecs" CACHE STRING "Mkspecs files [PREFIX/mkspecs]")
+set(INSTALL_ARCHDATADIR "." CACHE STRING "Arch-dependent data [PREFIX]")
+set(INSTALL_PLUGINSDIR "${INSTALL_ARCHDATADIR}/plugins" CACHE STRING
"Plugins [ARCHDATADIR/plugins]")
set(INSTALL_TARGETS_DEFAULT_ARGS
@@ -21,20 +22,20 @@ else()
set(_default_libexec "${INSTALL_ARCHDATADIR}/libexec")
endif()
-set(INSTALL_LIBEXECDIR "${_default_libexec}" CACHE PATH
+set(INSTALL_LIBEXECDIR "${_default_libexec}" CACHE STRING
"Helper programs [ARCHDATADIR/bin on Windows, ARCHDATADIR/libexec otherwise]")
-set(INSTALL_IMPORTDIR "${INSTALL_ARCHDATADIR}/imports" CACHE PATH
- "QML1 imports [ARCHDATADIR/imports]")
-set(INSTALL_QMLDIR "${INSTALL_ARCHDATADIR}/qml" CACHE PATH
+set(INSTALL_QMLDIR "${INSTALL_ARCHDATADIR}/qml" CACHE STRING
"QML2 imports [ARCHDATADIR/qml]")
-set(INSTALL_DATADIR "." CACHE PATH "Arch-independent data [PREFIX]")
-set(INSTALL_DOCDIR "${INSTALL_DATADIR}/doc" CACHE PATH "Documentation [DATADIR/doc]")
-set(INSTALL_TRANSLATIONSDIR "${INSTALL_DATADIR}/translations" CACHE PATH
+set(INSTALL_DATADIR "." CACHE STRING "Arch-independent data [PREFIX]")
+set(INSTALL_DOCDIR "${INSTALL_DATADIR}/doc" CACHE STRING "Documentation [DATADIR/doc]")
+set(INSTALL_TRANSLATIONSDIR "${INSTALL_DATADIR}/translations" CACHE STRING
"Translations [DATADIR/translations]")
-set(INSTALL_SYSCONFDIR "etc/xdg" CACHE PATH
+set(INSTALL_SYSCONFDIR "etc/xdg" CACHE STRING
"Settings used by Qt programs [PREFIX/etc/xdg]")
-set(INSTALL_EXAMPLESDIR "examples" CACHE PATH "Examples [PREFIX/examples]")
-set(INSTALL_TESTSDIR "tests" CACHE PATH "Tests [PREFIX/tests]")
+set(INSTALL_EXAMPLESDIR "examples" CACHE STRING "Examples [PREFIX/examples]")
+set(INSTALL_TESTSDIR "tests" CACHE STRING "Tests [PREFIX/tests]")
+set(INSTALL_DESCRIPTIONSDIR "${INSTALL_DATADIR}/modules" CACHE STRING
+ "Module description files directory")
# The variables might have already been set in QtBuildInternalsExtra.cmake if the file is included
# while building a new module and not QtBase. In that case, stop overriding the value.
@@ -49,10 +50,22 @@ endif()
set(QT_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")
+# Find the path to mkspecs/, depending on whether we are building as part of a standard qtbuild,
+# or a module against an already installed version of qt.
+if(NOT QT_MKSPECS_DIR)
+ if("${QT_BUILD_INTERNALS_PATH}" STREQUAL "")
+ get_filename_component(QT_MKSPECS_DIR "${CMAKE_CURRENT_LIST_DIR}/../mkspecs" ABSOLUTE)
+ else()
+ # We can rely on CMAKE_INSTALL_PREFIX being set by QtBuildInternalsExtra.cmake
+ get_filename_component(QT_MKSPECS_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_MKSPECSDIR}" ABSOLUTE)
+ endif()
+ set(QT_MKSPECS_DIR "${QT_MKSPECS_DIR}" CACHE INTERNAL "")
+endif()
+
# the default RPATH to be used when installing, but only if it's not a system directory
-LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
+LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
- SET(_default_install_rpath "${CMAKE_INSTALL_PREFIX}/lib")
+ SET(_default_install_rpath "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
ENDIF("${isSystemDir}" STREQUAL "-1")
# Default rpath settings: Use rpath for build tree as well as a full path for the installed binaries.
@@ -63,6 +76,23 @@ SET(CMAKE_INSTALL_RPATH "${_default_install_rpath}" CACHE PATH "RPATH for instal
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+# Generate a module description file based on the template in ModuleDescription.json.in
+function(qt_describe_module target)
+ set(path_suffix "${INSTALL_DESCRIPTIONSDIR}")
+ qt_path_join(build_dir ${QT_BUILD_DIR} ${path_suffix})
+ qt_path_join(install_dir ${QT_INSTALL_DIR} ${path_suffix})
+
+ set(descfile_in "${QT_CMAKE_DIR}/ModuleDescription.json.in")
+ set(descfile_out "${build_dir}/${target}.json")
+ set(cross_compilation "false")
+ if(CMAKE_CROSSCOMPILE)
+ set(cross_compilation "true")
+ endif()
+ configure_file("${descfile_in}" "${descfile_out}")
+
+ qt_install(FILES "${descfile_out}" DESTINATION "${install_dir}")
+endfunction()
+
function(qt_setup_tool_path_command)
if(NOT WIN32)
return()
@@ -84,10 +114,13 @@ if(WIN32)
endif()
if(MSVC)
set(QT_QMAKE_TARGET_MKSPEC win32-msvc)
- elseif(CLANG)
- set(QT_QMAKE_TARGET_MKSPEC win32-clang)
+ elseif(CLANG AND MINGW)
+ set(QT_QMAKE_TARGET_MKSPEC win32-clang-g++)
elseif(MINGW)
set(QT_QMAKE_TARGET_MKSPEC win32-g++)
+ endif()
+
+ if (MINGW)
list(APPEND QT_DEFAULT_PLATFORM_DEFINITIONS _WIN32_WINNT=0x0601)
endif()
elseif(LINUX)
@@ -113,8 +146,19 @@ endif()
# TODO: Fixme to be correct.
set(QT_QMAKE_HOST_MKSPEC "${QT_QMAKE_TARGET_MKSPEC}")
-if(QT_QMAKE_TARGET_MKSPEC)
- set(QT_DEFAULT_PLATFORM_DEFINITION_DIR mkspecs/${QT_QMAKE_TARGET_MKSPEC})
+# Platform definition dir provided by user on command line.
+# Derive the absolute one relative to the current source dir.
+if(QT_PLATFORM_DEFINITION_DIR)
+ set(QT_DEFAULT_PLATFORM_DEFINITION_DIR "${QT_PLATFORM_DEFINITION_DIR}")
+ get_filename_component(
+ QT_DEFAULT_PLATFORM_DEFINITION_DIR_ABSOLUTE
+ "${QT_PLATFORM_DEFINITION_DIR}"
+ ABSOLUTE)
+elseif(QT_QMAKE_TARGET_MKSPEC)
+ # Used by consumers of prefix builds via INSTALL_INTERFACE (relative path).
+ set(QT_DEFAULT_PLATFORM_DEFINITION_DIR "${INSTALL_MKSPECSDIR}/${QT_QMAKE_TARGET_MKSPEC}")
+ # Used by qtbase itself and consumers of non-prefix builds via BUILD_INTERFACE (absolute path).
+ set(QT_DEFAULT_PLATFORM_DEFINITION_DIR_ABSOLUTE "${QT_MKSPECS_DIR}/${QT_QMAKE_TARGET_MKSPEC}")
endif()
if(NOT DEFINED QT_DEFAULT_PLATFORM_DEFINITIONS)
@@ -123,8 +167,10 @@ endif()
set(QT_PLATFORM_DEFINITIONS ${QT_DEFAULT_PLATFORM_DEFINITIONS}
CACHE STRING "Qt platform specific pre-processor defines")
-set(QT_PLATFORM_DEFINITION_DIR ${QT_DEFAULT_PLATFORM_DEFINITION_DIR}
+set(QT_PLATFORM_DEFINITION_DIR "${QT_DEFAULT_PLATFORM_DEFINITION_DIR}"
CACHE PATH "Path to directory that contains qplatformdefs.h")
+set(QT_PLATFORM_DEFINITION_DIR_ABSOLUTE "${QT_DEFAULT_PLATFORM_DEFINITION_DIR_ABSOLUTE}"
+ CACHE INTERNAL "Path to directory that contains qplatformdefs.h")
set(QT_NAMESPACE "" CACHE STRING "Qt Namespace")
if(QT_NAMESPACE STREQUAL "")
set(QT_HAS_NAMESPACE OFF)
@@ -192,6 +238,8 @@ macro(qt_internal_append_known_modules_with_tools module)
if(NOT ${module} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS)
set(QT_KNOWN_MODULES_WITH_TOOLS "${QT_KNOWN_MODULES_WITH_TOOLS};${module}"
CACHE INTERNAL "Known Qt modules with tools" FORCE)
+ set(QT_KNOWN_MODULE_${module}_TOOLS ""
+ CACHE INTERNAL "Known Qt module ${module} tools" FORCE)
endif()
endmacro()
@@ -217,7 +265,8 @@ else()
endif()
# Compute the values of QT_BUILD_DIR, QT_INSTALL_DIR, QT_CONFIG_BUILD_DIR, QT_CONFIG_INSTALL_DIR
-# taking into account whether the current build is a prefix build or a non-prefix build.
+# taking into account whether the current build is a prefix build or a non-prefix build,
+# and whether it is a superbuild or non-superbuild.
#
# These values should be prepended to file paths in commands or properties,
# in order to correctly place generated Config files, generated Targets files,
@@ -226,17 +275,29 @@ endif()
# The build dir variables will always be absolute paths.
# The QT_INSTALL_DIR variable will have a relative path in a prefix build,
# which means that it can be empty, so use qt_join_path to prevent accidental absolute paths.
-if(QT_WILL_INSTALL)
- # In the usual prefix build case, the build dir is the current module build dir,
- # and the install dir is the prefix, so we don't set it.
- set(QT_BUILD_DIR "${CMAKE_BINARY_DIR}")
- set(QT_INSTALL_DIR "")
+if(QT_SUPERBUILD)
+ # In this case, we always copy all the build products in qtbase/{bin,lib,...}
+ if(QT_WILL_INSTALL)
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "${QtBase_BINARY_DIR}")
+ endif()
else()
- # When doing a non-prefix build, both the build dir and install dir are the same,
- # pointing to the qtbase build dir.
- set(QT_BUILD_DIR "${CMAKE_INSTALL_PREFIX}")
- set(QT_INSTALL_DIR "${QT_BUILD_DIR}")
+ if(QT_WILL_INSTALL)
+ # In the usual prefix build case, the build dir is the current module build dir,
+ # and the install dir is the prefix, so we don't set it.
+ set(QT_BUILD_DIR "${CMAKE_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ # When doing a non-prefix build, both the build dir and install dir are the same,
+ # pointing to the qtbase build dir.
+ set(QT_BUILD_DIR "${CMAKE_INSTALL_PREFIX}")
+ set(QT_INSTALL_DIR "${QT_BUILD_DIR}")
+ endif()
endif()
+
set(__config_path_part "${INSTALL_LIBDIR}/cmake")
set(QT_CONFIG_BUILD_DIR "${QT_BUILD_DIR}/${__config_path_part}")
set(QT_CONFIG_INSTALL_DIR "${QT_INSTALL_DIR}")
@@ -398,7 +459,15 @@ endfunction()
# at CMake configuration step, and use it as an input to a custom command that replaces the
# cmake_install.cmake file with an empty one. This means we will always replace the file on
# every reconfiguration, but not when doing null builds.
-function(remove_install_target)
+function(qt_remove_install_target)
+ # On superbuilds we only do this for qtbase - it will correctly remove the
+ # cmake_install.cmake at the root of the repository.
+ if(QT_SUPERBUILD)
+ if(NOT (PROJECT_NAME STREQUAL "QtBase"))
+ return()
+ endif()
+ endif()
+
set(file_in "${CMAKE_BINARY_DIR}/.remove_cmake_install_in.txt")
set(file_generated "${CMAKE_BINARY_DIR}/.remove_cmake_install_generated.txt")
set(cmake_install_file "${CMAKE_BINARY_DIR}/cmake_install.cmake")
@@ -416,7 +485,7 @@ endfunction()
function(qt_set_up_nonprefix_build)
if(NOT QT_WILL_INSTALL)
- remove_install_target()
+ qt_remove_install_target()
endif()
endfunction()
@@ -519,7 +588,7 @@ QT.${module_lower}_private.disabled_features = ${disabled_private_features}
endfunction()
function(qt_generate_global_config_pri_file)
- qt_path_join(qconfig_pri_target_path ${PROJECT_BINARY_DIR} mkspecs)
+ qt_path_join(qconfig_pri_target_path ${PROJECT_BINARY_DIR} ${INSTALL_MKSPECSDIR})
qt_path_join(qconfig_pri_target_path "${qconfig_pri_target_path}" "qconfig.pri")
get_target_property(enabled_features GlobalConfig INTERFACE_QT_ENABLED_PUBLIC_FEATURES)
@@ -571,7 +640,7 @@ CONFIG -= link_prl # we do not create prl files right now
CONFIG += ${config_entries}
"
)
- qt_install(FILES "${qconfig_pri_target_path}" DESTINATION mkspecs)
+ qt_install(FILES "${qconfig_pri_target_path}" DESTINATION ${INSTALL_MKSPECSDIR})
endfunction()
# Takes a list of path components and joins them into one path separated by forward slashes "/",
@@ -668,8 +737,11 @@ function(qt_create_nolink_target target dependee_target)
# Create the nolink interface target, assign the properties from the original target,
# associate the nolink target with the same export which contains
# the target that uses the _nolink target.
- # Also create a namespaced alias of the form {$target}::${target}_nolink which is used by
+ # Also create a namespaced alias of the form ${target}::${target}_nolink which is used by
# our modules.
+ # Also create a Qt namespaced alias target, because when exporting via install(EXPORT)
+ # Vulkan::Vulkan_nolink transforms into Qt6::Vulkan_nolink, and the latter needs to be an
+ # accessible alias for standalone tests.
if(NOT TARGET "${nolink_target}")
add_library("${nolink_target}" INTERFACE)
set(prefixed_nolink_target "${target}_nolink")
@@ -686,6 +758,7 @@ function(qt_create_nolink_target target dependee_target)
$<TARGET_PROPERTY:${target},INTERFACE_COMPILE_FEATURES>)
add_library(${prefixed_nolink_target} ALIAS ${nolink_target})
+ add_library("${INSTALL_CMAKE_NAMESPACE}::${nolink_target}" ALIAS ${nolink_target})
set(export_name "${INSTALL_CMAKE_NAMESPACE}${dependee_target}Targets")
qt_install(TARGETS ${nolink_target} EXPORT ${export_name})
@@ -718,6 +791,12 @@ function(qt_ensure_sync_qt)
qt_path_join(syncqt_install_dir ${QT_INSTALL_DIR} ${INSTALL_LIBEXECDIR})
qt_copy_or_install(PROGRAMS "${SYNCQT_FROM_SOURCE}"
DESTINATION "${syncqt_install_dir}")
+ elseif(QT_HOST_PATH)
+ get_filename_component(syncqt_absolute_path
+ "${QT_HOST_PATH}/${INSTALL_LIBEXECDIR}/syncqt.pl"
+ ABSOLUTE)
+ set(QT_SYNCQT "${syncqt_absolute_path}" CACHE FILEPATH "syncqt script")
+ message(STATUS "Using host syncqt found at: ${QT_SYNCQT}")
else()
get_filename_component(syncqt_absolute_path
"${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}/syncqt.pl"
@@ -736,17 +815,30 @@ macro(qt_parse_all_arguments result type flags options multiopts)
endif()
endmacro()
+include(CheckCXXSourceCompiles)
function(qt_internal_add_link_flags_no_undefined target)
if (NOT QT_BUILD_SHARED_LIBS)
return()
endif()
if (GCC OR CLANG)
- if(APPLE)
+ set(previous_CMAKE_REQUIRED_LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+
+ set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,-undefined,error")
+ check_cxx_source_compiles("int main() {}" HAVE_DASH_UNDEFINED_ERROR)
+ if(HAVE_DASH_UNDEFINED_ERROR)
set(no_undefined_flag "-Wl,-undefined,error")
- elseif(LINUX OR MINGW OR ANDROID)
+ endif()
+
+ set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--no-undefined")
+ check_cxx_source_compiles("int main() {}" HAVE_DASH_DASH_NO_UNDEFINED)
+ if(HAVE_DASH_DASH_NO_UNDEFINED)
set(no_undefined_flag "-Wl,--no-undefined")
- else()
+ endif()
+
+ set(CMAKE_REQUIRED_LINK_OPTIONS ${previous_CMAKE_REQUIRED_LINK_OPTIONS})
+
+ if (NOT HAVE_DASH_UNDEFINED_ERROR AND NOT HAVE_DASH_DASH_NO_UNDEFINED)
message(FATAL_ERROR "Platform linker doesn't support erroring upon encountering undefined symbols. Target:\"${target}\".")
endif()
target_link_options("${target}" PRIVATE "${no_undefined_flag}")
@@ -810,7 +902,7 @@ function(qt_internal_add_linker_version_script target)
qt_ensure_perl()
add_custom_command(TARGET "${target}" PRE_LINK
- COMMAND "${HOST_PERL}" "${PROJECT_SOURCE_DIR}/mkspecs/features/data/unix/findclasslist.pl" < "${infile}" > "${outfile}"
+ COMMAND "${HOST_PERL}" "${QT_MKSPECS_DIR}/features/data/unix/findclasslist.pl" < "${infile}" > "${outfile}"
BYPRODUCTS "${outfile}" DEPENDS "${infile}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating version linker script"
@@ -845,8 +937,8 @@ function(qt_internal_module_info result target)
string(REPLACE "." "_" define "${define}")
set("${result}_upper" "${upper}" PARENT_SCOPE)
set("${result}_lower" "${lower}" PARENT_SCOPE)
- set("${result}_repo_include_dir" "${QT_BUILD_DIR}/include" PARENT_SCOPE)
- set("${result}_include_dir" "${QT_BUILD_DIR}/include/${module}" PARENT_SCOPE)
+ set("${result}_repo_include_dir" "${QT_BUILD_DIR}/${INSTALL_INCLUDEDIR}" PARENT_SCOPE)
+ set("${result}_include_dir" "${QT_BUILD_DIR}/${INSTALL_INCLUDEDIR}/${module}" PARENT_SCOPE)
set("${result}_define" "${define}" PARENT_SCOPE)
endfunction()
@@ -854,7 +946,7 @@ endfunction()
set(__default_private_args "SOURCES;LIBRARIES;INCLUDE_DIRECTORIES;DEFINES;DBUS_ADAPTOR_BASENAME;DBUS_ADAPTOR_FLAGS;DBUS_ADAPTOR_SOURCES;DBUS_INTERFACE_BASENAME;DBUS_INTERFACE_FLAGS;DBUS_INTERFACE_SOURCES;FEATURE_DEPENDENCIES;COMPILE_OPTIONS;LINK_OPTIONS;MOC_OPTIONS;DISABLE_AUTOGEN_TOOLS;ENABLE_AUTOGEN_TOOLS;PLUGIN_TYPES")
set(__default_public_args "PUBLIC_LIBRARIES;PUBLIC_INCLUDE_DIRECTORIES;PUBLIC_DEFINES;PUBLIC_COMPILE_OPTIONS;PUBLIC_LINK_OPTIONS")
-
+set(__default_private_module_args "PRIVATE_MODULE_INTERFACE")
option(QT_CMAKE_DEBUG_EXTEND_TARGET "Debug extend_target calls in Qt's build system" OFF)
@@ -865,8 +957,10 @@ function(qt_autogen_tools_initial_setup target)
set_property(TARGET "${target}" APPEND PROPERTY COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION)
set_directory_properties(PROPERTIES
- QT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}
- QT_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+ QT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}
+ QT_VERSION_MINOR ${PROJECT_VERSION_MINOR}
+ QT_VERSION_PATCH ${PROJECT_VERSION_PATCH}
+ )
qt_enable_autogen_tool(${target} "moc" ON)
endfunction()
@@ -930,7 +1024,14 @@ function(qt_register_target_dependencies target public_libs private_libs)
set(target_deps "")
endif()
- foreach(lib IN LISTS public_libs private_libs)
+ # Only process private dependencies if target is a static library
+ get_target_property(target_type ${target} TYPE)
+ set(lib_list ${public_libs})
+ if (target_type STREQUAL "STATIC_LIBRARY")
+ list(APPEND lib_list ${private_libs})
+ endif()
+
+ foreach(lib IN LISTS lib_list)
if ("${lib}" MATCHES "^Qt::(.*)")
set(lib "${CMAKE_MATCH_1}")
if (lib STREQUAL Platform
@@ -980,7 +1081,7 @@ endfunction()
# This function can be used to add sources/libraries/etc. to the specified CMake target
# if the provided CONDITION evaluates to true.
-function(extend_target target)
+function(qt_extend_target target)
# Don't try to extend_target when cross compiling an imported host target (like a tool).
qt_is_imported_target("${target}" is_imported)
if(is_imported)
@@ -990,8 +1091,8 @@ function(extend_target target)
if (NOT TARGET "${target}")
message(FATAL_ERROR "Trying to extend non-existing target \"${target}\".")
endif()
- qt_parse_all_arguments(arg "extend_target" "HEADER_MODULE" "PRECOMPILED_HEADER"
- "CONDITION;${__default_public_args};${__default_private_args};COMPILE_FLAGS;NO_PCH_SOURCES" ${ARGN})
+ qt_parse_all_arguments(arg "qt_extend_target" "HEADER_MODULE" "PRECOMPILED_HEADER"
+ "CONDITION;${__default_public_args};${__default_private_args};${__default_private_module_args};COMPILE_FLAGS;NO_PCH_SOURCES" ${ARGN})
if ("x${arg_CONDITION}" STREQUAL x)
set(arg_CONDITION ON)
endif()
@@ -999,7 +1100,7 @@ function(extend_target target)
qt_evaluate_config_expression(result ${arg_CONDITION})
if (${result})
if(QT_CMAKE_DEBUG_EXTEND_TARGET)
- message("extend_target(${target} CONDITION ${arg_CONDITION} ...): Evaluated")
+ message("qt_extend_target(${target} CONDITION ${arg_CONDITION} ...): Evaluated")
endif()
set(dbus_sources "")
foreach(adaptor ${arg_DBUS_ADAPTOR_SOURCES})
@@ -1073,10 +1174,12 @@ function(extend_target target)
${private_visibility_option} ${arg_LINK_OPTIONS})
if(NOT arg_HEADER_MODULE)
- set_target_properties("${target}" PROPERTIES
+ set_property (TARGET "${target}" APPEND PROPERTY
AUTOMOC_MOC_OPTIONS "${arg_MOC_OPTIONS}"
- _qt_target_deps "${target_deps}"
)
+ set_property(TARGET "${target}" PROPERTY
+ _qt_target_deps "${target_deps}"
+ )
endif()
# When computing the private library dependencies, we need to check not only the known
@@ -1097,7 +1200,8 @@ function(extend_target target)
set(target_private "${target}Private")
if(TARGET "${target_private}")
- target_link_libraries("${target_private}" INTERFACE "${target}" "${qt_libs_private}")
+ target_link_libraries("${target_private}"
+ INTERFACE "${target}" ${arg_PRIVATE_MODULE_INTERFACE})
endif()
qt_register_target_dependencies("${target}"
"${arg_PUBLIC_LIBRARIES}"
@@ -1115,7 +1219,7 @@ function(extend_target target)
else()
if(QT_CMAKE_DEBUG_EXTEND_TARGET)
- message("extend_target(${target} CONDITION ${arg_CONDITION} ...): Skipped")
+ message("qt_extend_target(${target} CONDITION ${arg_CONDITION} ...): Skipped")
endif()
endif()
endfunction()
@@ -1125,17 +1229,25 @@ function(qt_internal_library_deprecation_level result)
if(WIN32)
# On Windows, due to the way DLLs work, we need to export all functions,
# including the inlines
- set("${result}" "QT_DISABLE_DEPRECATED_BEFORE=0x040800" PARENT_SCOPE)
+ list(APPEND deprecations "QT_DISABLE_DEPRECATED_BEFORE=0x040800")
else()
# On other platforms, Qt's own compilation goes needs to compile the Qt 5.0 API
- set("${result}" "QT_DISABLE_DEPRECATED_BEFORE=0x050000" PARENT_SCOPE)
+ list(APPEND deprecations "QT_DISABLE_DEPRECATED_BEFORE=0x050000")
endif()
- set("${result}" "QT_DEPRECATED_WARNINGS_SINCE=0x060000" PARENT_SCOPE)
+ list(APPEND deprecations "QT_DEPRECATED_WARNINGS_SINCE=0x060000")
+ set("${result}" deprecations PARENT_SCOPE)
endfunction()
-function(qt_install_injections module build_dir install_dir)
+function(qt_install_injections target build_dir install_dir)
set(injections ${ARGN})
+ set(module "Qt${target}")
+ get_target_property(target_type ${target} TYPE)
+ if (target_type STREQUAL "INTERFACE_LIBRARY")
+ set(is_framework FALSE)
+ else()
+ get_target_property(is_framework ${target} FRAMEWORK)
+ endif()
# examples:
# SYNCQT.INJECTIONS = src/corelib/global/qconfig.h:qconfig.h:QtConfig src/corelib/global/qconfig_p.h:5.12.0/QtCore/private/qconfig_p.h
# SYNCQT.INJECTIONS = src/gui/vulkan/qvulkanfunctions.h:^qvulkanfunctions.h:QVulkanFunctions:QVulkanDeviceFunctions src/gui/vulkan/qvulkanfunctions_p.h:^5.12.0/QtGui/private/qvulkanfunctions_p.h
@@ -1191,14 +1303,24 @@ function(qt_install_injections module build_dir install_dir)
file(GENERATE OUTPUT "${lower_case_forwarding_header_path}/${original_file_name}"
CONTENT "${main_contents}")
- # Copy the actual injected (generated) header file (not the just created forwarding one)
- # to its install location when doing a prefix build. In an non-prefix build, the qt_install
- # will be a no-op.
- qt_path_join(install_destination
- ${install_dir} ${INSTALL_INCLUDEDIR} ${module} ${destinationdir})
- qt_install(FILES ${current_repo_build_dir}/${file}
- DESTINATION ${install_destination}
- RENAME ${destinationname} OPTIONAL)
+ if(is_framework)
+ if(file MATCHES "_p\\.h$")
+ set(header_type PRIVATE)
+ else()
+ set(header_type PUBLIC)
+ endif()
+ qt_copy_framework_headers(${target} ${header_type}
+ ${current_repo_build_dir}/${file})
+ else()
+ # Copy the actual injected (generated) header file (not the just created forwarding one)
+ # to its install location when doing a prefix build. In an non-prefix build, the qt_install
+ # will be a no-op.
+ qt_path_join(install_destination
+ ${install_dir} ${INSTALL_INCLUDEDIR} ${module} ${destinationdir})
+ qt_install(FILES ${current_repo_build_dir}/${file}
+ DESTINATION ${install_destination}
+ RENAME ${destinationname} OPTIONAL)
+ endif()
# Generate UpperCaseNamed forwarding headers (part 3).
foreach(fwd_hdr ${fwd_hdrs})
@@ -1211,11 +1333,17 @@ function(qt_install_injections module build_dir install_dir)
file(GENERATE OUTPUT "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}"
CONTENT "#include \"${destinationname}\"\n")
- # Install the forwarding header.
- qt_path_join(install_destination
- ${install_dir} ${upper_case_forwarding_header_path})
- qt_install(FILES "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}"
- DESTINATION ${install_destination} OPTIONAL)
+ if(is_framework)
+ # Copy the forwarding header to the framework's Headers directory.
+ qt_copy_framework_headers(${target} PUBLIC
+ "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}")
+ else()
+ # Install the forwarding header.
+ qt_path_join(install_destination
+ ${install_dir} ${upper_case_forwarding_header_path})
+ qt_install(FILES "${build_dir}/${upper_case_forwarding_header_path}/${fwd_hdr}"
+ DESTINATION ${install_destination} OPTIONAL)
+ endif()
endforeach()
endforeach()
endfunction()
@@ -1281,6 +1409,121 @@ function(qt_internal_set_no_exceptions_flags target)
endif()
endfunction()
+function(qt_skip_warnings_are_errors target)
+ get_target_property(target_type "${target}" TYPE)
+ if(target_type STREQUAL "INTERFACE_LIBRARY")
+ return()
+ endif()
+ set_target_properties("${target}" PROPERTIES QT_SKIP_WARNINGS_ARE_ERRORS ON)
+endfunction()
+
+function(qt_skip_warnings_are_errors_when_repo_unclean target)
+ if(QT_REPO_NOT_WARNINGS_CLEAN)
+ qt_skip_warnings_are_errors("${target}")
+ endif()
+endfunction()
+
+function(qt_get_sanitized_plugin_type plugin_type out_var)
+ # Used to handle some edge cases such as platforms/darwin
+ string(REGEX REPLACE "[-/]" "_" plugin_type "${plugin_type}")
+ set("${out_var}" "${plugin_type}" PARENT_SCOPE)
+endfunction()
+
+# Copy header files to QtXYZ.framework/Versions/6/Headers/
+# Use this function for header files that
+# - are not added as source files to the target
+# - are not marked as PUBLIC_HEADER
+# - or are private and supposed to end up in the 6.7.8/QtXYZ/private subdir.
+function(qt_copy_framework_headers target)
+ get_target_property(is_fw ${target} FRAMEWORK)
+ if(NOT "${is_fw}")
+ return()
+ endif()
+
+ set(options PUBLIC PRIVATE QPA)
+ set(oneValueArgs)
+ set(multiValueArgs)
+ cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ get_target_property(fw_version ${target} FRAMEWORK_VERSION)
+ get_target_property(fw_bundle_version ${target} MACOSX_FRAMEWORK_BUNDLE_VERSION)
+ get_target_property(fw_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
+ get_target_property(fw_name ${target} OUTPUT_NAME)
+ set(fw_headers_dir ${fw_dir}/${fw_name}.framework/Versions/${fw_version}/Headers/)
+ if(ARG_PRIVATE)
+ string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/private/")
+ elseif(ARG_QPA)
+ string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/qpa/")
+ endif()
+
+ set(out_files)
+ foreach(hdr IN LISTS ARG_UNPARSED_ARGUMENTS)
+ get_filename_component(in_file_path ${hdr} ABSOLUTE)
+ get_filename_component(in_file_name ${hdr} NAME)
+ set(out_file_path ${fw_headers_dir}${in_file_name})
+ add_custom_command(
+ OUTPUT ${out_file_path}
+ DEPENDS ${in_file_path}
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${fw_headers_dir}"
+ COMMAND ${CMAKE_COMMAND} -E copy "${in_file_path}" "${fw_headers_dir}")
+ list(APPEND out_files ${out_file_path})
+ endforeach()
+
+ get_target_property(fw_copied_headers ${target} QT_COPIED_FRAMEWORK_HEADERS)
+ if(NOT fw_copied_headers)
+ set(fw_copied_headers "")
+ endif()
+ list(APPEND fw_copied_headers ${out_files})
+ set_target_properties(${target} PROPERTIES QT_COPIED_FRAMEWORK_HEADERS "${fw_copied_headers}")
+endfunction()
+
+function(qt_finalize_framework_headers_copy target)
+ get_target_property(target_type ${target} TYPE)
+ if(${target_type} STREQUAL "INTERFACE_LIBRARY")
+ return()
+ endif()
+ get_target_property(is_fw ${target} FRAMEWORK)
+ if(NOT "${is_fw}")
+ return()
+ endif()
+ get_target_property(headers ${target} QT_COPIED_FRAMEWORK_HEADERS)
+ if(headers)
+ # Hack to create the "Headers" symlink in the framework:
+ # Create a fake header file and copy it into the framework by marking it as PUBLIC_HEADER.
+ # CMake now takes care of creating the symlink.
+ set(fake_header ${target}_fake_header.h)
+ qt_get_main_cmake_configuration(main_config)
+ file(GENERATE OUTPUT ${fake_header} CONTENT "// ignore this file\n"
+ CONDITION "$<CONFIG:${main_config}>")
+ string(PREPEND fake_header "${CMAKE_CURRENT_BINARY_DIR}/")
+ target_sources(${target} PRIVATE ${fake_header})
+ set_source_files_properties(${fake_header} PROPERTIES GENERATED ON)
+ set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER ${fake_header})
+
+ # Add a target, e.g. Core_framework_headers, that triggers the header copy.
+ add_custom_target(${target}_framework_headers DEPENDS ${headers})
+ add_dependencies(${target} ${target}_framework_headers)
+ endif()
+endfunction()
+
+function(qt_clone_property_for_configs target property configs)
+ get_target_property(value "${target}" "${property}")
+ foreach(config ${configs})
+ string(TOUPPER "${config}" upper_config)
+ set_property(TARGET "${target}" PROPERTY "${property}_${upper_config}" "${value}")
+ endforeach()
+endfunction()
+
+function(qt_handle_multi_config_output_dirs target)
+ set(possible_configs "${CMAKE_BUILD_TYPE}")
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(possible_configs "${CMAKE_CONFIGURATION_TYPES}")
+ endif()
+ qt_clone_property_for_configs(${target} LIBRARY_OUTPUT_DIRECTORY "${possible_configs}")
+ qt_clone_property_for_configs(${target} RUNTIME_OUTPUT_DIRECTORY "${possible_configs}")
+ qt_clone_property_for_configs(${target} ARCHIVE_OUTPUT_DIRECTORY "${possible_configs}")
+endfunction()
+
# This is the main entry function for creating a Qt module, that typically
# consists of a library, public header files, private header files and configurable
# features.
@@ -1291,14 +1534,14 @@ endfunction()
# this module are imported into the scope of the calling feature.
#
# Target is without leading "Qt". So e.g. the "QtCore" module has the target "Core".
-function(add_qt_module target)
+function(qt_add_module target)
qt_internal_module_info(module "${target}")
# Process arguments:
- qt_parse_all_arguments(arg "add_qt_module"
- "NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT;EXCEPTIONS;INTERNAL_MODULE;NO_SYNC_QT;NO_PRIVATE_MODULE;HEADER_MODULE"
+ qt_parse_all_arguments(arg "qt_add_module"
+ "NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT;EXCEPTIONS;INTERNAL_MODULE;NO_SYNC_QT;NO_PRIVATE_MODULE;HEADER_MODULE;GENERATE_METATYPES"
"CONFIG_MODULE_NAME;PRECOMPILED_HEADER"
- "${__default_private_args};${__default_public_args};QMAKE_MODULE_CONFIG;EXTRA_CMAKE_FILES;EXTRA_CMAKE_INCLUDES;NO_PCH_SOURCES" ${ARGN})
+ "${__default_private_args};${__default_public_args};${__default_private_module_args};QMAKE_MODULE_CONFIG;EXTRA_CMAKE_FILES;EXTRA_CMAKE_INCLUDES;NO_PCH_SOURCES" ${ARGN})
if(NOT DEFINED arg_CONFIG_MODULE_NAME)
set(arg_CONFIG_MODULE_NAME "${module_lower}")
@@ -1307,8 +1550,10 @@ function(add_qt_module target)
qt_internal_add_qt_repo_known_module("${target}")
### Define Targets:
+ set(is_interface_lib 0)
if(${arg_HEADER_MODULE})
add_library("${target}" INTERFACE)
+ set(is_interface_lib 1)
elseif(${arg_STATIC})
add_library("${target}" STATIC)
elseif(${QT_BUILD_SHARED_LIBS})
@@ -1317,10 +1562,23 @@ function(add_qt_module target)
add_library("${target}" STATIC)
endif()
+ set(is_framework 0)
+ if(QT_FEATURE_framework AND NOT ${arg_HEADER_MODULE} AND NOT ${arg_STATIC})
+ set(is_framework 1)
+ set_target_properties(${target} PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}
+ MACOSX_FRAMEWORK_IDENTIFIER org.qt-project.Qt${target}
+ MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
+ MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
+ )
+ endif()
+
if (ANDROID)
qt_android_apply_arch_suffix("${target}")
endif()
qt_internal_add_target_aliases("${target}")
+ qt_skip_warnings_are_errors_when_repo_unclean("${target}")
# Add _private target to link against the private headers:
if(NOT ${arg_NO_PRIVATE_MODULE})
@@ -1329,6 +1587,27 @@ function(add_qt_module target)
qt_internal_add_target_aliases("${target_private}")
endif()
+ if(NOT arg_HEADER_MODULE)
+ set_target_properties(${target} PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
+ RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR}
+ )
+ qt_handle_multi_config_output_dirs("${target}")
+
+ if(is_framework)
+ set_target_properties(${target} PROPERTIES
+ OUTPUT_NAME Qt${target}
+ )
+ else()
+ set_target_properties(${target} PROPERTIES
+ OUTPUT_NAME "${INSTALL_CMAKE_NAMESPACE}${target}"
+ )
+ endif()
+ endif()
+
# Module headers:
if(${arg_NO_MODULE_HEADERS} OR ${arg_NO_SYNC_QT})
set_target_properties("${target}" PROPERTIES INTERFACE_MODULE_HAS_HEADERS OFF)
@@ -1351,41 +1630,52 @@ function(add_qt_module target)
### FIXME: Can we replace headers.pri?
qt_read_headers_pri("${target}" "module_headers")
- set_property(TARGET "${target}" APPEND PROPERTY PUBLIC_HEADER "${module_headers_public}")
- set_property(TARGET "${target}" APPEND PROPERTY PUBLIC_HEADER "${module_include_dir}/${module}Depends")
- set_property(TARGET "${target}" APPEND PROPERTY PRIVATE_HEADER "${module_headers_private}")
+ set(module_depends_header "${module_include_dir}/${module}Depends")
+ if(is_framework)
+ if(NOT is_interface_lib)
+ set(public_headers_to_copy "${module_headers_public}" "${module_depends_header}")
+ qt_copy_framework_headers(${target} PUBLIC "${public_headers_to_copy}")
+ qt_copy_framework_headers(${target} PRIVATE "${module_headers_private}")
+ endif()
+ else()
+ set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER "${module_headers_public}")
+ set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER ${module_depends_header})
+ set_property(TARGET ${target} APPEND PROPERTY PRIVATE_HEADER "${module_headers_private}")
+ endif()
if (NOT ${arg_HEADER_MODULE})
set_property(TARGET "${target}" PROPERTY MODULE_HEADER "${module_include_dir}/${module}")
endif()
if(module_headers_qpa)
- qt_install(FILES ${module_headers_qpa} DESTINATION ${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}/${module}/qpa)
+ if(is_framework)
+ qt_copy_framework_headers(${target} QPA "${module_headers_qpa}")
+ else()
+ qt_install(
+ FILES ${module_headers_qpa}
+ DESTINATION ${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}/${module}/qpa)
+ endif()
endif()
endif()
if(NOT arg_HEADER_MODULE)
+ # This property is used for super builds with static libraries. We use
+ # it in QtPlugins.cmake.in to avoid "polluting" the dependency chain
+ # for the target in it's project directory.
+ # E.g: When we process find_package(Qt6 ... Gui) in QtDeclarative, the
+ # rules in QtPugins.cmake add all the known Gui plugins as interface
+ # dependencies. This in turn causes circular dependencies on every
+ # plugin which links against Gui. Plugin A -> GUI -> Plugin A ....
+
+ set_target_properties(${target} PROPERTIES QT_BUILD_PROJECT_NAME ${PROJECT_NAME})
# Plugin types associated to a module
if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x")
# Reset the variable containing the list of plugins for the given plugin type
foreach(plugin_type ${arg_PLUGIN_TYPES})
- # Used to handle some edge cases such as platforms/darwin
- string(REGEX REPLACE "[-/]" "_" plugin_type "${plugin_type}")
-
+ qt_get_sanitized_plugin_type("${plugin_type}" plugin_type)
set_property(TARGET "${target}" APPEND PROPERTY MODULE_PLUGIN_TYPES "${plugin_type}")
qt_internal_add_qt_repo_known_plugin_types("${plugin_type}")
endforeach()
endif()
-
- set_target_properties("${target}" PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
- RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
- RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
- RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
- ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
- VERSION ${PROJECT_VERSION}
- SOVERSION ${PROJECT_VERSION_MAJOR}
- OUTPUT_NAME "${INSTALL_CMAKE_NAMESPACE}${target}"
- )
endif()
qt_internal_library_deprecation_level(deprecation_define)
@@ -1401,15 +1691,37 @@ function(add_qt_module target)
)
set(public_includes "")
+ set(public_headers_list "public_includes")
+ if(is_framework)
+ set(public_headers_list "private_includes")
+ set(fw_bundle_subdir "${INSTALL_LIBDIR}/Qt${target}.framework")
+ set(fw_headers_subdir "Versions/${PROJECT_VERSION_MAJOR}/Headers")
+ list(APPEND public_includes
+ # Add the lib/Foo.framework dir as include path to let CMake generate
+ # the -F compiler flag.
+ "$<BUILD_INTERFACE:${QT_BUILD_DIR}/${fw_bundle_subdir}>"
+ "$<INSTALL_INTERFACE:${fw_bundle_subdir}>"
+
+ # Add the fully resolved Headers subdir, because the Headers symlink might
+ # not be there yet.
+ "$<BUILD_INTERFACE:${QT_BUILD_DIR}/${fw_bundle_subdir}/${fw_headers_subdir}>"
+
+ # After installing, the Headers symlink is guaranteed to exist.
+ "$<INSTALL_INTERFACE:${fw_bundle_subdir}/Headers>"
+ )
+ endif()
# Handle cases like QmlDevTools which do not have their own headers, but rather borrow them
# from another module.
if(NOT arg_NO_SYNC_QT AND NOT arg_NO_MODULE_HEADERS)
- list(APPEND private_includes
- "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}>"
- "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}/${module}>")
+ # Don't include private headers unless they exist, aka syncqt created them.
+ if(module_headers_private)
+ list(APPEND private_includes
+ "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}>"
+ "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}/${module}>")
+ endif()
- list(APPEND public_includes
+ list(APPEND ${public_headers_list}
# For the syncqt headers
"$<BUILD_INTERFACE:${module_repo_include_dir}>"
"$<BUILD_INTERFACE:${module_include_dir}>")
@@ -1417,16 +1729,16 @@ function(add_qt_module target)
if(NOT arg_NO_MODULE_HEADERS AND NOT arg_NO_SYNC_QT)
# For the syncqt headers
- list(APPEND public_includes "$<INSTALL_INTERFACE:include/${module}>")
+ list(APPEND ${public_headers_list} "$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${module}>")
endif()
- list(APPEND public_includes ${arg_PUBLIC_INCLUDE_DIRECTORIES})
+ list(APPEND ${public_headers_list} ${arg_PUBLIC_INCLUDE_DIRECTORIES})
set(header_module)
if(arg_HEADER_MODULE)
set(header_module "HEADER_MODULE")
endif()
- extend_target("${target}"
+ qt_extend_target("${target}"
${header_module}
SOURCES ${arg_SOURCES}
INCLUDE_DIRECTORIES
@@ -1447,6 +1759,7 @@ function(add_qt_module target)
"${deprecation_define}"
PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES}
LIBRARIES ${arg_LIBRARIES} Qt::PlatformModuleInternal
+ PRIVATE_MODULE_INTERFACE ${arg_PRIVATE_MODULE_INTERFACE}
FEATURE_DEPENDENCIES ${arg_FEATURE_DEPENDENCIES}
DBUS_ADAPTOR_SOURCES ${arg_DBUS_ADAPTOR_SOURCES}
DBUS_ADAPTOR_FLAGS ${arg_DBUS_ADAPTOR_FLAGS}
@@ -1483,10 +1796,12 @@ function(add_qt_module target)
set_property(TARGET "${target}" APPEND PROPERTY PRIVATE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/qt${arg_CONFIG_MODULE_NAME}-config_p.h")
endif()
- if(DEFINED module_headers_private)
- qt_internal_add_linker_version_script("${target}" PRIVATE_HEADERS ${module_headers_private} ${module_headers_qpa})
- else()
- qt_internal_add_linker_version_script("${target}")
+ if(NOT arg_HEADER_MODULE)
+ if(DEFINED module_headers_private)
+ qt_internal_add_linker_version_script("${target}" PRIVATE_HEADERS ${module_headers_private} ${module_headers_qpa})
+ else()
+ qt_internal_add_linker_version_script("${target}")
+ endif()
endif()
# Handle injections. Aka create forwarding headers for certain headers that have been
@@ -1503,7 +1818,7 @@ function(add_qt_module target)
endif()
if(final_injections)
- qt_install_injections("${module}" "${QT_BUILD_DIR}" "${QT_INSTALL_DIR}" ${final_injections})
+ qt_install_injections(${target} "${QT_BUILD_DIR}" "${QT_INSTALL_DIR}" ${final_injections})
endif()
# Handle creation of cmake files for consumers of find_package().
@@ -1542,11 +1857,32 @@ function(add_qt_module target)
set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
endif()
+ # Generate metatypes
+ set(QT_MODULE_HAS_META_TYPES_FILE FALSE)
+ if (${arg_GENERATE_METATYPES})
+ set(QT_MODULE_HAS_META_TYPES_FILE TRUE)
+ set(metatypes_install_dir ${INSTALL_LIBDIR}/metatypes)
+ set(args)
+ if (NOT QT_WILL_INSTALL)
+ set(args COPY_OVER_INSTALL INSTALL_DIR "${QT_BUILD_DIR}/${metatypes_install_dir}")
+ else()
+ set(args INSTALL_DIR "${metatypes_install_dir}")
+ endif()
+ qt6_generate_meta_types_json_file(${target} ${args})
+ endif()
configure_package_config_file(
"${QT_CMAKE_DIR}/QtModuleConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
INSTALL_DESTINATION "${config_install_dir}"
)
+
+ if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake")
+ configure_file("${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake"
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake"
+ @ONLY)
+ list(APPEND extra_cmake_files "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake")
+ endif()
+
write_basic_package_version_file(
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
@@ -1571,11 +1907,12 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
RUNTIME DESTINATION ${INSTALL_BINDIR}
LIBRARY DESTINATION ${INSTALL_LIBDIR}
ARCHIVE DESTINATION ${INSTALL_LIBDIR}
+ FRAMEWORK DESTINATION ${INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${INSTALL_INCLUDEDIR}/${module}
PRIVATE_HEADER DESTINATION ${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}/${module}/private
)
- if (ANDROID)
+ if (ANDROID AND NOT arg_HEADER_MODULE)
# Record install library location so it can be accessed by
# qt_android_dependencies without having to specify it again.
set_target_properties(${target} PROPERTIES
@@ -1597,14 +1934,14 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
unset(arg_INTERNAL_MODULE)
endif()
- qt_path_join(pri_target_path ${PROJECT_BINARY_DIR} mkspecs/modules)
+ qt_path_join(pri_target_path ${PROJECT_BINARY_DIR} ${INSTALL_MKSPECSDIR}/modules)
qt_generate_module_pri_file("${target}" "${pri_target_path}" module_pri_files
${arg_INTERNAL_MODULE}
${header_module}
QMAKE_MODULE_CONFIG
${arg_QMAKE_MODULE_CONFIG}
)
- qt_install(FILES "${module_pri_files}" DESTINATION mkspecs/modules)
+ qt_install(FILES "${module_pri_files}" DESTINATION ${INSTALL_MKSPECSDIR}/modules)
### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
# that belong to Qt.
@@ -1617,21 +1954,37 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
# Handle cases like QmlDevTools which do not have their own headers, but rather borrow them
# from another module.
if(NOT arg_NO_SYNC_QT)
- list(APPEND interface_includes
- "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
- "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}>"
- "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}/${module}>")
+ list(APPEND interface_includes "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
if(NOT arg_NO_MODULE_HEADERS)
list(APPEND interface_includes
- "$<INSTALL_INTERFACE:include/${module}/${PROJECT_VERSION}>"
- "$<INSTALL_INTERFACE:include/${module}/${PROJECT_VERSION}/${module}>")
+ "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}>"
+ "$<BUILD_INTERFACE:${module_include_dir}/${PROJECT_VERSION}/${module}>")
+
+ if(is_framework)
+ set(fw_headers_dir
+ "${INSTALL_LIBDIR}/${module}.framework/Headers/")
+ list(APPEND interface_includes
+ "$<INSTALL_INTERFACE:${fw_headers_dir}${PROJECT_VERSION}>"
+ "$<INSTALL_INTERFACE:${fw_headers_dir}${PROJECT_VERSION}/${module}>")
+ else()
+ list(APPEND interface_includes
+ "$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}>"
+ "$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}/${module}/${PROJECT_VERSION}/${module}>")
+ endif()
endif()
endif()
if(NOT ${arg_NO_PRIVATE_MODULE})
target_include_directories("${target_private}" INTERFACE ${interface_includes})
endif()
+
+ if(is_framework AND NOT is_interface_lib)
+ qt_finalize_framework_headers_copy(${target})
+ endif()
+
+ qt_describe_module(${target})
+
endfunction()
function(qt_export_tools module_name)
@@ -1654,7 +2007,19 @@ function(qt_export_tools module_name)
# Also assemble a list of tool targets to expose in the config file for informational purposes.
set(extra_cmake_statements "")
set(tool_targets "")
+ set(tool_targets_non_prefixed "")
+
+ # List of package dependencies that need be find_package'd when using the Tools package.
+ set(package_deps "")
+
foreach(tool_name ${QT_KNOWN_MODULE_${module_name}_TOOLS})
+ # Specific tools can have package dependencies.
+ # e.g. qtwaylandscanner depends on WaylandScanner (non-qt package).
+ get_target_property(extra_packages "${tool_name}" QT_EXTRA_PACKAGE_DEPENDENCIES)
+ if(extra_packages)
+ list(APPEND package_deps "${extra_packages}")
+ endif()
+
set(extra_cmake_statements "${extra_cmake_statements}
if (NOT QT_NO_CREATE_TARGETS)
get_property(is_global TARGET ${INSTALL_CMAKE_NAMESPACE}::${tool_name} PROPERTY IMPORTED_GLOBAL)
@@ -1664,11 +2029,37 @@ if (NOT QT_NO_CREATE_TARGETS)
endif()
")
list(APPEND tool_targets "${QT_CMAKE_EXPORT_NAMESPACE}::${tool_name}")
+ list(APPEND tool_targets_non_prefixed "${tool_name}")
endforeach()
string(APPEND extra_cmake_statements
"set(${QT_CMAKE_EXPORT_NAMESPACE}${module_name}Tools_TARGETS \"${tool_targets}\")")
+ # Extract package dependencies that were determined in QtPostProcess, but only if ${module_name}
+ # is an actual target.
+ # module_name can be a non-existent target, if the tool doesn't have an existing associated
+ # module, e.g. qtwaylandscanner.
+ if(TARGET "${module_name}")
+ get_target_property(module_package_deps "${module_name}" _qt_tools_package_deps)
+ if(module_package_deps)
+ list(APPEND package_deps "${module_package_deps}")
+ endif()
+ endif()
+
+ # Configure and install dependencies file for the ${module_name}Tools package.
+ configure_file(
+ "${QT_CMAKE_DIR}/QtModuleToolsDependencies.cmake.in"
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake"
+ @ONLY
+ )
+
+ qt_install(FILES
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake"
+ DESTINATION "${config_install_dir}"
+ COMPONENT Devel
+ )
+
+ # Configure and install the ${module_name}Tools package Config file.
configure_package_config_file(
"${QT_CMAKE_DIR}/QtModuleToolsConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
@@ -1692,17 +2083,57 @@ endif()
NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::"
DESTINATION "${config_install_dir}")
- # Temporarily disable creation of versionless targets for tools,
- # because it breaks qtdeclarative build.
- #qt_internal_export_modern_cmake_config_targets_file(TARGETS ${QT_KNOWN_MODULE_${module_name}_TOOLS}
- # EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
- # CONFIG_INSTALL_DIR ${config_install_dir})
+
+ # Create versionless targets file.
+ configure_file(
+ "${QT_CMAKE_DIR}/QtModuleToolsVersionlessTargets.cmake.in"
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake"
+ @ONLY
+ )
+
+ qt_install(FILES
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}VersionlessTargets.cmake"
+ DESTINATION "${config_install_dir}"
+ COMPONENT Devel
+ )
+endfunction()
+
+# This function records a dependency between ${target_name} and ${dep_package_name}.
+# at the CMake package level.
+# E.g. The Tools package that provides the qtwaylandscanner target
+# needs to call find_package(WaylandScanner) (non-qt-package).
+# main_target_name = qtwaylandscanner
+# dep_package_name = WaylandScanner
+function(qt_record_extra_package_dependency main_target_name dep_package_name dep_package_version)
+ get_target_property(extra_packages "${main_target_name}" QT_EXTRA_PACKAGE_DEPENDENCIES)
+ if(NOT extra_packages)
+ set(extra_packages "")
+ endif()
+
+ list(APPEND extra_packages "${dep_package_name}\;${dep_package_version}")
+ set_target_properties("${main_target_name}" PROPERTIES QT_EXTRA_PACKAGE_DEPENDENCIES
+ "${extra_packages}")
+endfunction()
+
+# This function records a dependency between ${main_target_name} and ${dep_target_name}
+# at the CMake package level.
+# E.g. Qt6CoreConfig.cmake needs to find_package(Qt6WinMain).
+# main_target_name = Core
+# dep_target_name = WinMain
+# This is just a convenience function that deals with Qt targets and their associated packages
+# instead of raw package names.
+function(qt_record_extra_qt_package_dependency main_target_name dep_target_name
+ dep_package_version)
+ # WinMain -> Qt6WinMain.
+ qt_internal_module_info(qtfied_target_name "${dep_target_name}")
+ qt_record_extra_package_dependency("${main_target_name}" "${qtfied_target_name_versioned}"
+ "${dep_package_version}")
endfunction()
function(qt_internal_check_directory_or_type name dir type default result_var)
if ("x${dir}" STREQUAL x)
if("x${type}" STREQUAL x)
- message(FATAL_ERROR "add_qt_plugin called without setting either TYPE or ${name}.")
+ message(FATAL_ERROR "qt_add_plugin called without setting either TYPE or ${name}.")
endif()
set(${result_var} "${default}" PARENT_SCOPE)
else()
@@ -1714,6 +2145,8 @@ endfunction()
# This will set the QT_MODULE target property on the plug-in - e.g. "Gui", "Sql"...
function(qt_get_module_for_plugin target target_type)
qt_internal_get_qt_all_known_modules(known_modules)
+
+ qt_get_sanitized_plugin_type("${target_type}" target_type)
foreach(qt_module ${known_modules})
get_target_property(module_type "${QT_CMAKE_EXPORT_NAMESPACE}::${qt_module}" TYPE)
# Assuming interface libraries can't have plugins. Otherwise we'll need to fix the property
@@ -1738,32 +2171,34 @@ function(qt_get_module_for_plugin target target_type)
endfunction()
-# Collection of add_qt_plugin arguments so they can be shared across different
+# Collection of qt_add_plugin arguments so they can be shared across different
# plugin type wrappers
-set(__add_qt_plugin_optional_args
- "STATIC;EXCEPTIONS"
+set(__qt_add_plugin_optional_args
+ "STATIC;EXCEPTIONS;ALLOW_UNDEFINED_SYMBOLS"
)
-set(__add_qt_plugin_single_args
- "TYPE;CLASS_NAME;OUTPUT_DIRECTORY;INSTALL_DIRECTORY;ARCHIVE_INSTALL_DIRECTORY;QML_TARGET_PATH"
+set(__qt_add_plugin_single_args
+ "TYPE;CLASS_NAME;OUTPUT_DIRECTORY;INSTALL_DIRECTORY;ARCHIVE_INSTALL_DIRECTORY;QML_TARGET_PATH;OUTPUT_NAME"
)
-set(__add_qt_plugin_multi_args
+set(__qt_add_plugin_multi_args
"${__default_private_args};${__default_public_args};DEFAULT_IF"
)
# This is the main entry point for defining Qt plugins.
# A CMake target is created with the given target. The TYPE parameter is needed to place the
# plugin into the correct plugins/ sub-directory.
-function(add_qt_plugin target)
+function(qt_add_plugin target)
qt_internal_module_info(module "${target}")
qt_internal_set_qt_known_plugins("${QT_KNOWN_PLUGINS}" "${target}")
- qt_parse_all_arguments(arg "add_qt_plugin"
- "${__add_qt_plugin_optional_args};SKIP_INSTALL"
- "${__add_qt_plugin_single_args}"
- "${__add_qt_plugin_multi_args}"
+ qt_parse_all_arguments(arg "qt_add_plugin"
+ "${__qt_add_plugin_optional_args};SKIP_INSTALL"
+ "${__qt_add_plugin_single_args}"
+ "${__qt_add_plugin_multi_args}"
"${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}")
@@ -1775,8 +2210,11 @@ function(add_qt_plugin target)
set(archive_install_directory_default "${INSTALL_QMLDIR}/${target_path}")
endif()
- if ("x${arg_CLASS_NAME}" STREQUAL "x" AND NOT "${arg_TYPE}" STREQUAL "qml_plugin")
- message(AUTHOR_WARNING "add_qt_plugin called without setting CLASS_NAME.")
+ # Derive the class name from the target name if it's not explicitly specified.
+ # Don't set it for qml plugins though.
+ set(plugin_class_name "")
+ if (NOT arg_CLASS_NAME AND NOT "${arg_TYPE}" STREQUAL "qml_plugin")
+ set(plugin_class_name "${target}")
endif()
qt_internal_check_directory_or_type(OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" "${arg_TYPE}"
@@ -1800,16 +2238,40 @@ function(add_qt_plugin target)
endif()
endif()
+ # Make sure the Qt6 plugin library names are like they were in Qt5 qmake land.
+ # Whereas the Qt6 CMake target names are like the Qt5 CMake target names.
+ set(output_name "${target}")
+ if(arg_OUTPUT_NAME)
+ set(output_name "${arg_OUTPUT_NAME}")
+ endif()
+ set_property(TARGET "${target}" PROPERTY OUTPUT_NAME "${output_name}")
+
+ # Add a custom target with the Qt5 qmake name for a more user friendly ninja experience.
+ if(arg_OUTPUT_NAME AND NOT TARGET "${output_name}")
+ add_custom_target("${output_name}")
+ add_dependencies("${output_name}" "${target}")
+ endif()
+
if (ANDROID)
qt_android_apply_arch_suffix("${target}")
+ set_target_properties(${target}
+ PROPERTIES
+ LIBRARY_OUTPUT_NAME "plugins_${arg_TYPE}_${output_name}"
+ )
endif()
qt_internal_add_target_aliases("${target}")
+ qt_skip_warnings_are_errors_when_repo_unclean("${target}")
+
+ # Disable linking of plugins against other plugins during static regular and
+ # super builds. The latter causes cyclic dependencies otherwise.
+ set_target_properties(${target} PROPERTIES QT_DEFAULT_PLUGINS 0)
set_target_properties("${target}" PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${output_directory}"
RUNTIME_OUTPUT_DIRECTORY "${output_directory}"
ARCHIVE_OUTPUT_DIRECTORY "${output_directory}"
- QT_PLUGIN_CLASS_NAME "${arg_CLASS_NAME}")
+ QT_PLUGIN_CLASS_NAME "${plugin_class_name}")
+ qt_handle_multi_config_output_dirs("${target}")
qt_internal_library_deprecation_level(deprecation_define)
@@ -1853,7 +2315,7 @@ function(add_qt_plugin target)
${arg_PUBLIC_INCLUDE_DIRECTORIES}
)
- extend_target("${target}"
+ qt_extend_target("${target}"
SOURCES ${arg_SOURCES}
INCLUDE_DIRECTORIES
${private_includes}
@@ -1930,7 +2392,7 @@ function(add_qt_plugin target)
)
# Make the export name of plugins be consistent with modules, so that
- # add_qt_resource adds its additional targets to the same export set in a static Qt build.
+ # qt_add_resource adds its additional targets to the same export set in a static Qt build.
set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
qt_install(TARGETS "${target}"
EXPORT ${export_name}
@@ -1947,80 +2409,13 @@ function(add_qt_plugin target)
# Store the plug-in type in the target property
set_property(TARGET "${target}" PROPERTY QT_PLUGIN_TYPE "${arg_TYPE}")
- ### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
- # that belong to Qt.
- qt_internal_add_link_flags_no_undefined("${target}")
-
- qt_internal_add_linker_version_script(${target})
-endfunction()
-
-# Generate custom ${target}_qmltypes target for Qml Plugins
-function(qt_add_qmltypes_target target)
-
- # Do nothing when cross compiling
- if (CMAKE_CROSSCOMPILING)
- return()
- endif()
-
- # Do nothing during a Qt static build (because the tool isn't built in that case).
- if (NOT QT_BUILD_SHARED_LIBS)
- return()
- endif()
-
- qt_parse_all_arguments(arg "qt_generate_qmltypes"
- ""
- "TARGET_PATH;IMPORT_VERSION;IMPORT_NAME;QML_PLUGINDUMP_DEPENDENCIES"
- ""
- ${ARGN})
-
- # scan repos for qml repositories
- foreach(repo IN LISTS QT_REPOS)
- if (IS_DIRECTORY "${repo}/qml")
- list(APPEND import_paths "${repo}/qml")
- endif()
- endforeach()
- list(REMOVE_DUPLICATES import_paths)
- if (UNIX)
- list(JOIN import_paths ":" import_paths_env)
- else()
- list(JOIN import_paths "\;" import_paths_env)
- endif()
-
- if(NOT arg_IMPORT_NAME)
- string(REGEX REPLACE "\\.\\d+$" "" import_name ${arg_TARGET_PATH})
- else()
- set(import_name ${arg_IMPORT_NAME})
- endif()
-
- if(NOT arg_IMPORT_VERSION)
- message(FATAL_ERROR "Import version parameter was not specified. Specify the import version using the IMPORT_VERSION.")
- endif()
-
- get_target_property(source_dir ${target} SOURCE_DIR)
-
- # qml1_target check is no longer required
- set(qmltypes_command_args "-nonrelocatable")
- if (NOT arg_QML_PLUGINDUMP_DEPENDENCIES AND EXISTS "${source_dir}/dependencies.json")
- list(APPEND qmltypes_command_args "-dependencies" "${source_dir}/dependencies.json")
- elseif(arg_QML_PLUGINDUMP_DEPENDENCIES)
- list(APPEND qmltypes_command_args "-dependencies" "${arg_QML_PLUGINDUMP_DEPENDENCIES}")
+ if (NOT arg_ALLOW_UNDEFINED_SYMBOLS)
+ ### fixme: cmake is missing a built-in variable for this. We want to apply it only to
+ # modules and plugins that belong to Qt.
+ qt_internal_add_link_flags_no_undefined("${target}")
endif()
- string(REPLACE "/" "." import_name_arg ${import_name})
-
- list(APPEND qmltypes_command_args "${import_name_arg}" "${arg_IMPORT_VERSION}")
-
- set(qml_plugindump_target ${QT_CMAKE_EXPORT_NAMESPACE}::qmlplugindump)
-
- # Manually set dependency on plugindump target since CMake will not add
- # this rule because it's not the main executable argument to the COMMAND
- # parameter.
- add_custom_target(
- "${target}_qmltypes"
- DEPENDS ${qml_plugindump_target}
- COMMAND ${CMAKE_COMMAND} -E env "QML2_IMPORTPATH=${import_paths_env}"
- $<TARGET_FILE:${qml_plugindump_target}> ${qmltypes_command_args} > "${source_dir}/plugins.qmltypes"
- )
+ qt_internal_add_linker_version_script(${target})
endfunction()
function(qt_install_qml_files target)
@@ -2046,7 +2441,7 @@ function(qt_install_qml_files target)
endfunction()
-function(add_qt_resource target resourceName)
+function(qt_add_resource target resourceName)
# Don't try to add resources when cross compiling, and the target is actually a host target
# (like a tool).
qt_is_imported_target("${target}" is_imported)
@@ -2054,7 +2449,7 @@ function(add_qt_resource target resourceName)
return()
endif()
- qt_parse_all_arguments(arg "add_qt_resource" "" "PREFIX;LANG;BASE" "FILES" ${ARGN})
+ qt_parse_all_arguments(arg "qt_add_resource" "" "PREFIX;LANG;BASE" "FILES" ${ARGN})
QT6_PROCESS_RESOURCE(${target} ${resourceName}
PREFIX "${arg_PREFIX}"
@@ -2073,198 +2468,56 @@ function(add_qt_resource target resourceName)
endfunction()
-
-# This function creates a CMake target for qml modules. It will also make
-# sure that if no C++ source are present, that qml files show up in the project
-# in an IDE. Finally, it will also create a custom ${target}_qmltypes which
-# can be used to generate the respective plugin.qmltypes file.
-#
-# CPP_PLUGIN: Whether this qml module has any c++ source files.
-# URI: Module's uri.
-# TARGET_PATH: Expected installation path for the Qml Module. Equivalent
-# to the module's URI where '.' is replaced with '/'. Use this to override the
-# default substitution pattern.
-# VERSION: Version of the qml module
-# QML_PLUGINDUMP_DEPENDENCIES: Path to a dependencies.json file to be consumed
-# with the ${target}_qmltypes target (optional)
-# SKIP_TYPE_REGISTRATION: All qml files are expected to be registered by the
-# c++ plugin code.
-#
-function(add_qml_module target)
-
- set(qml_module_optional_args
- DESIGNER_SUPPORTED
- DO_NOT_INSTALL
- SKIP_TYPE_REGISTRATION
- )
-
- set(qml_module_single_args
- URI
- TARGET_PATH
- VERSION
- QML_PLUGINDUMP_DEPENDENCIES
- CLASSNAME
- )
-
- set(qml_module_multi_args
- IMPORTS
- TYPEINFO
- DEPENDENCIES
- )
-
- qt_parse_all_arguments(arg "add_qml_module"
- "${__add_qt_plugin_optional_args};${qml_module_optional_args}"
- "${__add_qt_plugin_single_args};${qml_module_single_args}"
- "${__add_qt_plugin_multi_args};${qml_module_multi_args}" ${ARGN})
-
- if (NOT arg_URI)
- message(FATAL_ERROR "add_qml_module called without specifying the module's uri. Please specify one using the URI parameter.")
- endif()
-
- set(target_path ${arg_TARGET_PATH})
-
- if (NOT arg_VERSION)
- message(FATAL_ERROR "add_qml_module called without specifying the module's import version. Please specify one using the VERSION parameter.")
- endif()
-
- if (NOT arg_TARGET_PATH)
- string(REPLACE "." "/" arg_TARGET_PATH ${arg_URI})
- endif()
-
- qt_remove_args(plugin_args
- ARGS_TO_REMOVE
- ${target}
- ${qml_module_multi_args}
- ${qml_module_single_args}
- ALL_ARGS
- ${__add_qt_plugin_optional_args}
- ${__add_qt_plugin_single_args}
- ${qml_module_single_args}
- ${__add_qt_plugin_multi_args}
- ${qml_module_multi_args}
- ARGS
- ${ARGV}
- )
-
- # If we have no sources, but qml files, create a custom target so the
- # qml file will be visibile in an IDE.
- if (arg_SOURCES)
- add_qt_plugin(${target}
- TYPE
- qml_plugin
- QML_TARGET_PATH
- "${arg_TARGET_PATH}"
- ${plugin_args}
- )
- endif()
-
-
- if (arg_CPP_PLUGIN)
- set(no_create_option DO_NOT_CREATE_TARGET)
- endif()
-
- if (arg_CLASSNAME)
- set(classname_arg CLASSNAME ${arg_CLASSNAME})
- endif()
-
- if (arg_DESIGNER_SUPPORTED)
- set(designer_supported_arg DESIGNER_SUPPORTED)
- endif()
-
- if (arg_SKIP_TYPE_REGISTRATION)
- set(skip_registration_arg SKIP_TYPE_REGISTRATION)
- endif()
-
- qt6_add_qml_module(${target}
- ${designer_supported_arg}
- ${no_create_option}
- ${skip_registration_arg}
- ${classname_arg}
- RESOURCE_PREFIX "/qt-project.org/imports"
- TARGET_PATH ${arg_TARGET_PATH}
- URI ${arg_URI}
- VERSION ${arg_VERSION}
- QML_FILES ${arg_QML_FILES}
- IMPORTS "${arg_IMPORTS}"
- TYPEINFO "${arg_TYPEINFO}"
- DO_NOT_INSTALL_METADATA
- DO_NOT_CREATE_TARGET
- INSTALL_QML_FILES
- DEPENDENCIES ${arg_DEPENDENCIES}
- RESOURCE_EXPORT "${INSTALL_CMAKE_NAMESPACE}${target}Targets"
- )
-
- get_target_property(qmldir_file ${target} QT_QML_MODULE_QMLDIR_FILE)
- qt_path_join(qml_module_install_dir ${QT_INSTALL_DIR} "${INSTALL_QMLDIR}/${arg_TARGET_PATH}")
- set(plugin_types "${CMAKE_CURRENT_SOURCE_DIR}/plugins.qmltypes")
- if (EXISTS ${plugin_types})
- qt_copy_or_install(FILES ${plugin_types}
- DESTINATION "${qml_module_install_dir}"
- )
-
- if(QT_WILL_INSTALL)
- # plugin.qmltypes when present should also be copied to the
- # cmake binary dir when doing prefix builds
- file(COPY ${plugin_types}
- DESTINATION "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/${arg_TARGET_PATH}"
- )
- endif()
- endif()
-
-
- qt_copy_or_install(
- FILES
- "${qmldir_file}"
- DESTINATION
- "${qml_module_install_dir}"
- )
-
- if(QT_WILL_INSTALL)
- # qmldir should also be copied to the cmake binary dir when doing
- # prefix builds
- file(COPY "${qmldir_file}"
- DESTINATION "${QT_BUILD_DIR}/${INSTALL_QMLDIR}/${arg_TARGET_PATH}"
- )
- endif()
-
-endfunction()
-
-# Collection of add_qt_executable arguments so they can be shared across add_qt_executable
-# and add_qt_test_helper.
-set(__add_qt_executable_optional_args
+# Collection of qt_add_executable arguments so they can be shared across qt_add_executable
+# and qt_add_test_helper.
+set(__qt_add_executable_optional_args
"GUI;BOOTSTRAP;NO_QT;NO_INSTALL;EXCEPTIONS"
)
-set(__add_qt_executable_single_args
+set(__qt_add_executable_single_args
"OUTPUT_DIRECTORY;INSTALL_DIRECTORY"
)
-set(__add_qt_executable_multi_args
+set(__qt_add_executable_multi_args
"EXE_FLAGS;${__default_private_args};${__default_public_args}"
)
# This function creates a CMake target for a generic console or GUI binary.
# Please consider to use a more specific version target like the one created
-# by add_qt_test or add_qt_tool below.
-function(add_qt_executable name)
- qt_parse_all_arguments(arg "add_qt_executable"
- "${__add_qt_executable_optional_args}"
- "${__add_qt_executable_single_args}"
- "${__add_qt_executable_multi_args}"
+# by qt_add_test or qt_add_tool below.
+function(qt_add_executable name)
+ qt_parse_all_arguments(arg "qt_add_executable"
+ "${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
${ARGN})
if ("x${arg_OUTPUT_DIRECTORY}" STREQUAL "x")
- set(arg_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${INSTALL_BINDIR}")
+ set(arg_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}")
endif()
get_filename_component(arg_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}"
- ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
+ ABSOLUTE BASE_DIR "${QT_BUILD_DIR}")
if ("x${arg_INSTALL_DIRECTORY}" STREQUAL "x")
set(arg_INSTALL_DIRECTORY "${INSTALL_BINDIR}")
endif()
- add_executable("${name}" ${arg_EXE_FLAGS})
+ if (ANDROID)
+ add_library("${name}" MODULE)
+ qt_android_apply_arch_suffix("${name}")
+ qt_android_generate_deployment_settings("${name}")
+ qt_android_add_apk_target("${name}")
+ # On our qmake builds we don't compile the executables with
+ # visibility=hidden. Not having this flag set will cause the
+ # executable to have main() hidden and can then no longer be loaded
+ # through dlopen()
+ set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default)
+ set_property(TARGET ${name} PROPERTY CXX_VISIBILITY_PRESET default)
+ else()
+ add_executable("${name}" ${arg_EXE_FLAGS})
+ endif()
qt_autogen_tools_initial_setup(${name})
+ qt_skip_warnings_are_errors_when_repo_unclean("${name}")
set(extra_libraries "")
if(NOT arg_BOOTSTRAP AND NOT arg_NO_QT)
@@ -2277,7 +2530,7 @@ function(add_qt_executable name)
${arg_INCLUDE_DIRECTORIES}
)
- extend_target("${name}"
+ qt_extend_target("${name}"
SOURCES ${arg_SOURCES}
INCLUDE_DIRECTORIES ${private_includes}
DEFINES ${arg_DEFINES}
@@ -2295,6 +2548,7 @@ function(add_qt_executable name)
)
set_target_properties("${name}" PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}"
+ LIBRARY_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}"
WIN32_EXECUTABLE "${arg_GUI}"
MACOSX_BUNDLE "${arg_GUI}"
)
@@ -2306,16 +2560,85 @@ function(add_qt_executable name)
if(NOT arg_NO_INSTALL)
qt_install(TARGETS "${name}"
RUNTIME DESTINATION "${arg_INSTALL_DIRECTORY}"
+ LIBRARY DESTINATION "${arg_INSTALL_DIRECTORY}"
BUNDLE DESTINATION "${arg_INSTALL_DIRECTORY}")
endif()
endfunction()
+# Simple wrapper around qt_add_executable for benchmarks which insure that
+# the binary is built under ${CMAKE_CURRENT_BINARY_DIR} and never installed.
+# See qt_add_executable() for more details.
+function(qt_add_benchmark target)
+
+ qt_parse_all_arguments(arg "qt_add_benchmark"
+ "${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
+ ${ARGN}
+ )
+
+ qt_remove_args(exec_args
+ ARGS_TO_REMOVE
+ ${target}
+ OUTPUT_DIRECTORY
+ INSTALL_DIRECTORY
+ ALL_ARGS
+ "${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
+ ARGS
+ ${ARGV}
+ )
+
+ qt_add_executable(${target}
+ NO_INSTALL # we don't install benchmarks
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" # avoid polluting bin directory
+ ${exec_args}
+ )
+
+endfunction()
+
+# Simple wrapper around qt_add_executable for manual tests which insure that
+# the binary is built under ${CMAKE_CURRENT_BINARY_DIR} and never installed.
+# See qt_add_executable() for more details.
+function(qt_add_manual_test target)
+
+ qt_parse_all_arguments(arg "qt_add_manual_test"
+ "${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
+ ${ARGN}
+ )
+
+ qt_remove_args(exec_args
+ ARGS_TO_REMOVE
+ ${target}
+ OUTPUT_DIRECTORY
+ INSTALL_DIRECTORY
+ ALL_ARGS
+ "${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
+ ARGS
+ ${ARGV}
+ )
+
+ qt_add_executable(${target}
+ NO_INSTALL # we don't install benchmarks
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" # avoid polluting bin directory
+ ${exec_args}
+ )
+
+endfunction()
+
# This function creates a CMake test target with the specified name for use with CTest.
-function(add_qt_test name)
- qt_parse_all_arguments(arg "add_qt_test"
+function(qt_add_test name)
+ qt_parse_all_arguments(arg "qt_add_test"
"RUN_SERIAL;EXCEPTIONS;GUI;QMLTEST"
- "OUTPUT_DIRECTORY" "QML_IMPORTPATH;TESTDATA;${__default_private_args};${__default_public_args}" ${ARGN})
+ "OUTPUT_DIRECTORY;WORKING_DIRECTORY;TIMEOUT"
+ "QML_IMPORTPATH;TESTDATA;${__default_private_args};${__default_public_args}" ${ARGN}
+ )
if (NOT arg_OUTPUT_DIRECTORY)
set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
@@ -2334,11 +2657,11 @@ function(add_qt_test name)
set(private_includes
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}"
- "$<BUILD_INTERFACE:${QT_BUILD_DIR}/include>"
+ "$<BUILD_INTERFACE:${QT_BUILD_DIR}/${INSTALL_INCLUDEDIR}>"
${arg_INCLUDE_DIRECTORIES}
)
- add_qt_executable("${name}"
+ qt_add_executable("${name}"
${exceptions_text}
${gui_text}
NO_INSTALL
@@ -2369,16 +2692,16 @@ function(add_qt_test name)
# QMLTest specifics
- extend_target("${name}" CONDITION arg_QMLTEST
+ qt_extend_target("${name}" CONDITION arg_QMLTEST
PUBLIC_LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::QuickTest
)
- extend_target("${name}" CONDITION arg_QMLTEST AND NOT ANDROID
+ qt_extend_target("${name}" CONDITION arg_QMLTEST AND NOT ANDROID
DEFINES
QUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)
- extend_target("${name}" CONDITION arg_QMLTEST AND ANDROID
+ qt_extend_target("${name}" CONDITION arg_QMLTEST AND ANDROID
DEFINES
QUICK_TEST_SOURCE_DIR=":/"
)
@@ -2392,20 +2715,31 @@ function(add_qt_test name)
# and use it also for XML output
file(RELATIVE_PATH label "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
- if(arg_QMLTEST AND NOT arg_SOURCES)
- set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
- set(test_executable ${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner)
+ if (ANDROID)
+ qt_android_add_test("${name}")
else()
- set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
- set(test_executable "${name}")
- endif()
+ if(arg_QMLTEST AND NOT arg_SOURCES)
+ set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(test_executable ${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner)
+ else()
+ if (arg_WORKING_DIRECTORY)
+ set(test_working_dir "${arg_WORKING_DIRECTORY}")
+ else()
+ set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ set(test_executable "${name}")
+ endif()
- add_test(NAME "${name}" COMMAND ${test_executable} ${extra_test_args} -o ${name}.xml,xml -o -,txt WORKING_DIRECTORY "${test_working_dir}")
+ add_test(NAME "${name}" COMMAND ${test_executable} ${extra_test_args} -o ${name}.xml,xml -o -,txt WORKING_DIRECTORY "${test_working_dir}")
+ endif()
set_tests_properties("${name}" PROPERTIES RUN_SERIAL "${arg_RUN_SERIAL}" LABELS "${label}")
-
+ if (arg_TIMEOUT)
+ set_tests_properties(${name} PROPERTIES TIMEOUT ${arg_TIMEOUT})
+ endif()
# Get path to qtbase/bin, then prepend this path containing the shared libraries to PATH
- set(INSTALL_PREFIX_BIN "${CMAKE_INSTALL_PREFIX}/bin")
+ set(INSTALL_PREFIX_BIN "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "PATH=${CMAKE_CURRENT_BINARY_DIR}${QT_PATH_SEPARATOR}${INSTALL_PREFIX_BIN}${QT_PATH_SEPARATOR}$ENV{PATH}")
+ set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "QT_TEST_RUNNING_IN_CTEST=1")
# Add the install prefix to list of plugin paths when doing a prefix build
if(NOT QT_INSTALL_DIR)
@@ -2445,7 +2779,7 @@ function(add_qt_test name)
endforeach()
if (builtin_files)
- add_qt_resource(${name} "testdata"
+ qt_add_resource(${name} "${name}_testdata_builtin"
PREFIX "/"
FILES ${builtin_files}
BASE ${CMAKE_CURRENT_SOURCE_DIR})
@@ -2479,27 +2813,27 @@ endfunction()
# tests launch separate programs to test certain input/output behavior.
# Specify OVERRIDE_OUTPUT_DIRECTORY if you dont' want to place the helper in the parent directory,
# in which case you should specify OUTPUT_DIRECTORY "/foo/bar" manually.
-function(add_qt_test_helper name)
+function(qt_add_test_helper name)
- set(add_qt_test_helper_optional_args
+ set(qt_add_test_helper_optional_args
"OVERRIDE_OUTPUT_DIRECTORY"
)
- qt_parse_all_arguments(arg "add_qt_test_helper"
- "${add_qt_test_helper_optional_args};${__add_qt_executable_optional_args}"
- "${__add_qt_executable_single_args}"
- "${__add_qt_executable_multi_args}"
+ qt_parse_all_arguments(arg "qt_add_test_helper"
+ "${qt_add_test_helper_optional_args};${__qt_add_executable_optional_args}"
+ "${__qt_add_executable_single_args}"
+ "${__qt_add_executable_multi_args}"
${ARGN})
qt_remove_args(forward_args
ARGS_TO_REMOVE
"${name}"
- ${add_qt_test_helper_optional_args}
+ ${qt_add_test_helper_optional_args}
ALL_ARGS
- ${add_qt_test_helper_optional_args}
- ${__add_qt_executable_optional_args}
- ${__add_qt_executable_single_args}
- ${__add_qt_executable_multi_args}
+ ${qt_add_test_helper_optional_args}
+ ${__qt_add_executable_optional_args}
+ ${__qt_add_executable_single_args}
+ ${__qt_add_executable_multi_args}
ARGS
${ARGV}
)
@@ -2509,7 +2843,7 @@ function(add_qt_test_helper name)
set(extra_args_to_pass OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/..")
endif()
- add_qt_executable("${name}" NO_INSTALL ${extra_args_to_pass} ${forward_args})
+ qt_add_executable("${name}" NO_INSTALL ${extra_args_to_pass} ${forward_args})
endfunction()
# Sets QT_WILL_BUILD_TOOLS if tools will be built.
@@ -2524,9 +2858,9 @@ endfunction()
# Wrapper function to create a regular cmake target and forward all the
# arguments collected by the conversion script. This is only meant for tests!
-function(add_cmake_library target)
+function(qt_add_cmake_library target)
# Process arguments:
- qt_parse_all_arguments(arg "add_cmake_library"
+ qt_parse_all_arguments(arg "qt_add_cmake_library"
"SHARED;MODULE;STATIC;INTERFACE"
"OUTPUT_DIRECTORY;ARCHIVE_INSTALL_DIRECTORY;INSTALL_DIRECTORY"
"${__default_private_args};${__default_public_args}"
@@ -2536,10 +2870,20 @@ function(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)
+ elseif(${arg_MODULE})
+ add_library("${target}" MODULE)
+ set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default)
+ set_property(TARGET ${name} PROPERTY CXX_VISIBILITY_PRESET default)
+
+ if(APPLE)
+ # CMake defaults to using .so extensions for loadable modules, aka plugins,
+ # but Qt plugins are actually suffixed with .dylib.
+ set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
+ endif()
else()
add_library("${target}")
endif()
@@ -2551,6 +2895,7 @@ function(add_cmake_library target)
if (ANDROID)
qt_android_apply_arch_suffix("${target}")
endif()
+ qt_skip_warnings_are_errors_when_repo_unclean("${target}")
if (arg_INSTALL_DIRECTORY)
set(install_arguments
@@ -2567,7 +2912,7 @@ function(add_cmake_library target)
)
endif()
- extend_target("${target}"
+ qt_extend_target("${target}"
SOURCES ${arg_SOURCES}
INCLUDE_DIRECTORIES
${arg_INCLUDE_DIRECTORIES}
@@ -2591,11 +2936,162 @@ function(add_cmake_library target)
endfunction()
+#
+# This function replaces qmake's qt_helper_lib feature. It is intended to
+# compile 3rdparty libraries as part of the build.
+#
+function(qt_add_3rdparty_library target)
+ # Process arguments:
+ qt_parse_all_arguments(arg "qt_add_3rdparty_library"
+ "SHARED;MODULE;STATIC;INTERFACE;EXCEPTIONS"
+ "OUTPUT_DIRECTORY"
+ "${__default_private_args};${__default_public_args}"
+ ${ARGN}
+ )
+
+ ### Define Targets:
+ if(${arg_INTERFACE})
+ add_library("${target}" INTERFACE)
+ elseif(${arg_STATIC} OR (${arg_MODULE} AND NOT BUILD_SHARED_LIBS))
+ add_library("${target}" STATIC)
+ elseif(${arg_SHARED})
+ add_library("${target}" SHARED)
+ elseif(${arg_MODULE})
+ add_library("${target}" MODULE)
+ set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default)
+ set_property(TARGET ${name} PROPERTY CXX_VISIBILITY_PRESET default)
+
+ if(APPLE)
+ # CMake defaults to using .so extensions for loadable modules, aka plugins,
+ # but Qt plugins are actually suffixed with .dylib.
+ set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib")
+ endif()
+ else()
+ add_library("${target}")
+ endif()
+
+ if (NOT arg_ARCHIVE_INSTALL_DIRECTORY AND arg_INSTALL_DIRECTORY)
+ set(arg_ARCHIVE_INSTALL_DIRECTORY "${arg_INSTALL_DIRECTORY}")
+ endif()
+
+ qt_internal_add_qt_repo_known_module(${target})
+ qt_internal_add_target_aliases(${target})
+
+ if (ANDROID)
+ qt_android_apply_arch_suffix("${target}")
+ endif()
+
+ qt_skip_warnings_are_errors_when_repo_unclean("${target}")
+
+ if(NOT arg_HEADER_MODULE)
+ set_target_properties(${target} PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
+ RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR}
+ QT_MODULE_IS_3RDPARTY_LIBRARY TRUE
+ )
+ qt_handle_multi_config_output_dirs("${target}")
+
+ set_target_properties(${target} PROPERTIES
+ OUTPUT_NAME "${INSTALL_CMAKE_NAMESPACE}${target}"
+ )
+ endif()
+
+ if(NOT arg_INTERFACE)
+ # This property is used for super builds with static libraries. We use
+ # it in QtPlugins.cmake.in to avoid "polluting" the dependency chain
+ # for the target in it's project directory.
+ # E.g: When we process find_package(Qt6 ... Gui) in QtDeclarative, the
+ # rules in QtPugins.cmake add all the known Gui plugins as interface
+ # dependencies. This in turn causes circular dependencies on every
+ # plugin which links against Gui. Plugin A -> GUI -> Plugin A ....
+ set_target_properties(${target} PROPERTIES QT_BUILD_PROJECT_NAME ${PROJECT_NAME})
+ endif()
+
+ if(NOT arg_EXCEPTIONS AND NOT arg_INTERFACE)
+ qt_internal_set_no_exceptions_flags("${target}")
+ endif()
+
+ qt_extend_target("${target}"
+ SOURCES ${arg_SOURCES}
+ INCLUDE_DIRECTORIES
+ ${arg_INCLUDE_DIRECTORIES}
+ PUBLIC_INCLUDE_DIRECTORIES
+ ${arg_PUBLIC_INCLUDE_DIRECTORIES}
+ PUBLIC_DEFINES
+ ${arg_PUBLIC_DEFINES}
+ DEFINES
+ ${arg_DEFINES}
+ PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES}
+ LIBRARIES ${arg_LIBRARIES}
+ COMPILE_OPTIONS ${arg_COMPILE_OPTIONS}
+ PUBLIC_COMPILE_OPTIONS ${arg_PUBLIC_COMPILE_OPTIONS}
+ LINK_OPTIONS ${arg_LINK_OPTIONS}
+ PUBLIC_LINK_OPTIONS ${arg_PUBLIC_LINK_OPTIONS}
+ MOC_OPTIONS ${arg_MOC_OPTIONS}
+ ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS}
+ DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS}
+ ${install_arguments}
+ )
+
+ if(NOT BUILD_SHARED_LIBS OR arg_SHARED)
+ set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}")
+ qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
+ qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
+ set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
+
+ configure_package_config_file(
+ "${QT_CMAKE_DIR}/Qt3rdPartyLibraryConfig.cmake.in"
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
+ INSTALL_DESTINATION "${config_install_dir}"
+ )
+
+ write_basic_package_version_file(
+ "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake"
+ VERSION ${PROJECT_VERSION}
+ COMPATIBILITY AnyNewerVersion
+ )
+
+ qt_install(TARGETS ${target}
+ EXPORT "${export_name}"
+ DESTINATION "${config_install_dir}"
+ )
+
+ qt_install(EXPORT ${export_name}
+ NAMESPACE "${QT_CMAKE_EXPORT_NAMESPACE}::"
+ DESTINATION "${config_install_dir}"
+ )
+
+ qt_internal_export_modern_cmake_config_targets_file(
+ TARGETS ${target}
+ EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
+ CONFIG_INSTALL_DIR "${config_install_dir}"
+ )
+ endif()
+endfunction()
+
+function(qt_get_tool_cmake_configuration out_var)
+ qt_get_main_cmake_configuration("${out_var}")
+ string(TOUPPER "${${out_var}}" upper_config)
+ set("${out_var}" "${upper_config}" PARENT_SCOPE)
+endfunction()
+
+function(qt_get_main_cmake_configuration out_var)
+ if(CMAKE_BUILD_TYPE)
+ set(config "${CMAKE_BUILD_TYPE}")
+ elseif(QT_MULTI_CONFIG_FIRST_CONFIG)
+ set(config "${QT_MULTI_CONFIG_FIRST_CONFIG}")
+ endif()
+ set("${out_var}" "${config}" PARENT_SCOPE)
+endfunction()
+
# This function is used to define a "Qt tool", such as moc, uic or rcc.
# The BOOTSTRAP option allows building it as standalone program, otherwise
# it will be linked against QtCore.
-function(add_qt_tool name)
- qt_parse_all_arguments(arg "add_qt_tool" "BOOTSTRAP;NO_QT;NO_INSTALL" "TOOLS_TARGET"
+function(qt_add_tool name)
+ qt_parse_all_arguments(arg "qt_add_tool" "BOOTSTRAP;NO_QT;NO_INSTALL" "TOOLS_TARGET"
"${__default_private_args}" ${ARGN})
# Handle case when a tool does not belong to a module and it can't be built either (like
@@ -2692,7 +3188,7 @@ function(add_qt_tool name)
set(no_install NO_INSTALL)
endif()
- add_qt_executable("${name}" OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ qt_add_executable("${name}" OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
${bootstrap}
${no_qt}
${no_install}
@@ -2709,8 +3205,11 @@ function(add_qt_tool name)
)
qt_internal_add_target_aliases("${name}")
+ # If building with a multi-config configuration, the main configuration tool will be placed in
+ # ./bin, while the rest will be in <CONFIG> specific subdirectories.
+ qt_get_tool_cmake_configuration(tool_cmake_configuration)
set_target_properties("${name}" PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
+ RUNTIME_OUTPUT_DIRECTORY_${tool_cmake_configuration} "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
)
if(NOT arg_NO_INSTALL AND arg_TOOLS_TARGET)
@@ -2737,11 +3236,11 @@ endfunction()
# Handle files that need special SIMD-related flags.
# This creates an object library and makes target link
# to it (privately).
-function(add_qt_simd_part target)
- qt_parse_all_arguments(arg "add_qt_simd_part" "" ""
+function(qt_add_simd_part target)
+ qt_parse_all_arguments(arg "qt_add_simd_part" "" ""
"NAME;SIMD;${__default_private_args};COMPILE_FLAGS" ${ARGN})
if ("x${arg_SIMD}" STREQUAL x)
- message(FATAL_ERROR "add_qt_simd_part needs a SIMD type to be set.")
+ message(FATAL_ERROR "qt_add_simd_part needs a SIMD type to be set.")
endif()
set(condition "QT_FEATURE_${arg_SIMD}")
@@ -2761,11 +3260,13 @@ function(add_qt_simd_part target)
qt_evaluate_config_expression(result ${condition})
if(${result})
if(QT_CMAKE_DEBUG_EXTEND_TARGET)
- message("add_qt_simd_part(${target} SIMD ${arg_SIMD} ...): Evaluated")
+ message("qt_add_simd_part(${target} SIMD ${arg_SIMD} ...): Evaluated")
endif()
string(TOUPPER "QT_CFLAGS_${arg_SIMD}" simd_flags)
- add_library("${name}" OBJECT)
+ if (NOT TARGET "${name}")
+ add_library("${name}" OBJECT)
+ endif()
target_sources("${name}" PRIVATE ${arg_SOURCES})
target_include_directories("${name}" PRIVATE
${arg_INCLUDE_DIRECTORIES}
@@ -2779,6 +3280,11 @@ function(add_qt_simd_part target)
target_link_libraries("${target}" PRIVATE "${name}")
+ # Add a link-only dependency on the parent library, to force copying of framework headers
+ # before trying to compile a source file.
+ target_link_libraries("${name}" PRIVATE
+ $<FILTER:$<TARGET_PROPERTY:${target},LINK_LIBRARIES>,EXCLUDE,^${target}_simd_>)
+
if(NOT BUILD_SHARED_LIBS)
qt_install(
TARGETS ${name}
@@ -2787,7 +3293,7 @@ function(add_qt_simd_part target)
endif()
else()
if(QT_CMAKE_DEBUG_EXTEND_TARGET)
- message("add_qt_simd_part(${target} SIMD ${arg_SIMD} ...): Skipped")
+ message("qt_add_simd_part(${target} SIMD ${arg_SIMD} ...): Skipped")
endif()
endif()
endfunction()
@@ -2818,8 +3324,9 @@ endfunction()
# Complete manual moc invocation with full control.
# Use AUTOMOC whenever possible.
function(qt_manual_moc result)
- cmake_parse_arguments(arg "" "" "FLAGS" ${ARGN})
+ cmake_parse_arguments(arg "" "OUTPUT_MOC_JSON_FILES" "FLAGS" ${ARGN})
set(moc_files)
+ set(metatypes_json_list)
foreach(infile ${arg_UNPARSED_ARGUMENTS})
qt_make_output_file("${infile}" "moc_" ".cpp"
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" outfile)
@@ -2827,16 +3334,30 @@ function(qt_manual_moc result)
set(moc_parameters_file "${outfile}_parameters$<$<BOOL:$<CONFIGURATION>>:_$<CONFIGURATION>>")
set(moc_parameters ${arg_FLAGS} -o "${outfile}" "${infile}")
+
+ set(metatypes_byproducts)
+ if (arg_OUTPUT_MOC_JSON_FILES)
+ set(moc_json_file "${outfile}.json")
+ list(APPEND moc_parameters --output-json)
+ list(APPEND metatypes_json_list "${outfile}.json")
+ set(metatypes_byproducts "${outfile}.json")
+ endif()
+
string (REPLACE ";" "\n" moc_parameters "${moc_parameters}")
file(GENERATE OUTPUT "${moc_parameters_file}" CONTENT "${moc_parameters}\n")
- add_custom_command(OUTPUT "${outfile}"
+ add_custom_command(OUTPUT "${outfile}" ${metatypes_byproducts}
COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::moc "@${moc_parameters_file}"
DEPENDS "${infile}" ${moc_depends} ${QT_CMAKE_EXPORT_NAMESPACE}::moc
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" VERBATIM)
endforeach()
set("${result}" ${moc_files} PARENT_SCOPE)
+
+ # Register generated json files
+ if (arg_OUTPUT_MOC_JSON_FILES)
+ set(${arg_OUTPUT_MOC_JSON_FILES} "${metatypes_json_list}" PARENT_SCOPE)
+ endif()
endfunction()
@@ -2889,7 +3410,7 @@ function(qt_create_qdbusxml2cpp_command target infile)
add_custom_command(OUTPUT "${header_file}" "${source_file}"
COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::qdbusxml2cpp ${arg_FLAGS} "${option}"
"${header_file}:${source_file}" "${absolute_in_file_path}"
- DEPENDS "${absolute_in_file_path}"
+ DEPENDS "${absolute_in_file_path}" ${QT_CMAKE_EXPORT_NAMESPACE}::qdbusxml2cpp
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
VERBATIM)
@@ -2903,7 +3424,7 @@ function(qt_compute_injection_forwarding_header target)
get_filename_component(file_name "${arg_SOURCE}" NAME)
set(source_absolute_path "${CMAKE_CURRENT_BINARY_DIR}/${arg_SOURCE}")
- file(RELATIVE_PATH relpath "${CMAKE_BINARY_DIR}" "${source_absolute_path}")
+ file(RELATIVE_PATH relpath "${PROJECT_BINARY_DIR}" "${source_absolute_path}")
if (arg_PRIVATE)
set(fwd "${PROJECT_VERSION}/${module}/private/${file_name}")
@@ -2916,18 +3437,191 @@ function(qt_compute_injection_forwarding_header target)
endfunction()
-function(add_qt_docs)
+function(qt_add_docs)
if(${ARGC} EQUAL 1)
# Function called from old generated CMakeLists.txt that was missing the target parameter
return()
endif()
if(NOT ${ARGC} EQUAL 2)
- message(FATAL_ERROR "add_qt_docs called with the wrong number of arguments. Should be add_qt_docs(target path_to_project.qdocconf).")
+ message(FATAL_ERROR "qt_add_docs called with the wrong number of arguments. Should be qt_add_docs(target path_to_project.qdocconf).")
return()
endif()
set(target ${ARGV0})
set(doc_project ${ARGV1})
- # TODO
+
+ if (NOT QT_SUPERBUILD OR QT_WILL_INSTALL)
+ set(qdoc_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qdoc")
+ set(qtattributionsscanner_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qtattributionsscanner")
+ set(qhelpgenerator_bin "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qhelpgenerator")
+ else()
+ set(qdoc_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qdoc")
+ set(qtattributionsscanner_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qtattributionsscanner")
+ set(qhelpgenerator_bin "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_BINDIR}/qhelpgenerator")
+ endif()
+
+ get_target_property(target_type ${target} TYPE)
+ if (NOT target_type STREQUAL "INTERFACE_LIBRARY")
+ get_target_property(target_bin_dir ${target} BINARY_DIR)
+ get_target_property(target_source_dir ${target} SOURCE_DIR)
+ else()
+ set(target_bin_dir ${CMAKE_CURRENT_BINARY_DIR})
+ set(target_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+ set(doc_ouput_dir "${target_bin_dir}/.doc")
+
+
+ # Generate include dir list
+ set(target_include_dirs_file "${doc_ouput_dir}/$<CONFIG>/includes.txt")
+
+ set(include_paths_property "$<TARGET_PROPERTY:${target},INCLUDE_DIRECTORIES>")
+ if (NOT target_type STREQUAL "INTERFACE_LIBRARY")
+ file(GENERATE
+ OUTPUT ${target_include_dirs_file}
+ CONTENT "-I$<JOIN:${include_paths_property},\n-I>"
+ )
+ set(include_path_args "@${target_include_dirs_file}")
+ else()
+ set(include_path_args "")
+ endif()
+
+ get_filename_component(doc_target "${doc_project}" NAME_WLE)
+ if (QT_WILL_INSTALL)
+ set(qdoc_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}/${doc_target}")
+ set(index_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
+ elseif (QT_SUPERBUILD)
+ set(qdoc_output_dir "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}/${doc_target}")
+ set(index_dir "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
+ else()
+ set(qdoc_output_dir "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
+ set(index_dir "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
+ endif()
+
+ # qtattributionsscanner
+ add_custom_target(qattributionsscanner_${target}
+ DEPENDS ${qattributionsscanner_bin}
+ COMMAND ${qtattributionsscanner_bin}
+ ${PROJECT_SOURCE_DIR}
+ --filter "QDocModule=${qdoc_target}"
+ -o "${target_bin_dir}/codeattributions.qdoc"
+ )
+
+ # prepare docs target
+ set(prepare_qdoc_args
+ -outputdir "${qdoc_output_dir}"
+ -installdir "${QT_INSTALL_DIR}/${INSTALL_DOCDIR}"
+ "${target_source_dir}/${doc_project}"
+ -prepare
+ -indexdir "${index_dir}"
+ -no-link-errors
+ "${include_path_args}"
+ )
+
+ if (QT_SUPERBUILD AND NOT QT_WILL_INSTALL)
+ set(qt_install_docs_env "${CMAKE_INSTALL_PREFIX}/qtbase/${INSTALL_DOCDIR}")
+ else()
+ set(qt_install_docs_env "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
+ endif()
+
+ set(qdoc_env_args
+ "QT_INSTALL_DOCS=\"${qt_install_docs_env}\""
+ "QT_VERSION=${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
+ "QT_VER=${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
+ "QT_VERSION_TAG=${PROJECT_VERSION_MAJOR}${PROJECT_VERSION_MINOR}${PROJECT_VERSION_PATCH}"
+ "BUILDDIR=${target_bin_dir}"
+ )
+
+ add_custom_target(prepare_docs_${target}
+ DEPENDS ${qdoc_bin}
+ COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args}
+ ${qdoc_bin}
+ ${prepare_qdoc_args}
+ )
+
+ add_dependencies(prepare_docs_${target} qattributionsscanner_${target})
+
+ # generate docs target
+ set(generate_qdocs_args
+ -outputdir "${qdoc_output_dir}"
+ -installdir "${INSTALL_DOCDIR}"
+ "${target_source_dir}/${doc_project}"
+ -generate
+ -indexdir "${index_dir}"
+ "${include_path_args}"
+ )
+
+ add_custom_target(generate_docs_${target}
+ DEPENDS ${qdoc_bin}
+ COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args}
+ ${qdoc_bin}
+ ${generate_qdocs_args}
+ )
+
+ add_dependencies(generate_docs_${target} prepare_docs_${target})
+
+ # generate html
+ set(html_qdocs_args
+ -outputdir "${qdoc_output_dir}"
+ -installdir "${INSTALL_DOCDIR}"
+ "${target_source_dir}/${doc_project}"
+ -indexdir "${index_dir}"
+ "${include_path_args}"
+ )
+
+ add_custom_target(html_docs_${target}
+ DEPENDS ${qdoc_bin}
+ COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args}
+ ${qdoc_bin}
+ ${html_qdocs_args}
+ )
+
+ add_dependencies(html_docs_${target} generate_docs_${target})
+
+ # generate .qch
+ set(qch_file_name ${doc_target}.qch)
+ set(qch_file_path ${qdoc_output_dir}/${qch_file_name})
+
+ add_custom_target(qch_docs_${target}
+ DEPENDS ${qhelpgenerator_bin}
+ COMMAND ${qhelpgenerator_bin}
+ "${qdoc_output_dir}/${doc_target}.qhp"
+ -o "${qch_file_path}"
+ )
+ add_dependencies(qch_docs_${target} generate_docs_${target})
+
+ if (QT_WILL_INSTALL)
+ add_custom_target(install_html_docs_${target}
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ "${qdoc_output_dir}"
+ "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}"
+ COMMENT "Installing html docs for target ${target}"
+ )
+
+ add_custom_target(install_qch_docs_${target}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${qch_file_path}"
+ "${CMAKE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${qch_file_name}"
+ COMMENT "Installing qch docs for target ${target}"
+ )
+ else()
+ # Don't need to do anything when not installing
+ add_custom_target(install_html_docs_${target})
+ add_custom_target(install_qch_docs_${target})
+ endif()
+
+ add_dependencies(install_html_docs_${target} html_docs_${target})
+ add_dependencies(install_qch_docs_${target} qch_docs_${target})
+
+ add_custom_target(install_docs_${target})
+ add_dependencies(install_docs_${target} install_html_docs_${target} install_qch_docs_${target})
+
+ add_dependencies(${qt_docs_prepare_target_name} prepare_docs_${target})
+ add_dependencies(${qt_docs_generate_target_name} generate_docs_${target})
+ add_dependencies(${qt_docs_html_target_name} html_docs_${target})
+ add_dependencies(${qt_docs_qch_target_name} qch_docs_${target})
+ add_dependencies(${qt_docs_install_html_target_name} install_html_docs_${target})
+ add_dependencies(${qt_docs_install_qch_target_name} install_qch_docs_${target})
+ add_dependencies(${qt_docs_install_target_name} install_docs_${target})
+
endfunction()
macro(qt_find_package)
@@ -3139,10 +3833,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)
@@ -3204,6 +3902,7 @@ function(qt_process_qlalr consuming_target input_file_list flags)
add_custom_command(
OUTPUT ${cpp_file} ${private_file} ${decl_file} ${impl_file}
COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::qlalr ${flags} ${input_file}
+ DEPENDS ${QT_CMAKE_EXPORT_NAMESPACE}::qlalr
MAIN_DEPENDENCY ${input_file}
)
target_sources(${consuming_target} PRIVATE ${cpp_file} ${impl_file})
@@ -3229,7 +3928,6 @@ function(qt_generate_qconfig_cpp)
qt_add_string_to_qconfig_cpp("libexec")
qt_add_string_to_qconfig_cpp("bin")
qt_add_string_to_qconfig_cpp("plugins")
- qt_add_string_to_qconfig_cpp("imports")
qt_add_string_to_qconfig_cpp("qml")
qt_add_string_to_qconfig_cpp(".")
qt_add_string_to_qconfig_cpp(".")
@@ -3268,19 +3966,19 @@ function(qt_generate_qconfig_cpp)
# TODO: Clean this up, there's a bunch of unrealistic assumptions here.
# See qtConfOutput_preparePaths in qtbase/configure.pri.
if(WIN32)
- set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/bin")
+ set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
else()
- set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/lib")
+ set(lib_location_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
endif()
file(RELATIVE_PATH from_lib_location_to_prefix
"${lib_location_absolute_path}" "${CMAKE_INSTALL_PREFIX}")
if(QT_HOST_PATH)
set(host_prefix "${QT_HOST_PATH}")
- set(host_bin_dir_absolute_path "${QT_HOST_PATH}/bin")
+ set(host_bin_dir_absolute_path "${QT_HOST_PATH}/${INSTALL_BINDIR}")
else()
set(host_prefix "${CMAKE_INSTALL_PREFIX}")
- set(host_bin_dir_absolute_path "${CMAKE_INSTALL_PREFIX}/bin")
+ set(host_bin_dir_absolute_path "${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
endif()
file(RELATIVE_PATH from_host_bin_dir_to_host_prefix
@@ -3298,3 +3996,75 @@ function(qt_generate_qconfig_cpp)
configure_file(global/qconfig.cpp.in global/qconfig.cpp @ONLY)
endfunction()
+
+function(qt_set_language_standards)
+ ## Use the latest standard the compiler supports (same as qt_common.prf)
+ if (QT_FEATURE_cxx2a)
+ set(CMAKE_CXX_STANDARD 20 PARENT_SCOPE)
+ elseif (QT_FEATURE_cxx17)
+ set(CMAKE_CXX_STANDARD 17 PARENT_SCOPE)
+ elseif (QT_FEATURE_cxx14)
+ set(CMAKE_CXX_STANDARD 14 PARENT_SCOPE)
+ elseif (QT_FEATURE_cxx11)
+ set(CMAKE_CXX_STANDARD 11 PARENT_SCOPE)
+ endif()
+
+ if (c_std_11 IN_LIST CMAKE_C_COMPILE_FEATURES)
+ set(CMAKE_C_STANDARD 11 PARENT_SCOPE)
+ elseif (c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES)
+ set(CMAKE_C_STANDARD 99 PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Compatibility macros that should be removed once all their usages are removed.
+function(extend_target)
+ qt_extend_target(${ARGV})
+endfunction()
+
+function(add_qt_module)
+ qt_add_module(${ARGV})
+endfunction()
+
+function(add_qt_plugin)
+ qt_add_plugin(${ARGV})
+endfunction()
+
+function(add_qt_tool)
+ qt_add_tool(${ARGV})
+endfunction()
+
+function(add_qt_test)
+ qt_add_test(${ARGV})
+endfunction()
+
+function(add_qt_test_helper)
+ qt_add_test_helper(${ARGV})
+endfunction()
+
+function(add_qt_manual_test)
+ qt_add_manual_test(${ARGV})
+endfunction()
+
+function(add_qt_benchmark)
+ qt_add_benchmark(${ARGV})
+endfunction()
+
+function(add_qt_executable)
+ qt_add_executable(${ARGV})
+endfunction()
+
+function(add_qt_simd_part)
+ qt_add_simd_part(${ARGV})
+endfunction()
+
+function(add_qt_docs)
+ qt_add_docs(${ARGV})
+endfunction()
+
+function(add_qt_resource)
+ qt_add_resource(${ARGV})
+endfunction()
+
+function(add_cmake_library)
+ qt_add_cmake_library(${ARGV})
+endfunction()
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake
new file mode 100644
index 0000000000..097192b2ab
--- /dev/null
+++ b/cmake/QtBuildInformation.cmake
@@ -0,0 +1,35 @@
+function(qt_print_feature_summary)
+ include(FeatureSummary)
+ feature_summary(WHAT PACKAGES_FOUND
+ REQUIRED_PACKAGES_NOT_FOUND
+ RECOMMENDED_PACKAGES_NOT_FOUND
+ OPTIONAL_PACKAGES_NOT_FOUND
+ RUNTIME_PACKAGES_NOT_FOUND
+ FATAL_ON_MISSING_REQUIRED_PACKAGES)
+endfunction()
+
+function(qt_print_build_instructions)
+ if((NOT PROJECT_NAME STREQUAL "QtBase" AND
+ NOT PROJECT_NAME STREQUAL "Qt") OR
+ QT_BUILD_STANDALONE_TESTS)
+
+ return()
+ endif()
+
+ set(build_command "cmake --build . --parallel")
+ set(install_command "cmake --install .")
+
+ message("Qt is now configured for building. Just run '${build_command}'.")
+ if(QT_WILL_INSTALL)
+ message("Once everything is built, you must run '${install_command}'.")
+ message("Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
+ else()
+ message("Once everything is built, Qt is installed.")
+ message("You should NOT run '${install_command}'")
+ message("Note that this build cannot be deployed to other machines or devices.")
+ endif()
+ message("To configure and build other modules, you can use the following convenience script:
+ ${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake")
+ message("\nIf reconfiguration fails for some reason, try to remove 'CMakeCache.txt' \
+from the build directory \n")
+endfunction()
diff --git a/cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake b/cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake
index 7f8b6df232..51645f48d5 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake
@@ -69,6 +69,10 @@ define_property(TARGET
# androiddeploytoolqt to successfully copy all the plugins and other dependent
# items into tha APK
function(qt_android_dependencies target)
+ get_target_property(target_type "${target}" TYPE)
+ if(target_type STREQUAL "INTERFACE_LIBRARY")
+ return()
+ endif()
get_target_property(arg_JAR_DEPENDENCIES ${target} QT_ANDROID_JAR_DEPENDENCIES)
get_target_property(arg_BUNDLED_JAR_DEPENDENCIES ${target} QT_ANDROID_BUNDLED_JAR_DEPENDENCIES)
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
index 4bf09e5b15..2703e06fe5 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
@@ -19,12 +19,12 @@ macro(qt_set_up_build_internals_paths)
set(QT_CMAKE_MODULE_PATH "${QT_BUILD_INTERNALS_PATH}/../${QT_CMAKE_EXPORT_NAMESPACE}")
list(PREPEND CMAKE_MODULE_PATH "${QT_CMAKE_MODULE_PATH}")
- # When doing a non-prefix build, prepend the qtbase source cmake directory to CMAKE_MODULE_PATH,
+ # Prepend the qtbase source cmake directory to CMAKE_MODULE_PATH,
# so that if a change is done in cmake/QtBuild.cmake, it gets automatically picked up when
# building qtdeclarative, rather than having to build qtbase first (which will copy
# QtBuild.cmake to the build dir). This is similar to qmake non-prefix builds, where the
# source qtbase/mkspecs directory is used.
- if(NOT QT_WILL_INSTALL)
+ if(EXISTS "${QT_SOURCE_TREE}/cmake")
list(PREPEND CMAKE_MODULE_PATH "${QT_SOURCE_TREE}/cmake")
endif()
@@ -60,57 +60,67 @@ macro(qt_build_repo_begin)
# Find Apple frameworks if needed.
qt_find_apple_system_frameworks()
-endmacro()
-macro(qt_build_repo_end)
- # Delayed actions on some of the Qt targets:
- include(QtPostProcess)
-
- # Install the repo-specific cmake find modules.
- qt_path_join(__qt_repo_install_dir ${QT_CONFIG_INSTALL_DIR} ${INSTALL_CMAKE_NAMESPACE})
-
- if(NOT PROJECT_NAME STREQUAL "QtBase")
- if (EXISTS cmake)
- qt_copy_or_install(DIRECTORY cmake/
- DESTINATION "${__qt_repo_install_dir}"
- FILES_MATCHING PATTERN "Find*.cmake"
- )
- endif()
- endif()
+ # Decide whether tools will be built.
+ qt_check_if_tools_will_be_built()
- # Print a feature summary:
- feature_summary(WHAT PACKAGES_FOUND
- REQUIRED_PACKAGES_NOT_FOUND
- RECOMMENDED_PACKAGES_NOT_FOUND
- OPTIONAL_PACKAGES_NOT_FOUND
- RUNTIME_PACKAGES_NOT_FOUND
- FATAL_ON_MISSING_REQUIRED_PACKAGES)
- qt_print_build_instructions()
+ string(TOLOWER ${PROJECT_NAME} project_name_lower)
+
+ set(qt_docs_target_name docs_${project_name_lower})
+ set(qt_docs_prepare_target_name prepare_docs_${project_name_lower})
+ set(qt_docs_generate_target_name generate_docs_${project_name_lower})
+ set(qt_docs_html_target_name html_docs_${project_name_lower})
+ set(qt_docs_qch_target_name qch_docs_${project_name_lower})
+ set(qt_docs_install_html_target_name install_html_docs_${project_name_lower})
+ set(qt_docs_install_qch_target_name install_qch_docs_${project_name_lower})
+ set(qt_docs_install_target_name install_docs_${project_name_lower})
+
+ add_custom_target(${qt_docs_target_name})
+ add_custom_target(${qt_docs_prepare_target_name})
+ add_custom_target(${qt_docs_generate_target_name})
+ add_custom_target(${qt_docs_qch_target_name})
+ add_custom_target(${qt_docs_html_target_name})
+ add_custom_target(${qt_docs_install_html_target_name})
+ add_custom_target(${qt_docs_install_qch_target_name})
+ add_custom_target(${qt_docs_install_target_name})
+
+ add_dependencies(${qt_docs_generate_target_name} ${qt_docs_prepare_target_name})
+ add_dependencies(${qt_docs_html_target_name} ${qt_docs_generate_target_name})
+ add_dependencies(${qt_docs_target_name} ${qt_docs_html_target_name} ${qt_docs_qch_target_name})
+ add_dependencies(${qt_docs_install_html_target_name} ${qt_docs_html_target_name})
+ add_dependencies(${qt_docs_install_qch_target_name} ${qt_docs_qch_target_name})
+ add_dependencies(${qt_docs_install_target_name} ${qt_docs_install_html_target_name} ${qt_docs_install_qch_target_name})
endmacro()
-function(qt_print_build_instructions)
- if(NOT PROJECT_NAME STREQUAL "QtBase")
- return()
+macro(qt_build_repo_end)
+ include(QtBuildInformation)
+
+ if(NOT QT_BUILD_STANDALONE_TESTS)
+ # Delayed actions on some of the Qt targets:
+ include(QtPostProcess)
+
+ # Install the repo-specific cmake find modules.
+ qt_path_join(__qt_repo_install_dir ${QT_CONFIG_INSTALL_DIR} ${INSTALL_CMAKE_NAMESPACE})
+
+ if(NOT PROJECT_NAME STREQUAL "QtBase")
+ if (EXISTS cmake)
+ qt_copy_or_install(DIRECTORY cmake/
+ DESTINATION "${__qt_repo_install_dir}"
+ FILES_MATCHING PATTERN "Find*.cmake"
+ )
+ endif()
+ endif()
+
+ if(NOT QT_SUPERBUILD)
+ qt_print_feature_summary()
+ endif()
endif()
- set(build_command "cmake --build . --parallel")
- set(install_command "cmake --install .")
-
- message("Qt is now configured for building. Just run '${build_command}'.")
- if(QT_WILL_INSTALL)
- message("Once everything is built, you must run '${install_command}'.")
- message("Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
- else()
- message("Once everything is built, Qt is installed.")
- message("You should NOT run '${install_command}'")
- message("Note that this build cannot be deployed to other machines or devices.")
+ if(NOT QT_SUPERBUILD)
+ qt_print_build_instructions()
endif()
- message("To configure and build other modules, you can use the following convenience script:
- ${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake")
- message("\nIf reconfiguration fails for some reason, try to remove 'CMakeCache.txt' \
-from the build directory \n")
-endfunction()
+endmacro()
macro(qt_build_repo)
qt_build_repo_begin(${ARGN})
@@ -118,50 +128,69 @@ macro(qt_build_repo)
# If testing is enabled, try to find the qtbase Test package.
# Do this before adding src, because there might be test related conditions
# in source.
- if (BUILD_TESTING)
+ if (BUILD_TESTING AND NOT QT_BUILD_STANDALONE_TESTS)
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Test)
endif()
- ## Decide whether tools will be built.
- qt_check_if_tools_will_be_built()
-
- if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/CMakeLists.txt")
- add_subdirectory(src)
- endif()
+ if(NOT QT_BUILD_STANDALONE_TESTS)
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/CMakeLists.txt")
+ add_subdirectory(src)
+ endif()
- if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tools/CMakeLists.txt")
- add_subdirectory(tools)
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tools/CMakeLists.txt")
+ add_subdirectory(tools)
+ endif()
endif()
if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
add_subdirectory(tests)
+ if(QT_NO_MAKE_TESTS)
+ set_property(DIRECTORY tests PROPERTY EXCLUDE_FROM_ALL TRUE)
+ endif()
endif()
qt_build_repo_end()
- if (BUILD_EXAMPLES AND BUILD_SHARED_LIBS AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt")
+ if (BUILD_EXAMPLES AND BUILD_SHARED_LIBS
+ AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt"
+ AND NOT QT_BUILD_STANDALONE_TESTS)
add_subdirectory(examples)
+ if(QT_NO_MAKE_EXAMPLES)
+ set_property(DIRECTORY examples PROPERTY EXCLUDE_FROM_ALL TRUE)
+ endif()
endif()
endmacro()
macro(qt_set_up_standalone_tests_build)
- qt_set_up_build_internals_paths()
- include(QtSetup)
-
- # Optionally include a repo specific Setup module.
- include(QtRepoSetup OPTIONAL)
-
- qt_find_apple_system_frameworks()
- qt_check_if_tools_will_be_built()
+ # Remove this macro once all usages of it have been removed.
+ # Standalone tests are not handled via the main repo project and qt_build_tests.
endmacro()
macro(qt_build_tests)
+ if(QT_BUILD_STANDALONE_TESTS)
+ # Find location of TestsConfig.cmake. These contain the modules that need to be
+ # find_package'd when testing.
+ set(_qt_build_tests_install_prefix
+ "${QT_CONFIG_INSTALL_DIR}/${INSTALL_CMAKE_NAMESPACE}BuildInternals/StandaloneTests")
+ if(QT_WILL_INSTALL)
+ qt_path_join(_qt_build_tests_install_prefix
+ ${CMAKE_INSTALL_PREFIX} ${_qt_build_tests_install_prefix})
+ endif()
+ include("${_qt_build_tests_install_prefix}/${PROJECT_NAME}TestsConfig.cmake" OPTIONAL)
+
+ # Of course we always need the test module as well.
+ find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Test)
+ endif()
+
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/auto/CMakeLists.txt")
add_subdirectory(auto)
endif()
- if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt")
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt" AND QT_BUILD_BENCHMARKS)
add_subdirectory(benchmarks)
endif()
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manual/CMakeLists.txt")
+ add_subdirectory(manual)
+ endif()
endmacro()
macro(qt_examples_build_begin)
@@ -170,8 +199,8 @@ macro(qt_examples_build_begin)
# Appending to CMAKE_PREFIX_PATH helps find the initial Qt6Config.cmake.
# Appending to QT_EXAMPLES_CMAKE_PREFIX_PATH helps find components of Qt6, because those
# find_package calls use NO_DEFAULT_PATH, and thus CMAKE_PREFIX_PATH is ignored.
- list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
- list(APPEND QT_EXAMPLES_CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
+ list(APPEND CMAKE_PREFIX_PATH "${QT_BUILD_DIR}")
+ list(APPEND QT_EXAMPLES_CMAKE_PREFIX_PATH "${QT_BUILD_DIR}")
# Also make sure the CMake config files do not recreate the already-existing targets
set(QT_NO_CREATE_TARGETS TRUE)
set(BACKUP_CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE})
diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in
index 04a0998cf1..5278890337 100644
--- a/cmake/QtBuildInternalsExtra.cmake.in
+++ b/cmake/QtBuildInternalsExtra.cmake.in
@@ -3,7 +3,6 @@ set(QT_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
option(BUILD_SHARED_LIBS "Build Qt statically or dynamically" @BUILD_SHARED_LIBS@)
set(QT_CMAKE_EXPORT_NAMESPACE @QT_CMAKE_EXPORT_NAMESPACE@)
set(INSTALL_CMAKE_NAMESPACE @INSTALL_CMAKE_NAMESPACE@)
-set(CMAKE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
set(QT_BUILD_INTERNALS_PATH "${CMAKE_CURRENT_LIST_DIR}")
# Propagate the original install prefix, so that a developer building a child module can
@@ -26,6 +25,13 @@ set(QT_SOURCE_TREE "@QT_SOURCE_TREE@" CACHE PATH
# Propagate decision of building tests and examples to other repositories.
set(BUILD_TESTING @BUILD_TESTING@ CACHE BOOL "Build the testing tree.")
set(BUILD_EXAMPLES @BUILD_EXAMPLES@ CACHE BOOL "Build Qt examples")
+set(QT_NO_MAKE_TESTS @QT_NO_MAKE_TESTS@ CACHE BOOL
+ "Should tests be built as part of the default 'all' target.")
+set(QT_NO_MAKE_EXAMPLES @QT_NO_MAKE_EXAMPLES@ CACHE BOOL
+ "Should examples be built as part of the default 'all' target.")
+
+# Propagate usage of ccache.
+set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache")
# Extra set of exported variables
@QT_EXTRA_BUILD_INTERNALS_VARS@
diff --git a/cmake/QtCompilerOptimization.cmake b/cmake/QtCompilerOptimization.cmake
index 5ca28c4de4..1f50044a6f 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 AND NOT QT_64BIT)
+ set(QT_CFLAGS_NEON "-mfpu=neon")
+ endif()
set(QT_CFLAGS_MIPS_DSP "-mdsp")
set(QT_CFLAGS_MIPS_DSPR2 "-mdspr2")
endif()
diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in
index efce91d1c4..6d69c1f90e 100644
--- a/cmake/QtConfig.cmake.in
+++ b/cmake/QtConfig.cmake.in
@@ -10,13 +10,16 @@ set(_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
if (NOT QT_NO_CREATE_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Targets.cmake")
- include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@VersionlessTargets.cmake")
+ if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@VersionlessTargets.cmake")
+ endif()
else()
# For examples using `find_package(...)` inside their CMakeLists.txt files:
# Make CMake's AUTOGEN detect this Qt version properly
set_directory_properties(PROPERTIES
QT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
- QT_VERSION_MINOR @PROJECT_VERSION_MINOR@)
+ QT_VERSION_MINOR @PROJECT_VERSION_MINOR@
+ QT_VERSION_PATCH @PROJECT_VERSION_PATCH@)
endif()
# if (NOT @INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS)
diff --git a/cmake/QtFeature.cmake b/cmake/QtFeature.cmake
index e3fb9c4232..faca42635c 100644
--- a/cmake/QtFeature.cmake
+++ b/cmake/QtFeature.cmake
@@ -23,10 +23,26 @@ function(qt_feature_module_begin)
set(__QtFeature_private_extra "" PARENT_SCOPE)
set(__QtFeature_public_extra "" PARENT_SCOPE)
+ set(__QtFeature_config_definitions "" PARENT_SCOPE)
+
set(__QtFeature_define_definitions "" PARENT_SCOPE)
endfunction()
+function(qt_feature_normalize_name name out_var)
+ # Normalize the feature name to something CMake can deal with.
+ if(name MATCHES "c\\+\\+")
+ string(REGEX REPLACE "[^a-zA-Z0-9_]" "x" name "${name}")
+ else()
+ string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" name "${name}")
+ endif()
+ set(${out_var} "${name}" PARENT_SCOPE)
+endfunction()
+
function(qt_feature feature)
+ set(original_name "${feature}")
+ qt_feature_normalize_name("${feature}" feature)
+ set_property(GLOBAL PROPERTY QT_FEATURE_ORIGINAL_NAME_${feature} "${original_name}")
+
qt_parse_all_arguments(arg "qt_feature"
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;" "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" ${ARGN})
@@ -260,7 +276,63 @@ function(qt_evaluate_feature feature)
qt_feature_set_value("${feature}" "${cache}" "${emit_if}" "${condition}" "${arg_LABEL}")
endfunction()
+function(qt_feature_config feature config_var_name)
+ qt_feature_normalize_name("${feature}" feature)
+ qt_parse_all_arguments(arg "qt_feature_config" "NEGATE" "NAME" "" ${ARGN})
+
+ # Store all the config related info in a unique variable key.
+ set(key_name "_QT_FEATURE_CONFIG_DEFINITION_${feature}_${config_var_name}")
+ set(${key_name} "FEATURE;${feature};CONFIG_VAR_NAME;${config_var_name};${ARGN}" PARENT_SCOPE)
+
+ # Store the key for later evaluation.
+ list(APPEND __QtFeature_config_definitions "${key_name}")
+
+ set(__QtFeature_config_definitions ${__QtFeature_config_definitions} PARENT_SCOPE)
+endfunction()
+
+function(qt_evaluate_qmake_config_values key)
+ if(NOT DEFINED ${key})
+ qt_debug_print_variables(DEDUP MATCH "^_QT_FEATURE_CONFIG_DEFINITION")
+ message(FATAL_ERROR
+ "Attempting to evaluate feature config ${key} but its definition is missing. ")
+ endif()
+
+ cmake_parse_arguments(arg
+ "NEGATE"
+ "FEATURE;NAME;CONFIG_VAR_NAME"
+ "" ${${key}})
+
+ set(expected "NOT")
+ if (arg_NEGATE)
+ set(expected "")
+ endif()
+
+ # If no custom name is specified, then the config value is the same as the feature name.
+ if(NOT arg_NAME)
+ set(arg_NAME "${arg_FEATURE}")
+ endif()
+
+ # The feature condition is false, there is no need to export any config values.
+ if(${expected} ${QT_FEATURE_${arg_FEATURE}})
+ return()
+ endif()
+
+ if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PUBLIC_CONFIG")
+ list(APPEND __QtFeature_qmake_public_config "${arg_NAME}")
+ set(__QtFeature_qmake_public_config "${__QtFeature_qmake_public_config}" PARENT_SCOPE)
+ endif()
+ if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PRIVATE_CONFIG")
+ list(APPEND __QtFeature_qmake_private_config "${arg_NAME}")
+ set(__QtFeature_qmake_private_config "${__QtFeature_qmake_private_config}" PARENT_SCOPE)
+ endif()
+ if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PUBLIC_QT_CONFIG")
+ list(APPEND __QtFeature_qmake_public_qt_config "${arg_NAME}")
+ set(__QtFeature_qmake_public_qt_config "${__QtFeature_qmake_public_qt_config}" PARENT_SCOPE)
+ endif()
+endfunction()
+
function(qt_feature_definition feature name)
+ qt_feature_normalize_name("${feature}" feature)
qt_parse_all_arguments(arg "qt_feature_definition" "NEGATE" "VALUE" "" ${ARGN})
# Store all the define related info in a unique variable key.
@@ -360,6 +432,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 "")
@@ -381,6 +461,11 @@ function(qt_feature_module_end)
endif()
endforeach()
+ foreach(key ${__QtFeature_config_definitions})
+ qt_evaluate_qmake_config_values(${key})
+ unset(${key} PARENT_SCOPE)
+ endforeach()
+
foreach(key ${__QtFeature_define_definitions})
qt_evaluate_feature_definition(${key})
unset(${key} PARENT_SCOPE)
@@ -420,7 +505,7 @@ function(qt_feature_module_end)
set(propertyPrefix "INTERFACE_")
else()
set(propertyPrefix "")
- set_target_properties("${target}" PROPERTIES EXPORT_PROPERTIES "QT_ENABLED_PUBLIC_FEATURES;QT_DISABLED_PUBLIC_FEATURES;QT_ENABLED_PRIVATE_FEATURES;QT_DISABLED_PRIVATE_FEATURES;MODULE_PLUGIN_TYPES;QT_PLUGINS")
+ set_target_properties("${target}" PROPERTIES EXPORT_PROPERTIES "QT_ENABLED_PUBLIC_FEATURES;QT_DISABLED_PUBLIC_FEATURES;QT_ENABLED_PRIVATE_FEATURES;QT_DISABLED_PRIVATE_FEATURES;MODULE_PLUGIN_TYPES;QT_PLUGINS;QT_QMAKE_PUBLIC_CONFIG;QT_QMAKE_PRIVATE_CONFIG;QT_QMAKE_PUBLIC_QT_CONFIG")
endif()
foreach(visibility public private)
string(TOUPPER "${visibility}" capitalVisibility)
@@ -430,6 +515,36 @@ function(qt_feature_module_end)
set_property(TARGET "${target}" PROPERTY ${propertyPrefix}QT_${capitalState}_${capitalVisibility}_FEATURES "${${state}_${visibility}_features}")
endforeach()
endforeach()
+
+ set_property(TARGET "${target}"
+ PROPERTY ${propertyPrefix}QT_QMAKE_PUBLIC_CONFIG
+ "${__QtFeature_qmake_public_config}")
+ set_property(TARGET "${target}"
+ PROPERTY ${propertyPrefix}QT_QMAKE_PRIVATE_CONFIG
+ "${__QtFeature_qmake_private_config}")
+ set_property(TARGET "${target}"
+ PROPERTY ${propertyPrefix}QT_QMAKE_PUBLIC_QT_CONFIG
+ "${__QtFeature_qmake_public_qt_config}")
+
+ # Config values were the old-school features before actual configure.json features were
+ # implemented. Therefore "CONFIG+=foo" values should be considered features as well,
+ # so that CMake can find them when building qtmultimedia for example.
+ if(__QtFeature_qmake_public_config)
+ set_property(TARGET "${target}"
+ APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PUBLIC_FEATURES
+ ${__QtFeature_qmake_public_config})
+ endif()
+ if(__QtFeature_qmake_private_config)
+ set_property(TARGET "${target}"
+ APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PRIVATE_FEATURES
+ ${__QtFeature_qmake_private_config})
+ endif()
+ if(__QtFeature_qmake_public_qt_config)
+ set_property(TARGET "${target}"
+ APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PUBLIC_FEATURES
+ ${__QtFeature_qmake_public_qt_config})
+ endif()
+
qt_feature_copy_global_config_features_to_core(${target})
endif()
@@ -445,6 +560,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)
@@ -468,10 +585,27 @@ function(qt_feature_copy_global_config_features_to_core target)
set_property(TARGET Core PROPERTY ${core_property_name} ${total_values})
endforeach()
endforeach()
+
+ set(config_property_names
+ QT_QMAKE_PUBLIC_CONFIG QT_QMAKE_PRIVATE_CONFIG QT_QMAKE_PUBLIC_QT_CONFIG )
+ foreach(property_name ${config_property_names})
+ set(core_property_name "${property_name}")
+ set(global_property_name "INTERFACE_${core_property_name}")
+
+ get_property(core_values TARGET Core PROPERTY ${core_property_name})
+ get_property(global_values TARGET GlobalConfig PROPERTY ${global_property_name})
+
+ set(total_values ${core_values} ${global_values})
+ set_property(TARGET Core PROPERTY ${core_property_name} ${total_values})
+ endforeach()
endif()
endfunction()
function(qt_config_compile_test name)
+ if(DEFINED "TEST_${name}")
+ return()
+ endif()
+
cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH;C_STANDARD;CXX_STANDARD" "LIBRARIES;CODE" ${ARGN})
if(arg_PROJECT_PATH)
@@ -523,18 +657,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()
@@ -545,8 +726,8 @@ function(qt_config_compile_test_x86simd extension label)
endfunction()
function(qt_make_features_available target)
- if(NOT "${target}" MATCHES "^${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-z][a-zA-Z0-9_-]*$")
- message(FATAL_ERROR "${target} does not match ${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-z][a-zA-Z0-9_-]*. INVALID NAME.")
+ if(NOT "${target}" MATCHES "^${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-Z][a-zA-Z0-9_-]*$")
+ message(FATAL_ERROR "${target} does not match ${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-Z][a-zA-Z0-9_-]*. INVALID NAME.")
endif()
if(NOT TARGET ${target})
message(FATAL_ERROR "${target} not found.")
diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake
index ad8ded29cf..54e7f4f50e 100644
--- a/cmake/QtInternalTargets.cmake
+++ b/cmake/QtInternalTargets.cmake
@@ -1,37 +1,38 @@
function(qt_internal_set_warnings_are_errors_flags target)
+ set(flags "")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# Regular clang 3.0+
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "3.0.0")
- target_compile_options("${target}" INTERFACE -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
+ list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
# using AppleClang
# Apple clang 4.0+
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL "9.2")
- target_compile_options("${target}" INTERFACE -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
+ list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
- target_compile_options("${target}" INTERFACE -Werror -Wno-error=cpp -Wno-error=deprecated-declarations)
+ list(APPEND flags -Werror -Wno-error=cpp -Wno-error=deprecated-declarations)
# GCC prints this bogus warning, after it has inlined a lot of code
# error: assuming signed overflow does not occur when assuming that (X + c) < X is always false
- target_compile_options("${target}" INTERFACE -Wno-error=strict-overflow)
+ list(APPEND flags -Wno-error=strict-overflow)
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs.
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0")
- target_compile_options("${target}" INTERFACE -Wno-error=implicit-fallthrough)
+ list(APPEND flags -Wno-error=implicit-fallthrough)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0.0")
# GCC 9 introduced these but we are not clean for it.
- target_compile_options("${target}" INTERFACE -Wno-error=deprecated-copy -Wno-error=redundant-move -Wno-error=init-list-lifetime)
+ list(APPEND flags -Wno-error=deprecated-copy -Wno-error=redundant-move -Wno-error=init-list-lifetime)
endif()
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
if (ANDROID)
- target_compile_options("${target}" INTERFACE -Wno-error=literal-suffix)
+ list(APPEND flags -Wno-error=literal-suffix)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# Intel CC 13.0 +, on Linux only
@@ -44,7 +45,7 @@ function(qt_internal_set_warnings_are_errors_flags target)
# 1786: function "entity" (declared at line N of "file") was declared deprecated ("message")
# 1881: argument must be a constant null pointer value
# (NULL in C++ is usually a literal 0)
- target_compile_options("${target}" INTERFACE -Werror -ww177,1224,1478,1786,1881)
+ list(APPEND flags -Werror -ww177,1224,1478,1786,1881)
endif()
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
@@ -52,9 +53,12 @@ function(qt_internal_set_warnings_are_errors_flags target)
# MSVC 2012, 2013, 2015.
# Respectively MSVC_VERRSIONs are: 1700-1799, 1800-1899, 1900-1909.
if(MSVC_VERSION GREATER_EQUAL 1700 AND MSVC_VERSION LESS_EQUAL 1909)
- target_compile_options("${target}" INTERFACE /WX)
+ list(APPEND flags /WX)
endif()
endif()
+ set(add_flags "$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
+ set(flags_generator_expression "$<${add_flags}:${flags}>")
+ target_compile_options("${target}" INTERFACE "${flags_generator_expression}")
endfunction()
add_library(PlatformCommonInternal INTERFACE)
@@ -96,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/QtModuleConfig.cmake.in b/cmake/QtModuleConfig.cmake.in
index f476c24913..b2e1511870 100644
--- a/cmake/QtModuleConfig.cmake.in
+++ b/cmake/QtModuleConfig.cmake.in
@@ -14,14 +14,11 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependenci
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
endif()
-# Guard against multiple inclusion of the plugins file in the same local directory scope.
-if(NOT TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target@)
- set(_QT_NEED_TO_INCLUDE_PLUGINS_@target@ TRUE)
-endif()
-
if (NOT QT_NO_CREATE_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
- include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
+ if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
+ endif()
endif()
foreach(extra_cmake_include @extra_cmake_includes@)
@@ -33,15 +30,24 @@ include(${_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir}/QtFeature.cmake)
qt_make_features_available(@QT_CMAKE_EXPORT_NAMESPACE@::@target@)
set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE)
-if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake"
- AND _QT_NEED_TO_INCLUDE_PLUGINS_@target@)
+if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
endif()
-unset(_QT_NEED_TO_INCLUDE_PLUGINS_@target@)
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
-get_target_property(_qt_module_plugin_types @INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
-if(_qt_module_plugin_types)
- list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
+get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
+if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
+ get_target_property(_qt_module_plugin_types
+ @INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
+ if(_qt_module_plugin_types)
+ list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
+ endif()
+endif()
+
+
+# Load Module's BuildIntenals should any exist
+if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
+ EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@BuildInternals.cmake")
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@BuildInternals.cmake")
endif()
diff --git a/cmake/QtModuleToolsConfig.cmake.in b/cmake/QtModuleToolsConfig.cmake.in
index 6d7ff9c8fa..79ca620c13 100644
--- a/cmake/QtModuleToolsConfig.cmake.in
+++ b/cmake/QtModuleToolsConfig.cmake.in
@@ -9,6 +9,9 @@ if (NOT QT_NO_CREATE_TARGETS)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
+ if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
+ include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
+ endif()
endif()
@extra_cmake_statements@
diff --git a/cmake/QtModuleToolsDependencies.cmake.in b/cmake/QtModuleToolsDependencies.cmake.in
index bac8bb0e04..46c60b8484 100644
--- a/cmake/QtModuleToolsDependencies.cmake.in
+++ b/cmake/QtModuleToolsDependencies.cmake.in
@@ -1,5 +1,5 @@
# Find "ModuleTools" dependencies, which are other ModuleTools packages.
-set(_tool_deps "@tool_deps@")
+set(_tool_deps "@package_deps@")
foreach(_target_dep ${_tool_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
@@ -9,7 +9,7 @@ foreach(_target_dep ${_tool_deps})
endif()
if (NOT ${pkg}_FOUND)
- set(@INSTALL_CMAKE_NAMESPACE@@target@Tools_FOUND FALSE)
+ set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
return()
endif()
endforeach()
diff --git a/cmake/QtModuleToolsVersionlessTargets.cmake.in b/cmake/QtModuleToolsVersionlessTargets.cmake.in
new file mode 100644
index 0000000000..6d0f57e039
--- /dev/null
+++ b/cmake/QtModuleToolsVersionlessTargets.cmake.in
@@ -0,0 +1,23 @@
+foreach(__qt_tool @tool_targets_non_prefixed@)
+ if(NOT TARGET Qt::${__qt_tool} AND TARGET Qt6::${__qt_tool})
+ add_executable(Qt::${__qt_tool} IMPORTED)
+
+ # Check all the usual imported location properties to find one that contains a path.
+ foreach(__qt_imported_location_config
+ IMPORTED_LOCATION
+ IMPORTED_LOCATION_RELEASE
+ IMPORTED_LOCATION_RELWITHDEBINFO
+ IMPORTED_LOCATION_MINSIZEREL
+ IMPORTED_LOCATION_DEBUG)
+
+ get_target_property(__qt_imported_location
+ Qt6::${__qt_tool} ${__qt_imported_location_config})
+ if(__qt_imported_location AND EXISTS "${__qt_imported_location}")
+ break()
+ endif()
+ endforeach()
+
+ set_target_properties(Qt::${__qt_tool}
+ PROPERTIES IMPORTED_LOCATION "${__qt_imported_location}")
+ endif()
+endforeach()
diff --git a/cmake/QtPlatformAndroid.cmake b/cmake/QtPlatformAndroid.cmake
index cb335da831..4b5bf6ff13 100644
--- a/cmake/QtPlatformAndroid.cmake
+++ b/cmake/QtPlatformAndroid.cmake
@@ -27,6 +27,18 @@ if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}")
message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}")
endif()
+# Get the Android SDK jar for an API version other than the one specified with
+# QT_ANDROID_API_VERSION.
+function(qt_get_android_sdk_jar_for_api api out_jar_location)
+ set(jar_location "${ANDROID_SDK_ROOT}/platforms/${api}/android.jar")
+ if (NOT EXISTS "${jar_location}")
+ message(WARNING "Could not locate Android SDK jar for api '${api}', defaulting to ${QT_ANDROID_API_VERSION}")
+ set(${out_jar_location} ${QT_ANDROID_JAR} PARENT_SCOPE)
+ else()
+ set(${out_jar_location} ${jar_location} PARENT_SCOPE)
+ endif()
+endfunction()
+
# Minimum recommend android SDK api version
set(QT_ANDROID_API_VERSION "android-21")
@@ -305,9 +317,62 @@ endfunction()
function(qt_android_apply_arch_suffix target)
get_target_property(target_type ${target} TYPE)
- if (target_type STREQUAL "SHARED_LIBRARY")
+ if (target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.so")
elseif (target_type STREQUAL "STATIC_LIBRARY")
set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.a")
endif()
endfunction()
+
+# Add custom target to package the APK
+function(qt_android_add_apk_target target)
+ get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE)
+ if (NOT deployment_file)
+ message(FATAL_ERROR "Target ${target} is not a valid android executable target\n")
+ endif()
+
+ set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt")
+ set(apk_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>/android-build")
+ add_custom_target(${target}_prepare_apk_dir
+ DEPENDS ${target}
+ COMMAND ${CMAKE_COMMAND}
+ -E copy $<TARGET_FILE:${target}>
+ "${apk_dir}/libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>"
+ COMMENT "Copying ${target} binarty to apk folder"
+ )
+
+ add_custom_target(${target}_make_apk
+ DEPENDS ${target}_prepare_apk_dir
+ COMMAND ${deployment_tool}
+ --input ${deployment_file}
+ --output ${apk_dir}
+ COMMENT "Creating APK for ${target}"
+ )
+endfunction()
+
+
+# Add a test for Android which will be run by the android test runner tool
+function(qt_android_add_test target)
+
+ set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt")
+ set(test_runner "${QT_HOST_PATH}/bin/androidtestrunner")
+
+ get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE)
+ if (NOT deployment_file)
+ message(FATAL_ERROR "Target ${target} is not a valid android executable target\n")
+ endif()
+
+ set(target_binary_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>")
+ set(apk_dir "${target_binary_dir}/android-build")
+
+ add_test(NAME "${target}"
+ COMMAND "${test_runner}"
+ --androiddeployqt "${deployment_tool} --input ${deployment_file}"
+ --adb "${ANDROID_SDK_ROOT}/platform-tools/adb"
+ --path "${apk_dir}"
+ --skip-install-root
+ --make "${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${target}_make_apk"
+ --apk "${apk_dir}/${target}.apk"
+ --verbose
+ )
+endfunction()
diff --git a/cmake/QtPlatformSupport.cmake b/cmake/QtPlatformSupport.cmake
index 2c5df77ba4..b54d52eba4 100644
--- a/cmake/QtPlatformSupport.cmake
+++ b/cmake/QtPlatformSupport.cmake
@@ -1,4 +1,4 @@
-function(set01 result)
+function(qt_set01 result)
if (${ARGN})
set("${result}" 1 PARENT_SCOPE)
else()
@@ -6,32 +6,32 @@ function(set01 result)
endif()
endfunction()
-set01(LINUX CMAKE_SYSTEM_NAME STREQUAL "Linux")
-set01(HPUX CMAKE_SYSTEM_NAME STREQUAL "HPUX")
-set01(ANDROID CMAKE_SYSTEM_NAME STREQUAL "Android") # FIXME: How to identify this?
-set01(NACL CMAKE_SYSTEM_NAME STREQUAL "NaCl") # FIXME: How to identify this?
-set01(INTEGRITY CMAKE_SYSTEM_NAME STREQUAL "Integrity") # FIXME: How to identify this?
-set01(VXWORKS CMAKE_SYSTEM_NAME STREQUAL "VxWorks") # FIXME: How to identify this?
-set01(QNX CMAKE_SYSTEM_NAME STREQUAL "QNX") # FIXME: How to identify this?
-set01(OPENBSD CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # FIXME: How to identify this?
-set01(FREEBSD CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FIXME: How to identify this?
-set01(NETBSD CMAKE_SYSTEM_NAME STREQUAL "NetBSD") # FIXME: How to identify this?
-set01(WASM CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+qt_set01(LINUX CMAKE_SYSTEM_NAME STREQUAL "Linux")
+qt_set01(HPUX CMAKE_SYSTEM_NAME STREQUAL "HPUX")
+qt_set01(ANDROID CMAKE_SYSTEM_NAME STREQUAL "Android") # FIXME: How to identify this?
+qt_set01(NACL CMAKE_SYSTEM_NAME STREQUAL "NaCl") # FIXME: How to identify this?
+qt_set01(INTEGRITY CMAKE_SYSTEM_NAME STREQUAL "Integrity") # FIXME: How to identify this?
+qt_set01(VXWORKS CMAKE_SYSTEM_NAME STREQUAL "VxWorks") # FIXME: How to identify this?
+qt_set01(QNX CMAKE_SYSTEM_NAME STREQUAL "QNX") # FIXME: How to identify this?
+qt_set01(OPENBSD CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # FIXME: How to identify this?
+qt_set01(FREEBSD CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FIXME: How to identify this?
+qt_set01(NETBSD CMAKE_SYSTEM_NAME STREQUAL "NetBSD") # FIXME: How to identify this?
+qt_set01(WASM CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
-set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
+qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
-set01(WINRT WIN32 AND CMAKE_VS_PLATFORM_TOOSLET STREQUAL "winrt") # FIXME: How to identify this?
+qt_set01(WINRT WIN32 AND CMAKE_VS_PLATFORM_TOOSLET STREQUAL "winrt") # FIXME: How to identify this?
-set01(APPLE_OSX APPLE) # FIXME: How to identify this? For now assume that always building for macOS.
-set01(APPLE_UIKIT APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "uikit") # FIXME: How to identify this?
-set01(APPLE_IOS APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "ios") # FIXME: How to identify this?
-set01(APPLE_TVOS APPLE AND CMAKE_XCODE_PLATFORM_TOOLSET STREQUAL "tvos") # FIXME: How to identify this?
-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)
-set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-set01(CLANG CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-set01(ICC CMAKE_C_COMPILER MATCHES "icc|icl")
-set01(QCC CMAKE_C_COMPILER MATCHES "qcc") # FIXME: How to identify this?
+qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+qt_set01(CLANG CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+qt_set01(ICC CMAKE_C_COMPILER MATCHES "icc|icl")
+qt_set01(QCC CMAKE_C_COMPILER MATCHES "qcc") # FIXME: How to identify this?
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(QT_64BIT TRUE)
diff --git a/cmake/QtPluginConfig.cmake.in b/cmake/QtPluginConfig.cmake.in
index ab812abcf2..5fde0bc511 100644
--- a/cmake/QtPluginConfig.cmake.in
+++ b/cmake/QtPluginConfig.cmake.in
@@ -1,3 +1,5 @@
+include_guard(DIRECTORY)
+
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
diff --git a/cmake/QtPlugins.cmake.in b/cmake/QtPlugins.cmake.in
index fb87a54c0d..91884302c6 100644
--- a/cmake/QtPlugins.cmake.in
+++ b/cmake/QtPlugins.cmake.in
@@ -1,3 +1,5 @@
+include_guard(DIRECTORY)
+
@QT_MODULE_PLUGIN_INCLUDES@
if(NOT @BUILD_SHARED_LIBS@)
@@ -17,9 +19,22 @@ if(NOT @BUILD_SHARED_LIBS@)
set(_manual_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS>>")
set(_no_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_NO_PLUGINS>>")
+ # In super builds the rules below pollute the dependency rule for the
+ # plugin target when it's being build, causing cyclic dependencies.
+ # to overcome this, we check if the current target where this rule evaluates
+ # has a QT_BUILD_PROJECT_NAME equal to the current PROJECT_NAME.
+ # If so we disable the injection of plugin link rules to avoid cyclic
+ # dependencies.
+ if (@QT_SUPERBUILD@)
+ set(_build_allow_plugin_link_rules_genex "$<NOT:$<STREQUAL:$<TARGET_PROPERTY:QT_BUILD_PROJECT_NAME>,@PROJECT_NAME@>>")
+ else()
+ set(_build_allow_plugin_link_rules_genex 1)
+ endif()
+
# The code in here uses the properties defined in qt_import_plugins (Qt6CoreMacros.cmake)
foreach(target @qt_plugins@)
set(_plugin_target "@INSTALL_CMAKE_NAMESPACE@::${target}")
+ set(_plugin_target_versionless "Qt::${target}")
get_target_property(_classname "${_plugin_target}" QT_PLUGIN_CLASS_NAME)
if(NOT _classname)
message("Warning: plugin ${_plugin_target} has no class name, skipping.")
@@ -38,6 +53,8 @@ if(NOT @BUILD_SHARED_LIBS@)
# INCLUDE
set(_plugin_is_whitelisted "$<IN_LIST:${_plugin_target},${_manual_plugins_genex}>")
+ set(_plugin_versionless_is_whitelisted
+ "$<IN_LIST:${_plugin_target_versionless},${_manual_plugins_genex}>")
# Note: qt_import_plugins sets the QT_PLUGINS_${_plugin_type} to "-"
# when excluding it with EXCLUDE_BY_TYPE,
@@ -47,7 +64,11 @@ if(NOT @BUILD_SHARED_LIBS@)
"$<NOT:" # EXCLUDE
"$<IN_LIST:${_plugin_target},${_no_plugins_genex}>"
">,"
- # excludes both plugins targeted by EXCLUDE_BY_TYPE and not included in INCLUDE_BY_TYPE
+ "$<NOT:"
+ "$<IN_LIST:${_plugin_target_versionless},${_no_plugins_genex}>"
+ ">,"
+ # Excludes both plugins targeted by EXCLUDE_BY_TYPE and not included in
+ # INCLUDE_BY_TYPE.
"$<STREQUAL:,$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>>>"
">"
)
@@ -61,16 +82,29 @@ if(NOT @BUILD_SHARED_LIBS@)
">"
">"
)
+ string(CONCAT _plugin_versionless_is_in_type_whitelist
+ "$<IN_LIST:"
+ "${_plugin_target_versionless},"
+ "$<GENEX_EVAL:"
+ "$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
+ ">"
+ ">"
+ )
# Complete condition that defines whether a static plugin is linked
string(CONCAT _plugin_condition
- "$<BOOL:$<OR:"
- "${_plugin_is_whitelisted},"
- "${_plugin_is_in_type_whitelist},"
- "$<AND:"
- "${_default_plugins_are_enabled_wrapped},"
- "${_plugin_is_default},"
- "${_plugin_is_not_blacklisted}"
+ "$<BOOL:$<AND:"
+ "${_build_allow_plugin_link_rules_genex},"
+ "$<OR:"
+ "${_plugin_is_whitelisted},"
+ "${_plugin_versionless_is_whitelisted},"
+ "${_plugin_is_in_type_whitelist},"
+ "${_plugin_versionless_is_in_type_whitelist},"
+ "$<AND:"
+ "${_default_plugins_are_enabled_wrapped},"
+ "${_plugin_is_default},"
+ "${_plugin_is_not_blacklisted}"
+ ">"
">"
">>"
)
diff --git a/cmake/QtPostProcess.cmake b/cmake/QtPostProcess.cmake
index ffa367cb9e..19cd4b699b 100644
--- a/cmake/QtPostProcess.cmake
+++ b/cmake/QtPostProcess.cmake
@@ -1,6 +1,6 @@
function(qt_internal_write_depends_file target)
set(module Qt${target})
- set(outfile "${QT_BUILD_DIR}/include/${module}/${module}Depends")
+ set(outfile "${QT_BUILD_DIR}/${INSTALL_INCLUDEDIR}/${module}/${module}Depends")
message("Generate ${outfile}...")
set(contents "/* This file was generated by cmake with the info from ${module} target. */\n")
string(APPEND contents "#ifdef __cplusplus /* create empty PCH in C mode */\n")
@@ -68,9 +68,11 @@ function(qt_internal_create_module_depends_file target)
set(arg_HEADER_MODULE OFF)
endif()
- if(NOT arg_HEADER_MODULE)
+ set(depends "")
+ if(target_type STREQUAL "STATIC_LIBRARY" AND NOT arg_HEADER_MODULE)
get_target_property(depends "${target}" LINK_LIBRARIES)
endif()
+
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
# Used for collecting Qt module dependencies that should be find_package()'d in
@@ -82,7 +84,7 @@ function(qt_internal_create_module_depends_file target)
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
endif()
if(NOT extra_depends STREQUAL "${extra_depends}-NOTFOUND")
- list(APPEND target_deps ${extra_depends})
+ list(APPEND target_deps "${extra_depends}")
endif()
# Used for assembling the content of an include/Module/ModuleDepends.h header.
@@ -183,23 +185,8 @@ function(qt_internal_create_module_depends_file target)
endif()
if(tool_deps)
- set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}Tools")
- qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
- qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
-
- # Configure and install ModuleToolDependencies file.
- configure_file(
- "${QT_CMAKE_DIR}/QtModuleToolsDependencies.cmake.in"
- "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ToolsDependencies.cmake"
- @ONLY
- )
-
- qt_install(FILES
- "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ToolsDependencies.cmake"
- DESTINATION "${config_install_dir}"
- COMPONENT Devel
- )
-
+ # The value of the property will be used by qt_export_tools.
+ set_property(TARGET "${target}" PROPERTY _qt_tools_package_deps "${tool_deps}")
endif()
endfunction()
@@ -313,8 +300,7 @@ endfunction()
function(qt_generate_build_internals_extra_cmake_code)
if(PROJECT_NAME STREQUAL "QtBase")
- set(QT_EXTRA_BUILD_INTERNALS_VARS)
- foreach(var IN LISTS qt_base_configure_tests_vars_to_export)
+ foreach(var IN LISTS QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "set(${var} \"${${var}}\" CACHE INTERNAL \"\")\n")
endforeach()
@@ -322,6 +308,36 @@ function(qt_generate_build_internals_extra_cmake_code)
qt_path_join(extra_file_path
${QT_CONFIG_BUILD_DIR}
${INSTALL_CMAKE_NAMESPACE}BuildInternals/QtBuildInternalsExtra.cmake)
+
+ if(CMAKE_BUILD_TYPE)
+ # Need to force set, because CMake itself initializes a value for CMAKE_BUILD_TYPE
+ # at the start of project configuration (with an empty value),
+ # so we need to force override it.
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\" CACHE STRING \"Choose the type of build.\" FORCE)\n")
+
+ endif()
+ if(CMAKE_CONFIGURATION_TYPES)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_CONFIGURATION_TYPES \"${CMAKE_CONFIGURATION_TYPES}\")\n")
+ endif()
+ if(CMAKE_TRY_COMPILE_CONFIGURATION)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_TRY_COMPILE_CONFIGURATION \"${CMAKE_TRY_COMPILE_CONFIGURATION}\")\n")
+ endif()
+ if(QT_MULTI_CONFIG_FIRST_CONFIG)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(QT_MULTI_CONFIG_FIRST_CONFIG \"${QT_MULTI_CONFIG_FIRST_CONFIG}\")\n")
+ endif()
+ if(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE \"${CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE}\")\n")
+ endif()
+ if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
+ string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
+ "set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE \"${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}\")\n")
+ endif()
+
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake.in"
"${extra_file_path}"
@@ -346,10 +362,45 @@ function(qt_create_tools_config_files)
endforeach()
endfunction()
-qt_create_tools_config_files()
+function(qt_internal_create_config_file_for_standalone_tests)
+ set(standalone_tests_config_dir "StandaloneTests")
+ qt_path_join(config_build_dir
+ ${QT_CONFIG_BUILD_DIR}
+ "${INSTALL_CMAKE_NAMESPACE}BuildInternals" "${standalone_tests_config_dir}")
+ qt_path_join(config_install_dir
+ ${QT_CONFIG_INSTALL_DIR}
+ "${INSTALL_CMAKE_NAMESPACE}BuildInternals" "${standalone_tests_config_dir}")
+
+ list(JOIN QT_REPO_KNOWN_MODULES " " QT_REPO_KNOWN_MODULES_STRING)
+ string(STRIP "${QT_REPO_KNOWN_MODULES_STRING}" QT_REPO_KNOWN_MODULES_STRING)
+
+ # Skip generating and installing file if no modules were built. This make sure not to install
+ # anything when build qtx11extras on macOS for example.
+ if(NOT QT_REPO_KNOWN_MODULES_STRING)
+ return()
+ endif()
+
+ # Ceate a Config file that calls find_package on the modules that were built as part
+ # of the current repo. This is used for standalone tests.
+ configure_file(
+ "${QT_CMAKE_DIR}/QtStandaloneTestsConfig.cmake.in"
+ "${config_build_dir}/${PROJECT_NAME}TestsConfig.cmake"
+ @ONLY
+ )
+ qt_install(FILES
+ "${config_build_dir}/${PROJECT_NAME}TestsConfig.cmake"
+ DESTINATION "${config_install_dir}"
+ COMPONENT Devel
+ )
+endfunction()
+
qt_internal_create_depends_files()
qt_generate_build_internals_extra_cmake_code()
qt_internal_create_plugins_files()
+qt_internal_create_config_file_for_standalone_tests()
+
+# Needs to run after qt_internal_create_depends_files.
+qt_create_tools_config_files()
if (ANDROID)
qt_modules_process_android_dependencies()
diff --git a/cmake/QtProperties.cmake b/cmake/QtProperties.cmake
index 5e2d6f0545..a12fa53252 100644
--- a/cmake/QtProperties.cmake
+++ b/cmake/QtProperties.cmake
@@ -93,7 +93,7 @@ define_property(TARGET
BRIEF_DOCS
"Specifies the default Qt resource prefix."
FULL_DOCS
- "When using add_qt_resource() without a PREFIX, then prefix of this target property
+ "When using qt_add_resource() without a PREFIX, then prefix of this target property
will be used."
)
diff --git a/cmake/QtResource.cmake.in b/cmake/QtResource.cmake.in
index 335cbde33c..bef47707ea 100644
--- a/cmake/QtResource.cmake.in
+++ b/cmake/QtResource.cmake.in
@@ -28,7 +28,7 @@ function(__qt_propagate_generated_resource target resource_name generated_source
endif()
endfunction()
-# Inspect all files passed to a call to add_qt_resource. If there are any
+# Inspect all files passed to a call to qt_add_resource. If there are any
# files present, invoke the quick compiler and return the remaining resource
# files that have not been processed in OUTPUT_REMAINING_RESOURCES as well as the new
# name for the resource in OUTPUT_RESOURCE_NAME.
@@ -40,13 +40,11 @@ function(__qt_quick_compiler_process_resources target resource_name)
set(qml_files)
set(resource_files)
- set(retained_files)
# scan for qml files
foreach(file IN LISTS arg_FILES)
# check whether this resource should not be processed by the qt quick
# compiler
get_source_file_property(skip_compiler_check ${file} QT_SKIP_QUICKCOMPILER)
- get_source_file_property(retain_compiler_check ${file} QT_RETAIN_QUICKCOMPILER)
if (skip_compiler_check)
list(APPEND resource_files ${file})
continue()
@@ -56,19 +54,13 @@ function(__qt_quick_compiler_process_resources target resource_name)
OR ${file} MATCHES "\.mjs$"
OR ${file} MATCHES "\.qml$")
list(APPEND qml_files ${file})
- if (retain_compiler_check)
- list(APPEND retained_files ${file})
- list(APPEND resource_files ${file})
- endif()
- else()
- list(APPEND resource_files ${file})
endif()
+ list(APPEND resource_files ${file})
endforeach()
if (NOT TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
message(WARNING "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE: Qml files were detected but the qmlcachgen target is not defined. Consider adding QmlTools to your find_package command.")
endif()
- set(retained_resource_paths)
if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
# Enable qt quick compiler support
set(qml_resource_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/${resource_name}.qrc")
@@ -86,9 +78,6 @@ function(__qt_quick_compiler_process_resources target resource_name)
else()
set(file_resource_path "${arg_PREFIX}/${file_resource_path}")
endif()
- if (file IN_LIST retained_files)
- list(APPEND retained_resource_paths ${file_resource_path})
- endif()
file(TO_CMAKE_PATH ${file_resource_path} file_resource_path)
list(APPEND file_resource_paths ${file_resource_path})
string(REGEX REPLACE "\.js$" "_js" compiled_file ${file_relative})
@@ -102,13 +91,15 @@ function(__qt_quick_compiler_process_resources target resource_name)
endif()
add_custom_command(
OUTPUT ${compiled_file}
- DEPENDS ${file_absolute}
${QT_TOOL_PATH_SETUP_COMMAND}
COMMAND
@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
- --resource-path ${file_resource_path}
- -o ${compiled_file}
- ${file_absolute}
+ --resource-path "${file_resource_path}"
+ -o "${compiled_file}"
+ "${file_absolute}"
+ DEPENDS
+ $<TARGET_FILE:@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen>
+ "${file_absolute}"
)
target_sources(${target} PRIVATE ${compiled_file})
endforeach()
@@ -125,25 +116,17 @@ function(__qt_quick_compiler_process_resources target resource_name)
set(resource_name_arg "${resource_name_arg}=${chained_resource_name}")
endif()
- if (retained_resource_paths)
- set(retained_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/retained_file_list.rsp")
- file(GENERATE
- OUTPUT ${retained_loader_list}
- CONTENT "$<JOIN:${retained_resource_paths},\n>"
- )
- set(retained_args "--retain" "@${retained_loader_list}")
- endif()
-
add_custom_command(
OUTPUT ${qmlcache_loader_file}
- DEPENDS ${qmlcache_loader_list}
${QT_TOOL_PATH_SETUP_COMMAND}
COMMAND
@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
- ${retained_args}
--resource-name "${resource_name_arg}"
- -o ${qmlcache_loader_file}
+ -o "${qmlcache_loader_file}"
"@${qmlcache_loader_list}"
+ DEPENDS
+ $<TARGET_FILE:@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen>
+ "${qmlcache_loader_list}"
)
__qt_propagate_generated_resource(${target}
@@ -293,7 +276,10 @@ function(QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE target resourceName)
add_custom_command(OUTPUT "${generatedSourceCode}"
COMMAND "@QT_CMAKE_EXPORT_NAMESPACE@::rcc"
ARGS ${rccArgs}
- DEPENDS ${resource_dependencies} ${generatedResourceFile}
+ DEPENDS
+ ${resource_dependencies}
+ ${generatedResourceFile}
+ "@QT_CMAKE_EXPORT_NAMESPACE@::rcc"
COMMENT "RCC ${newResourceName}"
VERBATIM)
diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake
index 16fd9b7520..90588c99b3 100644
--- a/cmake/QtSetup.cmake
+++ b/cmake/QtSetup.cmake
@@ -10,10 +10,22 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(_default_build_type "Debug")
endif()
+# Reset content of extra build internal vars for each inclusion of QtSetup.
+unset(QT_EXTRA_BUILD_INTERNALS_VARS)
+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${_default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values of build type for cmake-gui
+ set_property(CACHE CMAKE_BUILD_TYPE
+ PROPERTY STRINGS
+ "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values for cmake-gui.
+elseif(CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Building for multiple configurations: ${CMAKE_CONFIGURATION_TYPES}.")
+ message(STATUS "Main configuration is: ${QT_MULTI_CONFIG_FIRST_CONFIG}.")
+ if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
+ message(STATUS
+ "Default build configuration set to '${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}'.")
+ endif()
endif()
# Appends a 'debug postfix' to library targets (not executables)
@@ -24,11 +36,6 @@ elseif(APPLE)
set(CMAKE_DEBUG_POSTFIX "_debug")
endif()
-## Force C++ standard, do not fall back, do not use compiler extensions
-set(CMAKE_CXX_STANDARD 14)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
## Position independent code:
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@@ -44,7 +51,7 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# or when enabling developer builds and no prefix is specified.
# This detection only happens when building qtbase, and later is propagated via the generated
# QtBuildInternalsExtra.cmake file.
-if (PROJECT_NAME STREQUAL "QtBase")
+if (PROJECT_NAME STREQUAL "QtBase" AND NOT QT_BUILD_STANDALONE_TESTS)
if((CMAKE_INSTALL_PREFIX STREQUAL CMAKE_BINARY_DIR) OR
(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND FEATURE_developer_build))
@@ -78,24 +85,62 @@ if(FEATURE_developer_build)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()
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)
+ set(__build_benchmarks OFF)
+ endif()
else()
set(QT_BUILD_TESTING OFF)
+ set(__build_benchmarks OFF)
endif()
## Set up testing
option(BUILD_TESTING "Build the testing tree." ${QT_BUILD_TESTING})
+if(QT_BUILD_STANDALONE_TESTS)
+ set(QT_BUILD_TESTING ON)
+
+ # BuildInternals might have set it to OFF on initial configuration. So force it to ON when
+ # building standalone tests.
+ set(BUILD_TESTING ON CACHE BOOL "Build the testing tree." FORCE)
+
+ # Also force the tests to be built as part of the default build target.
+ set(QT_NO_MAKE_TESTS OFF CACHE BOOL
+ "Should examples be built as part of the default 'all' target." FORCE)
+endif()
+option(QT_NO_MAKE_TESTS "Should tests be built as part of the default 'all' target." OFF)
+
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
+option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks})
## Android platform settings
if(ANDROID)
include(QtPlatformAndroid)
endif()
-## add_qt_module and co.:
+## qt_add_module and co.:
include(QtBuild)
## Qt Feature support:
@@ -110,6 +155,8 @@ include(QtCompilerFlags)
## Set up non-prefix build:
qt_set_up_nonprefix_build()
+qt_set_language_standards()
+
## Find host tools (if non native):
set(QT_HOST_PATH "" CACHE PATH "Installed Qt host directory path, used for cross compiling.")
diff --git a/cmake/QtStandaloneTestsConfig.cmake.in b/cmake/QtStandaloneTestsConfig.cmake.in
new file mode 100644
index 0000000000..3d08ae0c12
--- /dev/null
+++ b/cmake/QtStandaloneTestsConfig.cmake.in
@@ -0,0 +1,2 @@
+find_package(@INSTALL_CMAKE_NAMESPACE@ @PROJECT_VERSION@
+ REQUIRED COMPONENTS @QT_REPO_KNOWN_MODULES_STRING@)
diff --git a/cmake/README.md b/cmake/README.md
index 5739b900f7..6b65f0e69a 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -114,8 +114,10 @@ install:
QMake defines most features in configure.json files, like -developer-build or -no-opengl.
-In CMake land, we currently generate configure.cmake files from the configure.json files. If the
-feature in configure.json has the name "dlopen", you can specify whether to enable or disable that
+In CMake land, we currently generate configure.cmake files from the configure.json files into
+the source directory next to them using the helper script
+``path_to_qtbase_source/util/cmake/configurejson2cmake.py``. They are checked into the repository.
+If the feature in configure.json has the name "dlopen", you can specify whether to enable or disable that
feature in CMake with a -D flag on the CMake command line. So for example -DFEATURE_dlopen=ON or
-DFEATURE_sql_mysql=OFF. At the moment, if you change a FEATURE flag's value, you have to remove the
CMakeCache.txt file and reconfigure with CMake. And even then you might stumble on some issues when
@@ -201,7 +203,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 +211,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
@@ -235,7 +288,7 @@ top-level source directory of a Qt repository.
``pro2cmake.py`` generates a skeleton CMakeLists.txt file from a .pro-file. You will need to polish
the resulting CMakeLists.txt file, but e.g. the list of files, etc. should be extracted for you.
-``pro2cmake.py`` is run like this: ``/path/to/pro2cmake.py some.pro``.
+``pro2cmake.py`` is run like this: ``path_to_qtbase_source/util/cmake/pro2cmake.py some.pro``.
## run_pro2cmake.py
@@ -243,7 +296,7 @@ the resulting CMakeLists.txt file, but e.g. the list of files, etc. should be ex
`` A small helper script to run pro2cmake.py on all .pro-files in a directory. Very useful to e.g.
convert all the unit tests for a Qt module over to cmake;-)
-``run_pro2cmake.py`` is run like this: ``/path/to/run_pro2cmake.py some_dir``.
+``run_pro2cmake.py`` is run like this: ``path_to_qtbase_source/util/cmake/run_pro2cmake.py some_dir``.
## How to convert certain constructs