qt 6.6.0 clean

This commit is contained in:
kleuter
2023-11-01 22:23:55 +01:00
parent 7b5ada15e7
commit 5d8194efa7
1449 changed files with 134276 additions and 31391 deletions

98
cmake/FindMimer.cmake Normal file
View File

@ -0,0 +1,98 @@
# Copyright (C) 2022 The Qt Company Ltd.
# Copyright (C) 2022 Mimer Information Technology
# SPDX-License-Identifier: BSD-3-Clause
# FindMimer
# ---------
# Try to locate the Mimer SQL client library
if(NOT DEFINED MimerSQL_ROOT)
if(DEFINED ENV{MIMERSQL_DEV_ROOT})
set(MimerSQL_ROOT "$ENV{MIMERSQL_DEV_ROOT}")
endif()
endif()
if(NOT DEFINED MimerSQL_ROOT)
find_package(PkgConfig QUIET)
endif()
if(PkgConfig_FOUND AND NOT DEFINED MimerSQL_ROOT)
pkg_check_modules(PC_Mimer QUIET mimcontrol)
set(MimerSQL_include_dir_hints "${PC_MimerSQL_INCLUDEDIR}")
set(MimerSQL_library_hints "${PC_MimerSQL_LIBDIR}")
else()
if(DEFINED MimerSQL_ROOT)
if(WIN32)
set(MimerSQL_include_dir_hints "${MimerSQL_ROOT}\\include")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MimerSQL_library_hints "${MimerSQL_ROOT}\\lib\\x86")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MimerSQL_library_hints "${MimerSQL_ROOT}\\lib\\amd64")
else()
set(MimerSQL_library_hints "")
endif()
else()
set(MimerSQL_include_dir_hints "${MimerSQL_ROOT}/include")
set(MimerSQL_library_hints "${MimerSQL_ROOT}/lib")
endif()
else()
if(WIN32)
set(MimerSQL_include_dir_hints "C:\\MimerSQLDev\\include")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MimerSQL_library_hints "C:\\MimerSQLDev\\lib\\x86")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MimerSQL_library_hints "C:\\MimerSQLDev\\lib\\amd64")
else()
set(MimerSQL_library_hints "")
endif()
elseif(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(MimerSQL_library_hints "/usr/local/lib")
set(MimerSQL_include_dir_hints "/usr/local/include")
else()
set(MimerSQL_include_dir_hints "")
set(MimerSQL_library_hints "")
endif()
endif()
endif()
find_path(Mimer_INCLUDE_DIR
NAMES mimerapi.h
HINTS ${MimerSQL_include_dir_hints})
if(WIN32)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MIMER_LIBS_NAMES mimapi32)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MIMER_LIBS_NAMES mimapi64)
endif()
else()
set(MIMER_LIBS_NAMES mimerapi)
endif()
find_library(Mimer_LIBRARIES
NAMES ${MIMER_LIBS_NAMES}
HINTS ${MimerSQL_library_hints})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Mimer
REQUIRED_VARS Mimer_LIBRARIES Mimer_INCLUDE_DIR)
# Now try to get the include and library path.
if(Mimer_FOUND)
set(Mimer_INCLUDE_DIRS ${Mimer_INCLUDE_DIR})
set(Mimer_LIBRARY_DIRS ${Mimer_LIBRARIES})
if (NOT TARGET MimerSQL::MimerSQL)
add_library(MimerSQL::MimerSQL UNKNOWN IMPORTED)
set_target_properties(MimerSQL::MimerSQL PROPERTIES
IMPORTED_LOCATION "${Mimer_LIBRARY_DIRS}"
INTERFACE_INCLUDE_DIRECTORIES "${Mimer_INCLUDE_DIRS}")
endif ()
endif()
mark_as_advanced(Mimer_INCLUDE_DIR Mimer_LIBRARIES)
include(FeatureSummary)
set_package_properties(MimerSQL PROPERTIES
URL "https://www.mimer.com"
DESCRIPTION "Mimer client library")

View File

@ -0,0 +1,53 @@
# Copyright (C) 2022 The Qt Company Ltd.
# Copyright (C) 2023 Intel Corpotation.
# SPDX-License-Identifier: BSD-3-Clause
# 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 WrapResolv::WrapResolv)
set(WrapResolv_FOUND ON)
return()
endif()
set(WrapResolv_FOUND OFF)
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
if(QNX)
find_library(LIBRESOLV socket)
else()
find_library(LIBRESOLV resolv)
endif()
cmake_push_check_state()
if(LIBRESOLV)
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBRESOLV}")
endif()
check_cxx_source_compiles("
#include <netinet/in.h>
#include <resolv.h>
int main(int, char **argv)
{
res_state statep;
int n = res_nmkquery(statep, 0, argv[1], 0, 0, NULL, 0, NULL, NULL, 0);
n = res_nsend(statep, NULL, 0, NULL, 0);
n = dn_expand(NULL, NULL, NULL, NULL, 0);
return n;
}
" HAVE_LIBRESOLV_FUNCTIONS)
cmake_pop_check_state()
if(HAVE_LIBRESOLV_FUNCTIONS)
set(WrapResolv_FOUND ON)
add_library(WrapResolv::WrapResolv INTERFACE IMPORTED)
if(LIBRESOLV)
target_link_libraries(WrapResolv::WrapResolv INTERFACE "${LIBRESOLV}")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WrapResolv DEFAULT_MSG WrapResolv_FOUND)

View File

@ -21,17 +21,31 @@ if(LIBRT)
endif()
check_cxx_source_compiles("
#include <unistd.h>
#include <time.h>
#include <unistd.h>
int main(int, char **) {
timespec ts; clock_gettime(CLOCK_REALTIME, &ts);
}" HAVE_GETTIME)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return 0;
}
" HAVE_GETTIME)
check_cxx_source_compiles("
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int, char **) {
shm_open(\"test\", O_RDWR | O_CREAT | O_EXCL, 0666);
shm_unlink(\"test\");
return 0;
}
" HAVE_SHM_OPEN_SHM_UNLINK)
cmake_pop_check_state()
if(HAVE_GETTIME)
if(HAVE_GETTIME OR HAVE_SHM_OPEN_SHM_UNLINK)
set(WrapRt_FOUND ON)
add_library(WrapRt::WrapRt INTERFACE IMPORTED)
if (LIBRT)

View File

@ -48,6 +48,26 @@ if(Vulkan_INCLUDE_DIR)
target_include_directories(WrapVulkanHeaders::WrapVulkanHeaders INTERFACE
${__qt_molten_vk_homebrew_include_path})
endif()
# Check for homebrew vulkan-headers folder structure
# If instead of molten-vk folder, CMAKE_PREFIX_PATH points to Homebrew's
# vulkan-headers installation, then we will not be able to find molten-vk
# headers. If we assume that user has installed the molten-vk formula as
# well, then we might have a chance to pick it up like this.
if(Vulkan_INCLUDE_DIR MATCHES "/homebrew/Cellar/")
set(__qt_standalone_molten_vk_homebrew_include_path
"${Vulkan_INCLUDE_DIR}/../../../../opt/molten-vk/include")
else()
set(__qt_standalone_molten_vk_homebrew_include_path
"${Vulkan_INCLUDE_DIR}/../../molten-vk/include")
endif()
get_filename_component(
__qt_standalone_molten_vk_homebrew_include_path
"${__qt_standalone_molten_vk_homebrew_include_path}" ABSOLUTE)
if(EXISTS "${__qt_standalone_molten_vk_homebrew_include_path}")
target_include_directories(WrapVulkanHeaders::WrapVulkanHeaders INTERFACE
${__qt_standalone_molten_vk_homebrew_include_path})
endif()
endif()
endif()

View File

@ -28,10 +28,10 @@ include(FindPackageHandleStandardArgs)
if(TARGET zstd::libzstd_static OR TARGET zstd::libzstd_shared)
find_package_handle_standard_args(WrapZSTD
REQUIRED_VARS zstd_VERSION VERSION_VAR zstd_VERSION)
if(TARGET zstd::libzstd_static)
set(zstdtargetsuffix "_static")
else()
if(TARGET zstd::libzstd_shared)
set(zstdtargetsuffix "_shared")
else()
set(zstdtargetsuffix "_static")
endif()
if(NOT TARGET WrapZSTD::WrapZSTD)
add_library(WrapZSTD::WrapZSTD INTERFACE IMPORTED)

View File

@ -7,6 +7,7 @@
"compiler_target": "${CMAKE_CXX_COMPILER_TARGET}",
"compiler_version": "${CMAKE_CXX_COMPILER_VERSION}",
"cross_compiled": ${cross_compilation},
"target_system": "${CMAKE_SYSTEM_NAME}"
"target_system": "${CMAKE_SYSTEM_NAME}",
"architecture": "${TEST_architecture_arch}"
}
}

View File

@ -8,6 +8,9 @@
# Make sure to not run detection when building standalone tests, because the detection was already
# done when initially configuring qtbase.
# This needs to be here because QtAutoDetect loads before any other modules
option(QT_USE_VCPKG "Enable the use of vcpkg" ON)
function(qt_internal_ensure_static_qt_config)
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Qt statically or dynamically" FORCE)
@ -161,7 +164,7 @@ function(qt_auto_detect_android)
endfunction()
function(qt_auto_detect_vcpkg)
if(DEFINED ENV{VCPKG_ROOT})
if(QT_USE_VCPKG AND DEFINED ENV{VCPKG_ROOT})
set(vcpkg_toolchain_file "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
get_filename_component(vcpkg_toolchain_file "${vcpkg_toolchain_file}" ABSOLUTE)
@ -174,8 +177,8 @@ function(qt_auto_detect_vcpkg)
endif()
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_toolchain_file}" CACHE STRING "" FORCE)
message(STATUS "Using vcpkg from $ENV{VCPKG_ROOT}")
if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
if(DEFINED ENV{QT_VCPKG_TARGET_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{QT_VCPKG_TARGET_TRIPLET}" CACHE STRING "")
message(STATUS "Using vcpkg triplet ${VCPKG_TARGET_TRIPLET}")
endif()
unset(vcpkg_toolchain_file)
@ -229,7 +232,9 @@ function(qt_auto_detect_ios)
endif()
set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "")
qt_internal_ensure_static_qt_config()
if(NOT DEFINED BUILD_SHARED_LIBS)
qt_internal_ensure_static_qt_config()
endif()
# Disable qt rpaths for iOS, just like mkspecs/common/uikit.conf does, due to those
# bundles not being able to use paths outside the app bundle. Not sure this is strictly
@ -239,7 +244,15 @@ function(qt_auto_detect_ios)
endfunction()
function(qt_auto_detect_cmake_config)
if(CMAKE_CONFIGURATION_TYPES)
# If CMAKE_CONFIGURATION_TYPES are not set for the multi-config generator use Release and
# Debug configurations by default, instead of those are proposed by the CMake internal logic.
get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(is_multi)
if(NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Release Debug)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" PARENT_SCOPE)
endif()
# Allow users to specify this option.
if(NOT QT_MULTI_CONFIG_FIRST_CONFIG)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
@ -476,6 +489,12 @@ function(qt_auto_detect_integrity)
endif()
endfunction()
# Save the build type before project() might set one.
# This allows us to determine if the user has set an explicit build type that we should use.
function(qt_auto_detect_cmake_build_type)
set(__qt_auto_detect_cmake_build_type_before_project_call "${CMAKE_BUILD_TYPE}" PARENT_SCOPE)
endfunction()
# Let CMake load our custom platform modules.
# CMake-provided platform modules take precedence.
if(NOT QT_AVOID_CUSTOM_PLATFORM_MODULES)
@ -495,3 +514,4 @@ qt_auto_detect_wasm()
qt_auto_detect_win32_arm()
qt_auto_detect_linux_x86()
qt_auto_detect_integrity()
qt_auto_detect_cmake_build_type()

View File

@ -216,6 +216,7 @@ qt_copy_or_install(FILES
cmake/QtAndroidHelpers.cmake
cmake/QtAppHelpers.cmake
cmake/QtAutogenHelpers.cmake
cmake/QtBaseTopLevelHelpers.cmake
cmake/QtBuild.cmake
cmake/QtBuildInformation.cmake
cmake/QtCMakeHelpers.cmake
@ -332,6 +333,7 @@ set(__public_cmake_helpers
cmake/QtCopyFileIfDifferent.cmake
cmake/QtFeature.cmake
cmake/QtFeatureCommon.cmake
cmake/QtInitProject.cmake
cmake/QtPublicAppleHelpers.cmake
cmake/QtPublicCMakeHelpers.cmake
cmake/QtPublicCMakeVersionHelpers.cmake
@ -395,17 +397,30 @@ if(QT_WILL_INSTALL)
)
endif()
if(MACOS)
qt_copy_or_install(FILES
cmake/macos/MacOSXBundleInfo.plist.in
DESTINATION "${__GlobalConfig_install_dir}/macos"
if(APPLE)
if(MACOS)
set(platform_shortname "macos")
elseif(IOS)
set(platform_shortname "ios")
endif()
qt_copy_or_install(FILES "cmake/${platform_shortname}/Info.plist.app.in"
DESTINATION "${__GlobalConfig_install_dir}/${platform_shortname}"
)
elseif(IOS)
qt_copy_or_install(FILES
cmake/ios/Info.plist.app.in
cmake/ios/LaunchScreen.storyboard
DESTINATION "${__GlobalConfig_install_dir}/ios"
# For examples built as part of prefix build before install
file(COPY "cmake/${platform_shortname}/Info.plist.app.in"
DESTINATION "${__GlobalConfig_build_dir}/${platform_shortname}"
)
if(IOS)
qt_copy_or_install(FILES "cmake/ios/LaunchScreen.storyboard"
DESTINATION "${__GlobalConfig_install_dir}/ios"
)
# For examples built as part of prefix build before install
file(COPY "cmake/ios/LaunchScreen.storyboard"
DESTINATION "${__GlobalConfig_build_dir}/ios"
)
endif()
elseif(WASM)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/wasmtestrunner/qt-wasmtestrunner.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)

View File

@ -0,0 +1,85 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Depends on __qt6_qtbase_src_path being set in the top-level dir.
macro(qt_internal_top_level_setup_autodetect)
# Run platform auto-detection /before/ the first project() call and thus
# before the toolchain file is loaded.
# Don't run auto-detection when doing standalone tests. In that case, the detection
# results are taken from either QtBuildInternals or the qt.toolchain.cmake file.
if(NOT QT_BUILD_STANDALONE_TESTS)
set(__qt6_auto_detect_path "${__qt6_qtbase_src_path}/cmake/QtAutoDetect.cmake")
if(NOT EXISTS "${__qt6_auto_detect_path}")
message(FATAL_ERROR "Required file does not exist: '${__qt6_auto_detect_path}'")
endif()
include("${__qt6_auto_detect_path}")
endif()
endmacro()
macro(qt_internal_top_level_setup_after_project)
# TODO: Remove this variable once the top-level calls this function and
# qt_internal_qt_configure_end is not called in qt_print_build_instructions anymore.
set(__qt6_top_level_after_project_called TRUE)
qt_internal_top_level_setup_testing()
endmacro()
macro(qt_internal_top_level_setup_testing)
# Required so we can call ctest from the root build directory
enable_testing()
endmacro()
# Depends on __qt6_qtbase_src_path being set in the top-level dir.
macro(qt_internal_top_level_setup_cmake_module_path)
if (NOT QT_BUILD_STANDALONE_TESTS)
set(__qt6_cmake_module_path "${__qt6_qtbase_src_path}/cmake")
if(NOT EXISTS "${__qt6_cmake_module_path}")
message(FATAL_ERROR "Required directory does not exist: '${__qt6_cmake_module_path}'")
endif()
list(APPEND CMAKE_MODULE_PATH "${__qt6_cmake_module_path}")
list(APPEND CMAKE_MODULE_PATH
"${__qt6_cmake_module_path}/3rdparty/extra-cmake-modules/find-modules")
list(APPEND CMAKE_MODULE_PATH "${__qt6_cmake_module_path}/3rdparty/kwin")
endif()
endmacro()
macro(qt_internal_top_level_before_build_submodules)
qt_internal_top_level_setup_no_create_targets()
endmacro()
macro(qt_internal_top_level_setup_no_create_targets)
# Also make sure the CMake config files do not recreate the already-existing targets
if (NOT QT_BUILD_STANDALONE_TESTS)
set(QT_NO_CREATE_TARGETS TRUE)
endif()
endmacro()
macro(qt_internal_top_level_end)
qt_internal_print_top_level_info()
# Depends on QtBuildInternalsConfig being included, which is the case whenver any repo is
# configured.
qt_internal_qt_configure_end()
endmacro()
function(qt_internal_print_top_level_info)
if(NOT QT_BUILD_STANDALONE_TESTS)
# Display a summary of everything
include(QtBuildInformation)
include(QtPlatformSupport)
qt_print_feature_summary()
qt_print_build_instructions()
endif()
endfunction()
macro(qt_internal_top_level_after_add_subdirectory)
if(module STREQUAL "qtbase")
if (NOT QT_BUILD_STANDALONE_TESTS)
list(APPEND CMAKE_PREFIX_PATH "${QtBase_BINARY_DIR}/${INSTALL_LIBDIR}/cmake")
list(APPEND CMAKE_FIND_ROOT_PATH "${QtBase_BINARY_DIR}")
endif()
endif()
endmacro()

View File

@ -281,7 +281,7 @@ qt_setup_tool_path_command()
# Platform define path, etc.
if(WIN32)
set(QT_DEFAULT_PLATFORM_DEFINITIONS WIN32 _ENABLE_EXTENDED_ALIGNED_STORAGE)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
if(QT_64BIT)
list(APPEND QT_DEFAULT_PLATFORM_DEFINITIONS WIN64 _WIN64)
endif()
@ -434,7 +434,7 @@ set(QT_TOP_LEVEL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
# Prevent warnings about object files without any symbols. This is a common
# thing in Qt as we tend to build files unconditionally, and then use ifdefs
# to compile out parts that are not relevant.
if(CMAKE_HOST_APPLE AND APPLE)
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
foreach(lang ASM C CXX)
# We have to tell 'ar' to not run ranlib by itself, by passing the 'S' option
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qcS <TARGET> <LINK_FLAGS> <OBJECTS>")
@ -577,11 +577,6 @@ endif()
_qt_internal_determine_if_host_info_package_needed(__qt_build_requires_host_info_package)
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}")
# Create tool script wrapper if necessary.
# TODO: Remove once all direct usages of QT_TOOL_COMMAND_WRAPPER_PATH are replaced with function
# calls.
_qt_internal_generate_tool_command_wrapper()
# This sets up the poor man's scope finalizer mechanism.
# For newer CMake versions, we use cmake_language(DEFER CALL) instead.
if(CMAKE_VERSION VERSION_LESS "3.19.0")

View File

@ -111,6 +111,13 @@ from the build directory")
if(QT_SUPERBUILD)
qt_internal_save_previously_visited_packages()
endif()
# TODO: Abuse qt_print_build_instructions being called as the last command in a top-level build.
# Instead we should call this explicitly at the end of the top-level project.
# TODO: Remove this once the top-level calls qt_internal_top_level_setup_after_project
if(QT_SUPERBUILD AND NOT __qt6_top_level_after_project_called)
qt_internal_qt_configure_end()
endif()
endfunction()
function(qt_configure_print_summary_helper summary_reports force_show)

View File

@ -105,6 +105,30 @@ endif()
# build.
include(QtPlatformSupport)
# Set FEATURE_${feature} if INPUT_${feature} is set in certain circumstances.
#
# Needs to be in QtBuildInternalsConfig.cmake instead of QtFeature.cmake because it's used in
# qt_build_internals_disable_pkg_config_if_needed.
function(qt_internal_compute_feature_value_from_possible_input feature)
# If FEATURE_ is not defined try to use the INPUT_ variable to enable/disable feature.
# If FEATURE_ is defined and the configure script is being used (so
# QT_INTERNAL_CALLED_FROM_CONFIGURE is TRUE), ignore the FEATURE_ variable, and take into
# account the INPUT_ variable instead, because a command line argument takes priority over
# a pre-cached FEATURE_ variable.
if((NOT DEFINED FEATURE_${feature} OR QT_INTERNAL_CALLED_FROM_CONFIGURE)
AND DEFINED INPUT_${feature}
AND NOT "${INPUT_${feature}}" STREQUAL "undefined"
AND NOT "${INPUT_${feature}}" STREQUAL "")
if(INPUT_${feature})
set(FEATURE_${feature} ON)
else()
set(FEATURE_${feature} OFF)
endif()
set(FEATURE_${feature} "${FEATURE_${feature}}" PARENT_SCOPE)
endif()
endfunction()
function(qt_build_internals_disable_pkg_config_if_needed)
# pkg-config should not be used by default on Darwin and Windows platforms (and QNX), as defined
# in the qtbase/configure.json. Unfortunately by the time the feature is evaluated there are
@ -131,15 +155,7 @@ function(qt_build_internals_disable_pkg_config_if_needed)
endif()
# Features won't have been evaluated yet if this is the first run, have to evaluate this here
if ((NOT DEFINED "FEATURE_pkg_config") AND (DEFINED "INPUT_pkg_config")
AND (NOT "${INPUT_pkg_config}" STREQUAL "undefined")
AND (NOT "${INPUT_pkg_config}" STREQUAL ""))
if(INPUT_pkg_config)
set(FEATURE_pkg_config ON)
else()
set(FEATURE_pkg_config OFF)
endif()
endif()
qt_internal_compute_feature_value_from_possible_input(pkg_config)
# If user explicitly specified a value for the feature, honor it, even if it might break
# the build.
@ -296,7 +312,27 @@ function(qt_build_internals_add_toplevel_targets)
COMMENT "Building everything in ${qt_repo_targets_name}/${qt_repo_target_basename}")
add_dependencies("${qt_repo_target_name}" ${qt_repo_targets})
list(APPEND qt_repo_target_all "${qt_repo_target_name}")
# Create special dependency target for External Project examples excluding targets
# marked as skipped.
set(qt_repo_target_name
"${qt_repo_targets_name}_${qt_repo_target_basename}_for_examples")
add_custom_target("${qt_repo_target_name}")
set(unskipped_targets "")
foreach(target IN LISTS qt_repo_targets)
if(TARGET "${target}")
qt_internal_is_target_skipped_for_examples("${target}" is_skipped)
if(NOT is_skipped)
list(APPEND unskipped_targets "${target}")
endif()
endif()
endforeach()
if(unskipped_targets)
add_dependencies("${qt_repo_target_name}" ${unskipped_targets})
endif()
endif()
endforeach()
if (qt_repo_target_all)
# Note qt_repo_targets_name is different from qt_repo_target_name that is used above.
@ -570,9 +606,27 @@ macro(qt_build_repo_end)
set(QT_INTERNAL_FRESH_REQUESTED "FALSE" CACHE INTERNAL "")
endif()
if(NOT QT_SUPERBUILD)
qt_internal_qt_configure_end()
endif()
list(POP_BACK CMAKE_MESSAGE_CONTEXT)
endmacro()
# Function called either at the end of per-repo configuration, or at the end of configuration of
# a super build.
# At the moment it is called before examples are configured in a per-repo build. We might want
# to change that at some point if needed.
function(qt_internal_qt_configure_end)
# If Qt is configued via the configure script, remove the marker variable, so that any future
# reconfigurations that are done by calling cmake directly don't trigger configure specific
# logic.
unset(QT_INTERNAL_CALLED_FROM_CONFIGURE CACHE)
# Clean up stale feature input values.
qt_internal_clean_feature_inputs()
endfunction()
macro(qt_build_repo)
qt_build_repo_begin(${ARGN})
@ -856,7 +910,7 @@ macro(qt_examples_build_begin)
set(QT_EXAMPLE_DEPENDENCIES ${qt_repo_plugins_recursive} ${arg_DEPENDS})
if(TARGET ${qt_repo_targets_name}_src)
list(APPEND QT_EXAMPLE_DEPENDENCIES ${qt_repo_targets_name}_src)
list(APPEND QT_EXAMPLE_DEPENDENCIES ${qt_repo_targets_name}_src_for_examples)
endif()
if(TARGET ${qt_repo_targets_name}_tools)
@ -980,19 +1034,118 @@ set(CMAKE_INSTALL_PREFIX \"\${_qt_internal_examples_cmake_install_prefix_backup}
set(CMAKE_UNITY_BUILD ${QT_UNITY_BUILD})
endmacro()
# Allows building an example either as an ExternalProject or in-tree with the Qt build.
# Also allows installing the example sources.
function(qt_internal_add_example subdir)
if(NOT QT_IS_EXTERNAL_EXAMPLES_BUILD)
qt_internal_add_example_in_tree(${ARGV})
else()
qt_internal_add_example_external_project(${ARGV})
# Pre-compute unique example name based on the subdir, in case of target name clashes.
qt_internal_get_example_unique_name(unique_example_name "${subdir}")
# QT_INTERNAL_NO_CONFIGURE_EXAMPLES is not meant to be used by Qt builders, it's here for faster
# testing of the source installation code path for build system engineers.
if(NOT QT_INTERNAL_NO_CONFIGURE_EXAMPLES)
if(NOT QT_IS_EXTERNAL_EXAMPLES_BUILD)
qt_internal_add_example_in_tree("${subdir}")
else()
qt_internal_add_example_external_project("${subdir}"
NAME "${unique_example_name}")
endif()
endif()
if(QT_INSTALL_EXAMPLES_SOURCES)
string(TOLOWER ${PROJECT_NAME} project_name_lower)
qt_internal_install_example_sources("${subdir}"
NAME "${unique_example_name}"
REPO_NAME "${project_name_lower}")
endif()
endfunction()
# Gets the install prefix where an example should be installed.
# Used for computing the final installation path.
function(qt_internal_get_example_install_prefix out_var)
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(${out_var} "${qt_example_install_prefix}" PARENT_SCOPE)
endfunction()
# Gets the install prefix where an example's sources should be installed.
# Used for computing the final installation path.
function(qt_internal_get_examples_sources_install_prefix out_var)
# Allow customizing the installation path of the examples source specifically.
if(QT_INTERNAL_EXAMPLES_SOURCES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_SOURCES_INSTALL_PREFIX}")
else()
qt_internal_get_example_install_prefix(qt_example_install_prefix)
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(${out_var} "${qt_example_install_prefix}" PARENT_SCOPE)
endfunction()
# Gets the relative path of an example, relative to the current repo's examples source dir.
# QT_EXAMPLE_BASE_DIR is meant to be already set in a parent scope.
function(qt_internal_get_example_rel_path out_var subdir)
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
set(${out_var} "${example_rel_path}" PARENT_SCOPE)
endfunction()
# Gets the install path where an example should be installed.
function(qt_internal_get_example_install_path out_var subdir)
qt_internal_get_example_install_prefix(qt_example_install_prefix)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(example_install_path "${qt_example_install_prefix}/${example_rel_path}")
set(${out_var} "${example_install_path}" PARENT_SCOPE)
endfunction()
# Gets the install path where an example's sources should be installed.
function(qt_internal_get_examples_sources_install_path out_var subdir)
qt_internal_get_examples_sources_install_prefix(qt_example_install_prefix)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(example_install_path "${qt_example_install_prefix}/${example_rel_path}")
set(${out_var} "${example_install_path}" PARENT_SCOPE)
endfunction()
# Get the unique name of an example project based on its subdir or explicitly given name.
# Makes the name unique by appending a short sha1 hash of the relative path of the example
# if a target of the same name already exist.
function(qt_internal_get_example_unique_name out_var subdir)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(name "${subdir}")
# qtdeclarative has calls like qt_internal_add_example(imagine/automotive)
# so passing a nested subdirectory. Custom targets (and thus ExternalProjects) can't contain
# slashes, so extract the last part of the path to be used as a name.
if(name MATCHES "/")
string(REPLACE "/" ";" exploded_path "${name}")
list(POP_BACK exploded_path last_dir)
if(NOT last_dir)
message(FATAL_ERROR "Example subdirectory must have a name.")
else()
set(name "${last_dir}")
endif()
endif()
# Likely a clash with an example subdir ExternalProject custom target of the same name in a
# top-level build.
if(TARGET "${name}")
string(SHA1 rel_path_hash "${example_rel_path}")
string(SUBSTRING "${rel_path_hash}" 0 4 short_hash)
set(name "${name}-${short_hash}")
endif()
set(${out_var} "${name}" PARENT_SCOPE)
endfunction()
# Use old non-ExternalProject approach, aka build in-tree with the Qt build.
function(qt_internal_add_example_in_tree subdir)
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
# Unset the default CMAKE_INSTALL_PREFIX that's generated in
# ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
# so we can override it with a different value in
@ -1006,15 +1159,8 @@ unset(CMAKE_INSTALL_PREFIX)
# Override the install prefix in the subdir cmake_install.cmake, so that
# relative install(TARGETS DESTINATION) calls in example projects install where we tell them to.
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(CMAKE_INSTALL_PREFIX "${qt_example_install_prefix}/${example_rel_path}")
qt_internal_get_example_install_path(example_install_path "${subdir}")
set(CMAKE_INSTALL_PREFIX "${example_install_path}")
# Make sure unclean example projects have their INSTALL_EXAMPLEDIR set to "."
# Won't have any effect on example projects that don't use INSTALL_EXAMPLEDIR.
@ -1024,7 +1170,7 @@ unset(CMAKE_INSTALL_PREFIX)
# TODO: Remove once all repositories use qt_internal_add_example instead of add_subdirectory.
set(QT_INTERNAL_SET_EXAMPLE_INSTALL_DIR_TO_DOT ON)
add_subdirectory(${subdir} ${ARGN})
add_subdirectory(${subdir})
endfunction()
function(qt_internal_add_example_external_project subdir)
@ -1034,33 +1180,6 @@ function(qt_internal_add_example_external_project subdir)
cmake_parse_arguments(PARSE_ARGV 1 arg "${options}" "${singleOpts}" "${multiOpts}")
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
if(NOT arg_NAME)
set(arg_NAME "${subdir}")
# qtdeclarative has calls like qt_internal_add_example(imagine/automotive)
# so passing a nested subdirectory. Custom targets (and thus ExternalProjects) can't contain
# slashes, so extract the last part of the path to be used as a name.
if(arg_NAME MATCHES "/")
string(REPLACE "/" ";" exploded_path "${arg_NAME}")
list(POP_BACK exploded_path last_dir)
if(NOT last_dir)
message(FATAL_ERROR "Example subdirectory must have a name.")
else()
set(arg_NAME "${last_dir}")
endif()
endif()
endif()
# Likely a clash with an example subdir ExternalProject custom target of the same name.
if(TARGET "${arg_NAME}")
string(SHA1 rel_path_hash "${example_rel_path}")
string(SUBSTRING "${rel_path_hash}" 0 4 short_hash)
set(arg_NAME "${arg_NAME}-${short_hash}")
endif()
# TODO: Fix example builds when using Conan / install prefixes are different for each repo.
if(QT_SUPERBUILD OR QtBase_BINARY_DIR)
# When doing a top-level build or when building qtbase,
@ -1281,15 +1400,7 @@ function(qt_internal_add_example_external_project subdir)
# example_source_dir, use _qt_internal_override_example_install_dir_to_dot to ensure
# INSTALL_EXAMPLEDIR does not interfere.
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(example_install_prefix "${qt_example_install_prefix}/${example_rel_path}")
qt_internal_get_example_install_path(example_install_path "${subdir}")
set(ep_binary_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}")
@ -1304,7 +1415,7 @@ function(qt_internal_add_example_external_project subdir)
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/${subdir}-ep"
STAMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/${subdir}-ep/stamp"
BINARY_DIR "${ep_binary_dir}"
INSTALL_DIR "${example_install_prefix}"
INSTALL_DIR "${example_install_path}"
INSTALL_COMMAND ""
${build_command}
TEST_COMMAND ""
@ -1358,6 +1469,54 @@ execute_process(
endfunction()
function(qt_internal_install_example_sources subdir)
set(options "")
set(single_args NAME REPO_NAME)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${options}" "${single_args}" "${multi_args}")
qt_internal_get_examples_sources_install_path(example_install_path "${subdir}")
# The trailing slash is important to avoid duplicate nested directory names.
set(example_source_dir "${subdir}/")
# Allow controlling whether sources should be part of the default install target.
if(QT_INSTALL_EXAMPLES_SOURCES_BY_DEFAULT)
set(exclude_from_all "")
else()
set(exclude_from_all "EXCLUDE_FROM_ALL")
endif()
# Create an install component for all example sources. Can also be part of the default
# install target if EXCLUDE_FROM_ALL is not passed.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources"
USE_SOURCE_PERMISSIONS
${exclude_from_all}
)
# Also create a specific install component just for this repo's examples.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources_${arg_REPO_NAME}"
USE_SOURCE_PERMISSIONS
EXCLUDE_FROM_ALL
)
# Also create a specific install component just for the current example's sources.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources_${arg_NAME}"
USE_SOURCE_PERMISSIONS
EXCLUDE_FROM_ALL
)
endfunction()
if ("STANDALONE_TEST" IN_LIST Qt6BuildInternals_FIND_COMPONENTS)
include(${CMAKE_CURRENT_LIST_DIR}/QtStandaloneTestTemplateProject/Main.cmake)
if (NOT PROJECT_VERSION_MAJOR)

View File

@ -103,6 +103,9 @@ set(QT_BUILD_EXAMPLES_AS_EXTERNAL "@QT_BUILD_EXAMPLES_AS_EXTERNAL@" CACHE BOOL
# Propagate usage of ccache.
set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache")
# Propagate usage of vcpkg, ON by default.
set(QT_USE_VCPKG @QT_USE_VCPKG@ CACHE BOOL "Enable the use of vcpkg")
# Propagate usage of unity build.
set(QT_UNITY_BUILD @QT_UNITY_BUILD@ CACHE BOOL "Enable unity (jumbo) build")
set(QT_UNITY_BUILD_BATCH_SIZE "@QT_UNITY_BUILD_BATCH_SIZE@" CACHE STRING "Unity build batch size")
@ -163,6 +166,7 @@ function(qt_internal_force_set_cmake_build_type_conditionally value)
AND NOT QT_NO_FORCE_SET_CMAKE_BUILD_TYPE
AND NOT __qt_internal_extras_is_multi_config)
set(CMAKE_BUILD_TYPE "${value}" CACHE STRING "Choose the type of build." FORCE)
set(__qt_build_internals_cmake_build_type "${value}" PARENT_SCOPE)
endif()
endfunction()

View File

@ -14,6 +14,8 @@ function(qt_internal_get_supported_min_cmake_version_for_building_qt out_var)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT}")
# We're building qtbase so the values come from .cmake.conf.
elseif(APPLE)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_APPLE}")
elseif(BUILD_SHARED_LIBS)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED}")
else()
@ -30,7 +32,9 @@ function(qt_internal_get_supported_min_cmake_version_for_using_qt out_var)
"It should have been set by this point.")
endif()
if(BUILD_SHARED_LIBS)
if(APPLE)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_APPLE}")
elseif(BUILD_SHARED_LIBS)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED}")
else()
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC}")

View File

@ -92,10 +92,10 @@ endif()
# Windows MSVC
if(MSVC)
set(QT_CFLAGS_OPTIMIZE "-O2")
set(QT_CFLAGS_OPTIMIZE "-O2 -Ob3") # -Ob3 was introduced in Visual Studio 2019 version 16.0
set(QT_CFLAGS_OPTIMIZE_DEBUG "-Od")
set(QT_CFLAGS_OPTIMIZE_SIZE "-O1")
set(QT_CFLAGS_OPTIMIZE_VALID_VALUES "/O2" "/O1" "/Od" "/Ob0" "/Ob1" "/Ob2" "/O0" "-O0")
set(QT_CFLAGS_OPTIMIZE_VALID_VALUES "/O2" "/O1" "/Od" "/Ob0" "/Ob1" "/Ob2" "/Ob3" "/O0" "-O0")
if(CLANG)
set(QT_CFLAGS_OPTIMIZE_FULL "/clang:-O3")

View File

@ -29,13 +29,12 @@ list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}")
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/extra-cmake-modules/find-modules")
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/kwin")
if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
# Add module directory to pick up custom Info.plist template for macOS
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
elseif(APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
# Add module directory to pick up custom Info.plist template for iOS
set(__qt_internal_cmake_ios_support_files_path "${_qt_import_prefix}/ios")
list(APPEND CMAKE_MODULE_PATH "${__qt_internal_cmake_ios_support_files_path}")
if(APPLE)
if(NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/macos")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/ios")
endif()
endif()
# Public helpers available to all Qt packages.

View File

@ -148,7 +148,7 @@ function(qt_internal_add_executable name)
if(WASM)
# WASM unconditionally sets DISABLE_EXCEPTION_CATCHING=1
qt_internal_set_exceptions_flags("${name}" NO_EXCEPTIONS)
qt_internal_set_exceptions_flags("${name}" FALSE)
else()
qt_internal_set_exceptions_flags("${name}" ${arg_EXCEPTIONS})
endif()
@ -422,7 +422,7 @@ function(qt_internal_add_configure_time_executable target)
)
set(should_build_at_configure_time TRUE)
if(EXISTS "${target_binary_path}")
if(EXISTS "${target_binary_path}" AND EXISTS "${timestamp_file}")
set(last_ts 0)
foreach(source IN LISTS sources)
file(TIMESTAMP "${source}" ts "%s")

View File

@ -177,15 +177,20 @@ function(qt_evaluate_config_expression resultVar)
set(${resultVar} ${result} PARENT_SCOPE)
endfunction()
function(_qt_internal_get_feature_condition_keywords out_var)
set(keywords "EQUAL" "LESS" "LESS_EQUAL" "GREATER" "GREATER_EQUAL" "STREQUAL" "STRLESS"
"STRLESS_EQUAL" "STRGREATER" "STRGREATER_EQUAL" "VERSION_EQUAL" "VERSION_LESS"
"VERSION_LESS_EQUAL" "VERSION_GREATER" "VERSION_GREATER_EQUAL" "MATCHES"
"EXISTS" "COMMAND" "DEFINED" "NOT" "AND" "OR" "TARGET" "EXISTS" "IN_LIST" "(" ")")
set(${out_var} "${keywords}" PARENT_SCOPE)
endfunction()
function(_qt_internal_dump_expression_values expression_dump expression)
set(dump "")
set(skipNext FALSE)
set(isTargetExpression FALSE)
set(keywords "EQUAL" "LESS" "LESS_EQUAL" "GREATER" "GREATER_EQUAL" "STREQUAL" "STRLESS"
"STRLESS_EQUAL" "STRGREATER" "STRGREATER_EQUAL" "VERSION_EQUAL" "VERSION_LESS"
"VERSION_LESS_EQUAL" "VERSION_GREATER" "VERSION_GREATER_EQUAL" "MATCHES"
"EXISTS" "COMMAND" "DEFINED" "NOT" "AND" "OR" "TARGET" "EXISTS" "IN_LIST" "(" ")")
_qt_internal_get_feature_condition_keywords(keywords)
list(LENGTH expression length)
math(EXPR length "${length}-1")
@ -239,19 +244,44 @@ endfunction()
# ${computed} is also stored when reconfiguring and the condition does not align with the user
# provided value.
#
function(qt_feature_check_and_save_user_provided_value resultVar feature condition computed label)
function(qt_feature_check_and_save_user_provided_value
resultVar feature condition condition_expression computed label)
if (DEFINED "FEATURE_${feature}")
# Revisit new user provided value
set(user_value "${FEATURE_${feature}}")
string(TOUPPER "${user_value}" result)
string(TOUPPER "${user_value}" user_value_upper)
set(result "${user_value_upper}")
# If the build is marked as dirty and the user_value doesn't meet the new condition,
# reset it to the computed one.
# If ${feature} depends on another dirty feature, reset the ${feature} value to
# ${computed}.
get_property(dirty_build GLOBAL PROPERTY _qt_dirty_build)
if(NOT condition AND result AND dirty_build)
set(result "${computed}")
message(WARNING "Reset FEATURE_${feature} value to ${result}, because it doesn't \
meet its condition after reconfiguration.")
if(dirty_build)
_qt_internal_feature_compute_feature_dependencies(deps "${feature}")
if(deps)
get_property(dirty_features GLOBAL PROPERTY _qt_dirty_features)
foreach(dirty_feature ${dirty_features})
if(dirty_feature IN_LIST deps AND NOT "${result}" STREQUAL "${computed}")
set(result "${computed}")
message(WARNING
"Auto-resetting 'FEATURE_${feature}' from '${user_value_upper}' to "
"'${computed}', "
"because the dependent feature '${dirty_feature}' was marked dirty.")
# Append ${feature} as a new dirty feature.
set_property(GLOBAL APPEND PROPERTY _qt_dirty_features "${feature}")
break()
endif()
endforeach()
endif()
# If the build is marked as dirty and the feature doesn't meet its condition,
# reset its value to the computed one, which is likely OFF.
if(NOT condition AND result)
set(result "${computed}")
message(WARNING "Resetting 'FEATURE_${feature}' from '${user_value_upper}' to "
"'${computed}' because it doesn't meet its condition after reconfiguration. "
"Condition expression is: '${condition_expression}'")
endif()
endif()
set(bool_values OFF NO FALSE N ON YES TRUE Y)
@ -299,6 +329,14 @@ condition:\n ${conditionString}\nCondition values dump:\n ${conditionDump}
set(QT_KNOWN_FEATURES "${QT_KNOWN_FEATURES}" CACHE INTERNAL "" FORCE)
endmacro()
macro(_qt_internal_parse_feature_definition feature)
cmake_parse_arguments(arg
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;"
"AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF"
${_QT_FEATURE_DEFINITION_${feature}})
endmacro()
# The build system stores 2 CMake cache variables for each feature, to allow detecting value changes
# during subsequent reconfigurations.
@ -334,9 +372,7 @@ function(qt_evaluate_feature feature)
message(FATAL_ERROR "Attempting to evaluate feature ${feature} but its definition is missing. Either the feature does not exist or a dependency to the module that defines it is missing")
endif()
cmake_parse_arguments(arg
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;" "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" ${_QT_FEATURE_DEFINITION_${feature}})
_qt_internal_parse_feature_definition("${feature}")
if("${arg_ENABLE}" STREQUAL "")
set(arg_ENABLE OFF)
@ -374,16 +410,7 @@ function(qt_evaluate_feature feature)
qt_evaluate_config_expression(emit_if ${arg_EMIT_IF})
endif()
# If FEATURE_ is not defined trying to use INPUT_ variable to enable/disable feature.
if ((NOT DEFINED "FEATURE_${feature}") AND (DEFINED "INPUT_${feature}")
AND (NOT "${INPUT_${feature}}" STREQUAL "undefined")
AND (NOT "${INPUT_${feature}}" STREQUAL ""))
if(INPUT_${feature})
set(FEATURE_${feature} ON)
else()
set(FEATURE_${feature} OFF)
endif()
endif()
qt_internal_compute_feature_value_from_possible_input("${feature}")
# Warn about a feature which is not emitted, but the user explicitly provided a value for it.
if(NOT emit_if AND DEFINED FEATURE_${feature})
@ -401,7 +428,8 @@ function(qt_evaluate_feature feature)
# Only save the user provided value if the feature was emitted.
if(emit_if)
qt_feature_check_and_save_user_provided_value(
saved_user_value "${feature}" "${condition}" "${computed}" "${arg_LABEL}")
saved_user_value
"${feature}" "${condition}" "${arg_CONDITION}" "${computed}" "${arg_LABEL}")
else()
# Make sure the feature internal value is OFF if not emitted.
set(saved_user_value OFF)
@ -414,6 +442,60 @@ function(qt_evaluate_feature feature)
set(QT_FEATURE_LABEL_${feature} "${arg_LABEL}" CACHE INTERNAL "")
endfunction()
# Collect feature names that ${feature} depends on, by inspecting the given expression.
function(_qt_internal_feature_extract_feature_dependencies_from_expression out_var expression)
list(LENGTH expression length)
math(EXPR length "${length}-1")
if(length LESS 0)
set(${out_var} "" PARENT_SCOPE)
return()
endif()
set(deps "")
foreach(memberIdx RANGE ${length})
list(GET expression ${memberIdx} member)
if(member MATCHES "^QT_FEATURE_(.+)")
list(APPEND deps "${CMAKE_MATCH_1}")
endif()
endforeach()
set(${out_var} "${deps}" PARENT_SCOPE)
endfunction()
# Collect feature names that ${feature} depends on, based on feature names that appear
# in the ${feature}'s condition expressions.
function(_qt_internal_feature_compute_feature_dependencies out_var feature)
# Only compute the deps once per feature.
get_property(deps_computed GLOBAL PROPERTY _qt_feature_deps_computed_${feature})
if(deps_computed)
get_property(deps GLOBAL PROPERTY _qt_feature_deps_${feature})
set(${out_var} "${deps}" PARENT_SCOPE)
return()
endif()
_qt_internal_parse_feature_definition("${feature}")
set(options_to_check AUTODETECT CONDITION ENABLE DISABLE EMIT_IF)
set(deps "")
# Go through each option that takes condition expressions and collect the feature names.
foreach(option ${options_to_check})
set(option_value "${arg_${option}}")
if(option_value)
_qt_internal_feature_extract_feature_dependencies_from_expression(
option_deps "${option_value}")
if(option_deps)
list(APPEND deps ${option_deps})
endif()
endif()
endforeach()
set_property(GLOBAL PROPERTY _qt_feature_deps_computed_${feature} TRUE)
set_property(GLOBAL PROPERTY _qt_feature_deps_${feature} "${deps}")
set(${out_var} "${deps}" PARENT_SCOPE)
endfunction()
function(qt_feature_config feature config_var_name)
qt_feature_normalize_name("${feature}" feature)
cmake_parse_arguments(PARSE_ARGV 2 arg
@ -786,6 +868,49 @@ function(qt_feature_copy_global_config_features_to_core target)
endif()
endfunction()
function(qt_internal_detect_dirty_features)
# We need to clean up QT_FEATURE_*, but only once per configuration cycle
get_property(qt_feature_clean GLOBAL PROPERTY _qt_feature_clean)
if(NOT qt_feature_clean AND NOT QT_NO_FEATURE_AUTO_RESET)
message(STATUS "Checking for feature set changes")
set_property(GLOBAL PROPERTY _qt_feature_clean TRUE)
foreach(feature ${QT_KNOWN_FEATURES})
qt_internal_compute_feature_value_from_possible_input("${feature}")
if(DEFINED "FEATURE_${feature}" AND
NOT "${QT_FEATURE_${feature}}" STREQUAL "${FEATURE_${feature}}")
message(" '${feature}' was changed from ${QT_FEATURE_${feature}} "
"to ${FEATURE_${feature}}")
set(dirty_build TRUE)
set_property(GLOBAL APPEND PROPERTY _qt_dirty_features "${feature}")
endif()
unset("QT_FEATURE_${feature}" CACHE)
endforeach()
set(QT_KNOWN_FEATURES "" CACHE INTERNAL "" FORCE)
if(dirty_build)
set_property(GLOBAL PROPERTY _qt_dirty_build TRUE)
message(WARNING
"Due to detected feature set changes, dependent features "
"will be re-computed automatically. This might cause a lot of files to be rebuilt. "
"To disable this behavior, configure with -DQT_NO_FEATURE_AUTO_RESET=ON")
endif()
endif()
endfunction()
function(qt_internal_clean_feature_inputs)
foreach(feature IN LISTS QT_KNOWN_FEATURES)
# Unset the INPUT_foo cache variables after they were used in feature evaluation, to
# ensure stale values don't influence features upon reconfiguration when
# QT_INTERNAL_CALLED_FROM_CONFIGURE is TRUE and the INPUT_foo variable is not passed.
# e.g. first configure -no-gui, then manually toggle FEATURE_gui to ON in
# CMakeCache.txt, then reconfigure (with the configure script) without -no-gui.
# Without this unset(), we'd have switched FEATURE_gui to OFF again.
unset(INPUT_${feature} CACHE)
endforeach()
endfunction()
function(qt_config_compile_test name)
if(DEFINED "TEST_${name}")
return()
@ -924,6 +1049,7 @@ function(qt_config_compile_test name)
# fail instead of cmake abort later via CMAKE_REQUIRED_LIBRARIES.
string(FIND "${library}" "::" cmake_target_namespace_separator)
if(NOT cmake_target_namespace_separator EQUAL -1)
message(STATUS "Performing Test ${arg_LABEL} - Failed because ${library} not found")
set(HAVE_${name} FALSE)
break()
endif()

View File

@ -16,6 +16,15 @@ function(qt_find_package_promote_targets_to_global_scope target)
"qt_find_package_targets_dict" "promote_global")
endfunction()
# As an optimization when using -developer-build, qt_find_package records which
# packages were found during the initial configuration. Then on subsequent
# reconfigurations it skips looking for packages that were not found on the
# initial run.
# For the build system to pick up a newly added qt_find_package call, you need to:
# - Start with a clean build dir
# - Or remove the <builddir>/CMakeCache.txt file and configure from scratch
# - Or remove the QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES cache variable (by
# editing CMakeCache.txt) and reconfigure.
macro(qt_find_package)
# Get the target names we expect to be provided by the package.
set(find_package_options CONFIG NO_MODULE MODULE REQUIRED)

View File

@ -4,6 +4,7 @@
macro(qt_find_apple_system_frameworks)
if(APPLE)
qt_internal_find_apple_system_framework(FWAppKit AppKit)
qt_internal_find_apple_system_framework(FWCFNetwork CFNetwork)
qt_internal_find_apple_system_framework(FWAssetsLibrary AssetsLibrary)
qt_internal_find_apple_system_framework(FWPhotos Photos)
qt_internal_find_apple_system_framework(FWAudioToolbox AudioToolbox)
@ -58,7 +59,7 @@ function(qt_internal_find_apple_system_framework out_var framework_name)
endif()
endfunction()
# Copy header files to QtXYZ.framework/Versions/A/Headers/
# Copy header files to the framework's Headers directory
# Use this function for header files that
# - are not added as source files to the target
# - are not marked as PUBLIC_HEADER
@ -71,7 +72,7 @@ function(qt_copy_framework_headers target)
set(options)
set(oneValueArgs)
set(multiValueArgs PUBLIC PRIVATE QPA)
set(multiValueArgs PUBLIC PRIVATE QPA RHI)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
qt_internal_get_framework_info(fw ${target})
@ -79,10 +80,11 @@ function(qt_copy_framework_headers target)
set(output_dir_PUBLIC "${output_dir}/${fw_versioned_header_dir}")
set(output_dir_PRIVATE "${output_dir}/${fw_private_module_header_dir}/private")
set(output_dir_QPA "${output_dir}/${fw_private_module_header_dir}/qpa")
set(output_dir_RHI "${output_dir}/${fw_private_module_header_dir}/rhi")
set(out_files)
foreach(type IN ITEMS PUBLIC PRIVATE QPA)
foreach(type IN ITEMS PUBLIC PRIVATE QPA RHI)
set(fw_output_header_dir "${output_dir_${type}}")
foreach(hdr IN LISTS arg_${type})
get_filename_component(in_file_path ${hdr} ABSOLUTE)
@ -164,8 +166,13 @@ function(qt_internal_get_framework_info out_var target)
set(${out_var}_name "${module}")
set(${out_var}_dir "${${out_var}_name}.framework")
set(${out_var}_header_dir "${${out_var}_dir}/Headers")
set(${out_var}_versioned_header_dir "${${out_var}_dir}/Versions/${${out_var}_version}/Headers")
set(${out_var}_private_header_dir "${${out_var}_header_dir}/${${out_var}_bundle_version}")
if(UIKIT)
# iOS frameworks do not version their headers
set(${out_var}_versioned_header_dir "${${out_var}_header_dir}")
else()
set(${out_var}_versioned_header_dir "${${out_var}_dir}/Versions/${${out_var}_version}/Headers")
endif()
set(${out_var}_private_header_dir "${${out_var}_versioned_header_dir}/${${out_var}_bundle_version}")
set(${out_var}_private_module_header_dir "${${out_var}_private_header_dir}/${module}")
set(${out_var}_name "${${out_var}_name}" PARENT_SCOPE)

View File

@ -104,6 +104,7 @@ function(qt_internal_add_headersclean_target module_target module_headers)
set(hcleanFLAGS -Wall -Wextra -Werror -Woverloaded-virtual -Wshadow -Wundef -Wfloat-equal
-Wnon-virtual-dtor -Wpointer-arith -Wformat-security -Wno-long-long -Wno-variadic-macros
-fno-operator-names
-pedantic-errors)
if(QT_FEATURE_reduce_relocations AND UNIX)
@ -181,9 +182,7 @@ function(qt_internal_add_headersclean_target module_target module_headers)
)
set(input_header_path_type ABSOLUTE)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# -Za would enable strict standards behavior, but we can't add it because
# <windows.h> and <GL.h> violate the standards.
set(hcleanFLAGS -std:c++latest -Zc:__cplusplus -WX -W3)
set(hcleanFLAGS -std:c++latest -Zc:__cplusplus -WX -W3 -EHsc)
# Because we now add `-DNOMINMAX` to `PlatformCommonInternal`.
set(hcleanUDEFS -UNOMINMAX)

214
cmake/QtInitProject.cmake Normal file
View File

@ -0,0 +1,214 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
if(NOT PROJECT_DIR)
set(PROJECT_DIR "${CMAKE_SOURCE_DIR}")
endif()
get_filename_component(project_name "${PROJECT_DIR}" NAME)
get_filename_component(project_abs_dir "${PROJECT_DIR}" ABSOLUTE)
if(NOT IS_DIRECTORY "${project_abs_dir}")
message(FATAL_ERROR "Unable to scan ${project_abs_dir}. The directory doesn't exist.")
endif()
set(known_extensions "")
set(types "")
# The function allows extending the capabilities of this script and establishes simple relation
# chains between the file types.
# Option Arguments:
# EXPERIMENTAL
# Marks that the support of the following files is experimental and the required Qt modules
# are in Technical preview state.
# DEPRECATED
# Marks that the support of the following files will be discontinued soon and the required
# Qt modules are deprecated.
# One-value Arguments:
# TEMPLATE
# The CMake code template. Use the '@files@' string for the files substitution.
# Multi-value Arguments:
# EXTENSIONS
# List of the file extensions treated as this source 'type'.
# MODULES
# List of Qt modules required for these file types.
# DEPENDS
# The prerequisite source 'type' needed by this source 'type'
macro(handle_type type)
cmake_parse_arguments(arg
"EXPERIMENTAL;DEPRECATED"
"TEMPLATE"
"EXTENSIONS;MODULES;DEPENDS"
${ARGN}
)
if(NOT arg_EXTENSIONS)
message(FATAL_ERROR "Unexpected call handle_type of with no EXTENSIONS specified."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(unique_extensions_subset "${known_extensions}")
list(REMOVE_ITEM unique_extensions_subset ${arg_EXTENSIONS})
if(NOT "${known_extensions}" STREQUAL "${unique_extensions_subset}")
message(FATAL_ERROR "${type} contains duplicated extensions, this is not supported."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(${type}_file_extensions "${arg_EXTENSIONS}")
if(NOT arg_TEMPLATE)
message(FATAL_ERROR "Unexpected call handle_type of with no TEMPLATE specified."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(${type}_template "${arg_TEMPLATE}")
if(arg_MODULES)
set(${type}_required_modules "${arg_MODULES}")
endif()
list(APPEND types ${type})
if(arg_EXPERIMENTAL)
set(${type}_is_experimental TRUE)
else()
set(${type}_is_experimental FALSE)
endif()
if(arg_DEPRECATED)
set(${type}_is_deprecated TRUE)
else()
set(${type}_is_deprecated FALSE)
endif()
if(arg_DEPENDS)
set(${type}_dependencies ${arg_DEPENDS})
endif()
endmacro()
handle_type(cpp EXTENSIONS .c .cc .cpp .cxx .h .hh .hxx .hpp MODULES Core TEMPLATE
"\n\nqt_add_executable(${project_name}
@files@
)"
)
handle_type(qml EXTENSIONS .qml .js .mjs MODULES Gui Qml Quick TEMPLATE
"\n\nqt_add_qml_module(${project_name}
URI ${project_name}
OUTPUT_DIRECTORY qml
VERSION 1.0
RESOURCE_PREFIX /qt/qml
QML_FILES
@files@
)"
)
handle_type(ui EXTENSIONS .ui MODULES Gui Widgets DEPENDS cpp TEMPLATE
"\n\ntarget_sources(${project_name}
PRIVATE
@files@
)"
)
handle_type(qrc EXTENSIONS .qrc DEPENDS cpp TEMPLATE
"\n\nqt_add_resources(${project_name}_resources @files@)
target_sources(${project_name}
PRIVATE
\\\${${project_name}_resources}
)"
)
handle_type(protobuf EXPERIMENTAL EXTENSIONS .proto MODULES Protobuf Grpc TEMPLATE
"\n\nqt_add_protobuf(${project_name}
GENERATE_PACKAGE_SUBFOLDERS
PROTO_FILES
@files@
)"
)
set(extra_packages "")
file(GLOB_RECURSE files RELATIVE "${project_abs_dir}" "${project_abs_dir}/*")
foreach(f IN LISTS files)
get_filename_component(file_extension "${f}" LAST_EXT)
string(TOLOWER "${file_extension}" file_extension)
foreach(type IN LISTS types)
if(file_extension IN_LIST ${type}_file_extensions)
list(APPEND ${type}_sources "${f}")
list(APPEND packages ${${type}_required_modules})
if(${type}_is_experimental)
message("We found files with the following extensions in your directory:"
" ${${type}_file_extensions}\n"
"Note that the modules ${${type}_required_modules} are"
" in the technical preview state.")
endif()
if(${type}_is_deprecated)
message("We found files with the following extensions in your directory:"
" ${${type}_file_extensions}\n"
"Note that the modules ${${type}_required_modules} are deprecated.")
endif()
break()
endif()
endforeach()
endforeach()
if(packages)
list(REMOVE_DUPLICATES packages)
list(JOIN packages " " packages_string)
list(JOIN packages "\n Qt::" deps_string)
set(deps_string "Qt::${deps_string}")
endif()
set(content
"cmake_minimum_required(VERSION 3.16)
project(${project_name} LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS ${packages_string})
qt_standard_project_setup()"
)
set(has_useful_sources FALSE)
foreach(type IN LISTS types)
if(${type}_sources)
set(skip FALSE)
foreach(dep IN LISTS ${type}_dependencies)
if(NOT ${dep}_sources)
set(skip TRUE)
message("Sources of type ${${type}_file_extensions} cannot live in the project"
" without ${${dep}_file_extensions} files. Skipping.")
break()
endif()
endforeach()
if(skip)
continue()
endif()
set(has_useful_sources TRUE)
string(REGEX MATCH "( +)@files@" unused "${${type}_template}")
list(JOIN ${type}_sources "\n${CMAKE_MATCH_1}" ${type}_sources)
string(REPLACE "@files@" "${${type}_sources}" ${type}_content
"${${type}_template}")
string(APPEND content "${${type}_content}")
endif()
endforeach()
string(APPEND content "\n\ntarget_link_libraries(${project_name}
PRIVATE
${deps_string}
)\n"
)
if(EXISTS "${project_abs_dir}/CMakeLists.txt")
message(FATAL_ERROR "Project is already initialized in current directory."
" Please remove CMakeLists.txt if you want to regenerate the project.")
endif()
if(NOT has_useful_sources)
message(FATAL_ERROR "Could not find any files to generate the project.")
endif()
file(WRITE "${project_abs_dir}/CMakeLists.txt" "${content}")
message("The project file is successfully generated. To build the project run:"
"\nmkdir build"
"\ncd build"
"\nqt-cmake ${project_abs_dir}"
"\ncmake --build ${project_abs_dir}"
)

View File

@ -156,6 +156,8 @@ qt_internal_add_target_aliases(PlatformToolInternal)
target_link_libraries(PlatformToolInternal INTERFACE PlatformAppInternal)
qt_internal_add_global_definition(QT_NO_JAVA_STYLE_ITERATORS)
qt_internal_add_global_definition(QT_NO_AS_CONST)
qt_internal_add_global_definition(QT_NO_QEXCHANGE)
qt_internal_add_global_definition(QT_NO_NARROWING_CONVERSIONS_IN_CONNECT)
qt_internal_add_global_definition(QT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH)

View File

@ -35,6 +35,15 @@ function(qt_process_qlalr consuming_target input_file_list flags)
return()
endif()
qt_internal_is_skipped_test(skipped ${consuming_target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${consuming_target})
if(in_batch)
_qt_internal_test_batch_target_name(consuming_target)
endif()
foreach(input_file ${input_file_list})
file(STRINGS ${input_file} input_file_lines)
qt_qlalr_find_option_in_list("${input_file_lines}" "^%parser(.+)" "parser")

View File

@ -27,6 +27,8 @@ endif()
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake"
OPTIONAL)
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
endif()

View File

@ -30,6 +30,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
EXTERNAL_HEADERS_DIR
PRIVATE_HEADER_FILTERS
QPA_HEADER_FILTERS
RHI_HEADER_FILTERS
HEADER_SYNC_SOURCE_DIRECTORY
${__default_target_info_args}
)
@ -114,6 +115,10 @@ endfunction()
# The regular expressions that filter QPA header files out of target sources.
# The value must use the following format 'regex1|regex2|regex3'.
#
# RHI_HEADER_FILTERS
# The regular expressions that filter RHI header files out of target sources.
# The value must use the following format 'regex1|regex2|regex3'.
#
# HEADER_SYNC_SOURCE_DIRECTORY
# The source directory for header sync procedure. Header files outside this directory will be
# ignored by syncqt. The specifying this directory allows to skip the parsing of the whole
@ -326,14 +331,24 @@ function(qt_internal_add_module target)
EXPORT_PROPERTIES "${export_properties}")
endif()
# FIXME: This workaround is needed because the deployment logic
# for iOS and WASM just copies/embeds the directly linked library,
# which will just be a versioned symlink to the actual library.
if((UIKIT OR WASM) AND BUILD_SHARED_LIBS)
set(version_args "")
else()
set(version_args
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
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}
)
${version_args}
)
qt_set_target_info_properties(${target} ${ARGN})
qt_handle_multi_config_output_dirs("${target}")
@ -436,6 +451,13 @@ function(qt_internal_add_module target)
set_target_properties(${target}
PROPERTIES _qt_module_qpa_headers_filter_regex "${qpa_filter_regex}")
set(rhi_filter_regex "")
if(arg_RHI_HEADER_FILTERS)
set(rhi_filter_regex "${arg_RHI_HEADER_FILTERS}")
endif()
set_target_properties(${target}
PROPERTIES _qt_module_rhi_headers_filter_regex "${rhi_filter_regex}")
set(private_filter_regex ".+_p(ch)?\\.h")
if(arg_PRIVATE_HEADER_FILTERS)
set(private_filter_regex "${private_filter_regex}|${arg_PRIVATE_HEADER_FILTERS}")
@ -793,6 +815,11 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}")
qt_internal_export_genex_properties(TARGETS ${target}
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}"
)
### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
# that belong to Qt.
if(NOT arg_HEADER_MODULE)
@ -878,6 +905,7 @@ function(qt_finalize_module target)
PUBLIC ${module_headers_public} "${module_depends_header}"
PRIVATE ${module_headers_private}
QPA ${module_headers_qpa}
RHI ${module_headers_rhi}
)
qt_finalize_framework_headers_copy(${target})
@ -910,6 +938,7 @@ endfunction()
# * foo_versioned_inner_include_dir with the value "QtCore/6.2.0/QtCore"
# * foo_private_include_dir with the value "QtCore/6.2.0/QtCore/private"
# * foo_qpa_include_dir with the value "QtCore/6.2.0/QtCore/qpa"
# * foo_rhi_include_dir with the value "QtCore/6.2.0/QtCore/rhi"
# * foo_interface_name the interface name of the module stored in _qt_module_interface_name
# property, e.g. Core.
#
@ -932,6 +961,9 @@ endfunction()
# * foo_<build|install>_qpa_include_dir with
# qtbase_build_dir/include/QtCore/6.2.0/QtCore/qpa for build interface and
# include/QtCore/6.2.0/QtCore/qpa for install interface.
# * foo_<build|install>_rhi_include_dir with
# qtbase_build_dir/include/QtCore/6.2.0/QtCore/rhi for build interface and
# include/QtCore/6.2.0/QtCore/rhi for install interface.
# The following values are set by the function and might be useful in caller's scope:
# * repo_install_interface_include_dir contains path to the top-level repository include directory,
# e.g. qtbase_build_dir/include
@ -966,6 +998,8 @@ the different base name for the module info variables.")
"${${result}_versioned_inner_include_dir}/private")
set("${result}_qpa_include_dir"
"${${result}_versioned_inner_include_dir}/qpa")
set("${result}_rhi_include_dir"
"${${result}_versioned_inner_include_dir}/rhi")
# Module build interface directories
set(repo_build_interface_include_dir "${QT_BUILD_DIR}/include")
@ -979,6 +1013,8 @@ the different base name for the module info variables.")
"${repo_build_interface_include_dir}/${${result}_private_include_dir}")
set("${result}_build_interface_qpa_include_dir"
"${repo_build_interface_include_dir}/${${result}_qpa_include_dir}")
set("${result}_build_interface_rhi_include_dir"
"${repo_build_interface_include_dir}/${${result}_rhi_include_dir}")
# Module install interface directories
set(repo_install_interface_include_dir "${INSTALL_INCLUDEDIR}")
@ -992,6 +1028,8 @@ the different base name for the module info variables.")
"${repo_install_interface_include_dir}/${${result}_private_include_dir}")
set("${result}_install_interface_qpa_include_dir"
"${repo_install_interface_include_dir}/${${result}_qpa_include_dir}")
set("${result}_install_interface_rhi_include_dir"
"${repo_install_interface_include_dir}/${${result}_rhi_include_dir}")
set("${result}" "${module}" PARENT_SCOPE)
set("${result}_versioned" "${module_versioned}" PARENT_SCOPE)
@ -1005,6 +1043,7 @@ the different base name for the module info variables.")
"${${result}_versioned_inner_include_dir}" PARENT_SCOPE)
set("${result}_private_include_dir" "${${result}_private_include_dir}" PARENT_SCOPE)
set("${result}_qpa_include_dir" "${${result}_qpa_include_dir}" PARENT_SCOPE)
set("${result}_rhi_include_dir" "${${result}_rhi_include_dir}" PARENT_SCOPE)
set("${result}_interface_name" "${module_interface_name}" PARENT_SCOPE)
# Setting module build interface directories in parent scope
@ -1019,6 +1058,8 @@ the different base name for the module info variables.")
"${${result}_build_interface_private_include_dir}" PARENT_SCOPE)
set("${result}_build_interface_qpa_include_dir"
"${${result}_build_interface_qpa_include_dir}" PARENT_SCOPE)
set("${result}_build_interface_rhi_include_dir"
"${${result}_build_interface_rhi_include_dir}" PARENT_SCOPE)
# Setting module install interface directories in parent scope
set(repo_install_interface_include_dir "${repo_install_interface_include_dir}" PARENT_SCOPE)
@ -1032,6 +1073,8 @@ the different base name for the module info variables.")
"${${result}_install_interface_private_include_dir}" PARENT_SCOPE)
set("${result}_install_interface_qpa_include_dir"
"${${result}_install_interface_qpa_include_dir}" PARENT_SCOPE)
set("${result}_install_interface_rhi_include_dir"
"${${result}_install_interface_rhi_include_dir}" PARENT_SCOPE)
endfunction()
function(qt_internal_list_to_json_array out_var list_var)
@ -1075,6 +1118,10 @@ function(qt_describe_module target)
endif()
set(extra_build_information "")
if(NOT QT_NAMESPACE STREQUAL "")
string(APPEND extra_build_information "
\"namespace\": \"${QT_NAMESPACE}\",")
endif()
if(ANDROID)
string(APPEND extra_build_information "
\"android\": {
@ -1135,7 +1182,7 @@ endfunction()
function(qt_internal_install_module_headers target)
set(options)
set(one_value_args)
set(multi_value_args PUBLIC PRIVATE QPA)
set(multi_value_args PUBLIC PRIVATE QPA RHI)
cmake_parse_arguments(arg "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
qt_internal_module_info(module ${target})
@ -1160,6 +1207,7 @@ function(qt_internal_install_module_headers target)
PUBLIC ${arg_PUBLIC}
PRIVATE ${arg_PRIVATE}
QPA ${arg_QPA}
RHI ${arg_RHI}
)
else()
if(arg_PUBLIC)
@ -1173,6 +1221,9 @@ function(qt_internal_install_module_headers target)
if(arg_QPA)
qt_install(FILES ${arg_QPA} DESTINATION "${module_install_interface_qpa_include_dir}")
endif()
if(arg_RHI)
qt_install(FILES ${arg_RHI} DESTINATION "${module_install_interface_rhi_include_dir}")
endif()
endif()
endfunction()
@ -1180,6 +1231,7 @@ function(qt_internal_collect_module_headers out_var target)
set(${out_var}_public "")
set(${out_var}_private "")
set(${out_var}_qpa "")
set(${out_var}_rhi "")
set(${out_var}_all "")
qt_internal_get_target_sources(sources ${target})
@ -1200,6 +1252,7 @@ function(qt_internal_collect_module_headers out_var target)
get_target_property(public_filter ${target} _qt_module_public_headers_filter_regex)
get_target_property(private_filter ${target} _qt_module_private_headers_filter_regex)
get_target_property(qpa_filter ${target} _qt_module_qpa_headers_filter_regex)
get_target_property(rhi_filter ${target} _qt_module_rhi_headers_filter_regex)
set(condition_independent_headers_warning "")
foreach(file_path IN LISTS sources)
@ -1251,6 +1304,8 @@ function(qt_internal_collect_module_headers out_var target)
list(APPEND ${out_var}_all "${file_path}")
if(qpa_filter AND file_name MATCHES "${qpa_filter}")
list(APPEND ${out_var}_qpa "${file_path}")
elseif(rhi_filter AND file_name MATCHES "${rhi_filter}")
list(APPEND ${out_var}_rhi "${file_path}")
elseif(private_filter AND file_name MATCHES "${private_filter}")
list(APPEND ${out_var}_private "${file_path}")
elseif((NOT public_filter OR file_name MATCHES "${public_filter}")
@ -1274,7 +1329,7 @@ function(qt_internal_collect_module_headers out_var target)
endif()
set(header_types public private qpa)
set(header_types public private qpa rhi)
set(has_header_types_properties "")
foreach(header_type IN LISTS header_types)
get_target_property(current_propety_value ${target} _qt_module_has_${header_type}_headers)
@ -1296,5 +1351,6 @@ function(qt_internal_collect_module_headers out_var target)
_qt_module_has_public_headers
_qt_module_has_private_headers
_qt_module_has_qpa_headers
_qt_module_has_rhi_headers
)
endfunction()

View File

@ -148,6 +148,41 @@ while(NOT "${configure_args}" STREQUAL "")
endif()
endwhile()
# Read the specified manually generator value from CMake command line.
# The '-cmake-generator' argument has higher priority than CMake command line.
if(NOT generator)
set(is_next_arg_generator_name FALSE)
foreach(arg IN LISTS cmake_args)
if(is_next_arg_generator_name)
set(is_next_arg_generator_name FALSE)
if(NOT arg MATCHES "^-.*")
set(generator "${arg}")
set(auto_detect_generator FALSE)
endif()
elseif(arg MATCHES "^-G(.*)")
set(generator "${CMAKE_MATCH_1}")
if(generator)
set(auto_detect_generator FALSE)
else()
set(is_next_arg_generator_name TRUE)
endif()
endif()
endforeach()
endif()
# Attempt to detect the generator type, either single or multi-config
if("${generator}" STREQUAL "Xcode"
OR "${generator}" STREQUAL "Ninja Multi-Config"
OR "${generator}" MATCHES "^Visual Studio")
set(multi_config ON)
else()
set(multi_config OFF)
endif()
# Tell the build system we are configuring via the configure script so we can act on that.
# The cache variable is unset at the end of configuration.
push("-DQT_INTERNAL_CALLED_FROM_CONFIGURE:BOOL=TRUE")
if(FRESH_REQUESTED)
push("-DQT_INTERNAL_FRESH_REQUESTED:BOOL=TRUE")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
@ -826,6 +861,7 @@ translate_boolean_input(precompile_header BUILD_WITH_PCH)
translate_boolean_input(unity_build QT_UNITY_BUILD)
translate_string_input(unity_build_batch_size QT_UNITY_BUILD_BATCH_SIZE)
translate_boolean_input(ccache QT_USE_CCACHE)
translate_boolean_input(vcpkg QT_USE_VCPKG)
translate_boolean_input(shared BUILD_SHARED_LIBS)
translate_boolean_input(warnings_are_errors WARNINGS_ARE_ERRORS)
translate_string_input(qt_namespace QT_NAMESPACE)
@ -875,6 +911,7 @@ endif()
drop_input(make)
drop_input(nomake)
translate_boolean_input(install-examples-sources QT_INSTALL_EXAMPLES_SOURCES)
check_qt_build_parts(nomake)
check_qt_build_parts(make)
@ -896,9 +933,9 @@ if(INPUT_force_debug_info)
endif()
list(LENGTH build_configs nr_of_build_configs)
if(nr_of_build_configs EQUAL 1)
if(nr_of_build_configs EQUAL 1 AND NOT multi_config)
push("-DCMAKE_BUILD_TYPE=${build_configs}")
elseif(nr_of_build_configs GREATER 1)
elseif(nr_of_build_configs GREATER 1 OR multi_config)
set(multi_config ON)
string(REPLACE ";" "[[;]]" escaped_build_configs "${build_configs}")
# We must not use the push macro here to avoid variable expansion.
@ -983,6 +1020,14 @@ endforeach()
push("${MODULE_ROOT}")
if(INPUT_sysroot)
qtConfAddWarning("The -sysroot option is deprecated and no longer has any effect. "
"It is recommended to use a toolchain file instead, i.e., "
"-DCMAKE_TOOLCHAIN_FILE=<filename>. "
"Alternatively, you may use -DCMAKE_SYSROOT option "
"to pass the sysroot to CMake.\n")
endif()
# Restore the escaped semicolons in arguments that are lists
list(TRANSFORM cmake_args REPLACE "\\[\\[;\\]\\]" "\\\\;")

View File

@ -27,7 +27,7 @@ function(_qt_internal_handle_ios_launch_screen target)
if(NOT launch_screen AND NOT QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN)
set(is_default_launch_screen TRUE)
set(launch_screen
"${__qt_internal_cmake_ios_support_files_path}/LaunchScreen.storyboard")
"${__qt_internal_cmake_apple_support_files_path}/LaunchScreen.storyboard")
endif()
# Check that the launch screen exists.
@ -554,15 +554,13 @@ function(_qt_internal_set_xcode_bitcode_enablement target)
"NO")
endfunction()
function(_qt_internal_generate_ios_info_plist target)
function(_qt_internal_copy_info_plist target)
# If the project already specifies a custom file, we don't override it.
get_target_property(existing_plist "${target}" MACOSX_BUNDLE_INFO_PLIST)
if(existing_plist)
return()
get_target_property(info_plist_in "${target}" MACOSX_BUNDLE_INFO_PLIST)
if(NOT info_plist_in)
set(info_plist_in "${__qt_internal_cmake_apple_support_files_path}/Info.plist.app.in")
endif()
set(info_plist_in "${__qt_internal_cmake_ios_support_files_path}/Info.plist.app.in")
string(MAKE_C_IDENTIFIER "${target}" target_identifier)
set(info_plist_out_dir
"${CMAKE_CURRENT_BINARY_DIR}/.qt/info_plist/${target_identifier}")
@ -592,6 +590,62 @@ function(_qt_internal_generate_ios_info_plist target)
set_target_properties("${target}" PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${info_plist_out}")
endfunction()
function(_qt_internal_plist_buddy plist_file)
cmake_parse_arguments(PARSE_ARGV 1 arg
"" "OUTPUT_VARIABLE;ERROR_VARIABLE" "COMMANDS")
foreach(command ${arg_COMMANDS})
execute_process(COMMAND "/usr/libexec/PlistBuddy"
-c "${command}" "${plist_file}"
OUTPUT_VARIABLE plist_buddy_output
ERROR_VARIABLE plist_buddy_error)
string(STRIP "${plist_buddy_output}" plist_buddy_output)
if(arg_OUTPUT_VARIABLE)
list(APPEND ${arg_OUTPUT_VARIABLE} ${plist_buddy_output})
set(${arg_OUTPUT_VARIABLE} ${${arg_OUTPUT_VARIABLE}} PARENT_SCOPE)
endif()
if(arg_ERROR_VARIABLE)
list(APPEND ${arg_ERROR_VARIABLE} ${plist_buddy_error})
set(${arg_ERROR_VARIABLE} ${${arg_ERROR_VARIABLE}} PARENT_SCOPE)
endif()
if(plist_buddy_error)
return()
endif()
endforeach()
endfunction()
function(_qt_internal_set_apple_localizations target)
if(QT_NO_SET_PLIST_LOCALIZATIONS)
return()
endif()
get_target_property(supported_languages "${target}" _qt_apple_supported_languages)
if("${supported_languages}" STREQUAL "supported_languages-NOTFOUND")
return()
endif()
get_target_property(plist_file "${target}" MACOSX_BUNDLE_INFO_PLIST)
if (NOT plist_file)
return()
endif()
_qt_internal_plist_buddy("${plist_file}"
COMMANDS "print CFBundleLocalizations"
OUTPUT_VARIABLE existing_localizations
)
if(existing_localizations)
return()
endif()
list(TRANSFORM supported_languages PREPEND
"Add CFBundleLocalizations: string ")
_qt_internal_plist_buddy("${plist_file}"
COMMANDS
"Add CFBundleLocalizations array"
${supported_languages}
"Delete CFBundleAllowMixedLocalizations"
)
endfunction()
function(_qt_internal_set_ios_simulator_arch target)
if(CMAKE_XCODE_ATTRIBUTE_ARCHS
OR QT_NO_SET_XCODE_ARCHS)
@ -621,6 +675,9 @@ endfunction()
function(_qt_internal_finalize_apple_app target)
# Shared between macOS and iOS apps
_qt_internal_copy_info_plist("${target}")
_qt_internal_set_apple_localizations("${target}")
# Only set the various properties if targeting the Xcode generator, otherwise the various
# Xcode tokens are embedded as-is instead of being dynamically evaluated.
# This affects things like the version number or application name as reported by Qt API.
@ -637,12 +694,12 @@ function(_qt_internal_finalize_apple_app target)
endfunction()
function(_qt_internal_finalize_ios_app target)
_qt_internal_finalize_apple_app("${target}")
# Must be called before we generate the Info.plist
_qt_internal_handle_ios_launch_screen("${target}")
_qt_internal_finalize_apple_app("${target}")
_qt_internal_set_xcode_targeted_device_family("${target}")
_qt_internal_set_xcode_bitcode_enablement("${target}")
_qt_internal_handle_ios_launch_screen("${target}")
_qt_internal_generate_ios_info_plist("${target}")
_qt_internal_set_ios_simulator_arch("${target}")
endfunction()

View File

@ -53,7 +53,7 @@ endfunction()
function(__qt_internal_get_emcc_recommended_version out_var)
# This version of Qt needs this version of emscripten.
set(QT_EMCC_RECOMMENDED_VERSION "3.1.25")
set(QT_EMCC_RECOMMENDED_VERSION "3.1.37")
set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE)
endfunction()
@ -81,12 +81,16 @@ function(__qt_internal_get_qt_build_emsdk_version out_var)
endif()
if(EXISTS "${WASM_BUILD_DIR}/src/corelib/global/qconfig.h")
file(READ "${WASM_BUILD_DIR}/src/corelib/global/qconfig.h" ver)
else()
elseif(EXISTS "${WASM_BUILD_DIR}/include/QtCore/qconfig.h")
file(READ "${WASM_BUILD_DIR}/include/QtCore/qconfig.h" ver)
else()
message("qconfig.h not found, unable to determine Qt build Emscripten version")
endif()
if (ver)
string(REGEX MATCH "#define QT_EMCC_VERSION.\"[0-9]+\\.[0-9]+\\.[0-9]+\"" emOutput ${ver})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" build_emcc_version "${emOutput}")
set(${out_var} "${build_emcc_version}" PARENT_SCOPE)
endif()
string(REGEX MATCH "#define QT_EMCC_VERSION.\"[0-9]+\\.[0-9]+\\.[0-9]+\"" emOutput ${ver})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" build_emcc_version "${emOutput}")
set(${out_var} "${build_emcc_version}" PARENT_SCOPE)
endfunction()
function(_qt_test_emscripten_version)

View File

@ -37,8 +37,6 @@ function(qt_generate_qconfig_cpp in_file out_file)
set(QT_SYS_CONF_DIR "${INSTALL_SYSCONFDIR}")
# Compute and set relocation prefixes.
# 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
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
@ -213,6 +211,7 @@ function(qt_get_qmake_module_name result module)
string(REGEX REPLACE "^Qt6" "" module "${module}")
string(REGEX REPLACE "Private$" "_private" module "${module}")
string(REGEX REPLACE "Qpa$" "_qpa_lib_private" module "${module}")
string(REGEX REPLACE "Rhi$" "_rhi_lib_private" module "${module}")
string(TOLOWER "${module}" module)
set(${result} ${module} PARENT_SCOPE)
endfunction()

View File

@ -3,10 +3,14 @@
function(qt_internal_add_resource target resourceName)
if(NOT TARGET "${target}")
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT in_batch)
message(FATAL_ERROR "Trying to add resource to a non-existing target \"${target}\".")
endif()
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()

View File

@ -8,18 +8,14 @@
set(QT_BUILDING_QT TRUE CACHE BOOL
"When this is present and set to true, it signals that we are building Qt from source.")
# Pre-calculate the developer_build feature if it's set by the user via INPUT_developer_build
if(NOT FEATURE_developer_build AND INPUT_developer_build
AND NOT "${INPUT_developer_build}" STREQUAL "undefined")
set(FEATURE_developer_build ON)
endif()
# Pre-calculate the developer_build feature if it's set by the user via the INPUT_developer_build
# variable when using the configure script. When not using configure, don't take the INPUT variable
# into account, so that users can toggle the feature directly in the cache or via IDE.
qt_internal_compute_feature_value_from_possible_input(developer_build)
# Pre-calculate the no_prefix feature if it's set by configure via INPUT_no_prefix.
# This needs to be done before qtbase/configure.cmake is processed.
if(NOT FEATURE_no_prefix AND INPUT_no_prefix
AND NOT "${INPUT_no_prefix}" STREQUAL "undefined")
set(FEATURE_no_prefix ON)
endif()
qt_internal_compute_feature_value_from_possible_input(no_prefix)
set(_default_build_type "Release")
if(FEATURE_developer_build)
@ -49,7 +45,20 @@ unset(QT_EXTRA_BUILD_INTERNALS_VARS)
# Save the global property in a variable to make it available to feature conditions.
get_property(QT_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
# Try to detect if an explicit CMAKE_BUILD_TYPE was set by the user.
# CMake sets CMAKE_BUILD_TYPE_INIT to Debug on most Windows platforms and doesn't set
# anything for UNIXes. CMake assigns CMAKE_BUILD_TYPE_INIT to CMAKE_BUILD_TYPE during
# first project() if CMAKE_BUILD_TYPE has no previous value.
# We use extra information about the state of CMAKE_BUILD_TYPE before the first
# project() call that's set in QtAutodetect.
# STREQUAL check needs to have expanded variables because an undefined var is not equal
# to an empty defined var.
# See also qt_internal_force_set_cmake_build_type_conditionally which is used
# to set the build type when building other repos or tests.
if("${CMAKE_BUILD_TYPE}" STREQUAL "${CMAKE_BUILD_TYPE_INIT}"
AND NOT __qt_auto_detect_cmake_build_type_before_project_call
AND NOT __qt_build_internals_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
@ -193,6 +202,8 @@ else()
set(QT_INTERNAL_CONFIGURE_FROM_IDE FALSE CACHE INTERNAL "Configuring Qt Project from IDE")
endif()
set(_qt_sync_headers_at_configure_time_default ${QT_INTERNAL_CONFIGURE_FROM_IDE})
if(FEATURE_developer_build)
if(DEFINED QT_CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_EXPORT_COMPILE_COMMANDS ${QT_CMAKE_EXPORT_COMPILE_COMMANDS})
@ -213,11 +224,26 @@ if(FEATURE_developer_build)
if (CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL Debug)
set(__build_benchmarks OFF)
endif()
# Sync headers during the initial configuration of a -developer-build to facilitate code
# navigation for code editors that use an LSP-based code model.
set(_qt_sync_headers_at_configure_time_default TRUE)
else()
set(_qt_build_tests_default OFF)
set(__build_benchmarks OFF)
endif()
# Sync Qt header files at configure time
option(QT_SYNC_HEADERS_AT_CONFIGURE_TIME "Run syncqt at configure time already"
${_qt_sync_headers_at_configure_time_default})
unset(_qt_sync_headers_at_configure_time_default)
# In static Ninja Multi-Config builds the sync_headers dependencies(and other autogen dependencies
# are not added to '_autogen/timestamp' targets. See QTBUG-113974.
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND NOT QT_BUILD_SHARED_LIBS)
set(QT_SYNC_HEADERS_AT_CONFIGURE_TIME TRUE CACHE BOOL "" FORCE)
endif()
# Build Benchmarks
option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks})
if(QT_BUILD_BENCHMARKS)
@ -255,10 +281,10 @@ endif()
option(QT_BUILD_TESTS_BATCHED "Link all tests into a single binary." ${_qt_batch_tests})
if(QT_BUILD_TESTS AND QT_BUILD_TESTS_BATCHED AND CMAKE_VERSION VERSION_LESS "3.18")
if(QT_BUILD_TESTS AND QT_BUILD_TESTS_BATCHED AND CMAKE_VERSION VERSION_LESS "3.19")
message(FATAL_ERROR
"Test batching requires at least CMake 3.18, due to requiring per-source "
"TARGET_DIRECTORY assignments.")
"Test batching requires at least CMake 3.19, due to requiring per-source "
"TARGET_DIRECTORY assignments and DEFER calls.")
endif()
# QT_BUILD_TOOLS_WHEN_CROSSCOMPILING -> QT_FORCE_BUILD_TOOLS
@ -285,6 +311,9 @@ enable_testing()
option(QT_BUILD_EXAMPLES "Build Qt examples" OFF)
option(QT_BUILD_EXAMPLES_BY_DEFAULT "Should examples be built as part of the default 'all' target." ON)
option(QT_INSTALL_EXAMPLES_SOURCES "Install example sources" OFF)
option(QT_INSTALL_EXAMPLES_SOURCES_BY_DEFAULT
"Install example sources as part of the default 'install' target" ON)
# FIXME: Support prefix builds as well QTBUG-96232
if(QT_WILL_INSTALL)
@ -354,31 +383,11 @@ endif()
option(QT_ALLOW_SYMLINK_IN_PATHS "Allows symlinks in paths." OFF)
# We need to clean up QT_FEATURE_*, but only once per configuration cycle
get_property(qt_feature_clean GLOBAL PROPERTY _qt_feature_clean)
if(NOT qt_feature_clean)
message(STATUS "Check for feature set changes")
set_property(GLOBAL PROPERTY _qt_feature_clean TRUE)
foreach(feature ${QT_KNOWN_FEATURES})
if(DEFINED "FEATURE_${feature}" AND
NOT "${QT_FEATURE_${feature}}" STREQUAL "${FEATURE_${feature}}")
message(" '${feature}' is changed from ${QT_FEATURE_${feature}} \
to ${FEATURE_${feature}}")
set(dirty_build TRUE)
endif()
unset("QT_FEATURE_${feature}" CACHE)
endforeach()
set(QT_KNOWN_FEATURES "" CACHE INTERNAL "" FORCE)
if(dirty_build)
set_property(GLOBAL PROPERTY _qt_dirty_build TRUE)
message(WARNING "Re-configuring in existing build folder. \
Some features will be re-evaluated automatically.")
endif()
endif()
qt_internal_detect_dirty_features()
if(NOT QT_BUILD_EXAMPLES)
# Disable deployment setup to avoid warnings about missing patchelf with CMake < 3.21.
set(QT_SKIP_SETUP_DEPLOYMENT ON)
endif()
option(QT_ALLOW_DOWNLOAD "Allows files to be downloaded when building Qt." OFF)

View File

@ -79,6 +79,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
endif()
get_target_property(qpa_filter_regex ${target} _qt_module_qpa_headers_filter_regex)
get_target_property(rhi_filter_regex ${target} _qt_module_rhi_headers_filter_regex)
get_target_property(private_filter_regex ${target} _qt_module_private_headers_filter_regex)
# We need to use the real paths since otherwise it may lead to the invalid work of the
@ -96,6 +97,12 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
)
endif()
if(rhi_filter_regex)
set(rhi_filter_argument
-rhiHeadersFilter "${rhi_filter_regex}"
)
endif()
set(common_syncqt_arguments
-module "${module}"
-sourceDir "${source_dir_real}"
@ -104,8 +111,10 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
-includeDir "${module_build_interface_include_dir}"
-privateIncludeDir "${module_build_interface_private_include_dir}"
-qpaIncludeDir "${module_build_interface_qpa_include_dir}"
-rhiIncludeDir "${module_build_interface_rhi_include_dir}"
-generatedHeaders ${module_headers_generated}
${qpa_filter_argument}
${rhi_filter_argument}
${public_namespaces_filter}
${non_qt_module_argument}
${internal_module_argument}
@ -178,6 +187,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
${syncqt_args_rsp}
${module_headers}
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
"$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_internal_sync_headers_deps>>"
COMMENT
"Running syncqt.cpp for module: ${module}"
VERBATIM
@ -194,6 +204,8 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
${syncqt_outputs}
)
add_dependencies(sync_headers ${target}_sync_headers)
set_target_properties(${target}
PROPERTIES _qt_internal_sync_headers_target ${target}_sync_headers)
if(is_3rd_party_library)
add_dependencies(thirdparty_sync_headers ${target}_sync_headers)
@ -224,7 +236,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
endif()
add_dependencies(sync_all_public_headers ${target}_sync_all_public_headers)
if(NOT is_3rd_party_library AND NOT is_framework)
if(NOT is_3rd_party_library AND NOT is_framework AND module_headers)
# Install all the CaMeL style aliases of header files from the staging directory in one rule
qt_install(DIRECTORY "${syncqt_staging_dir}/"
DESTINATION "${module_install_interface_include_dir}"
@ -246,7 +258,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
# Run sync Qt first time at configure step to make all header files available for the code model
# of IDEs.
get_property(synced_modules GLOBAL PROPERTY _qt_synced_modules)
if(NOT "${module}" IN_LIST synced_modules)
if(NOT "${module}" IN_LIST synced_modules AND QT_SYNC_HEADERS_AT_CONFIGURE_TIME)
message(STATUS "Running syncqt.cpp for module: ${module}")
get_target_property(syncqt_location ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt LOCATION)
execute_process(

View File

@ -20,10 +20,14 @@
# Skip the specified source files by PRECOMPILE_HEADERS feature.
function(qt_internal_extend_target target)
if(NOT TARGET "${target}")
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT in_batch)
message(FATAL_ERROR "Trying to extend a non-existing target \"${target}\".")
endif()
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()
@ -109,6 +113,19 @@ function(qt_internal_extend_target target)
if(NOT base_lib STREQUAL lib)
qt_create_nolink_target("${base_lib}" ${target})
endif()
# Collect _sync_headers targets from libraries that the target depends on. This is
# heuristic way of building the dependency tree between the _sync_headers targets of
# different Qt modules.
if(TARGET "${lib}")
get_target_property(is_private ${lib} _qt_is_private_module)
if(is_private)
get_target_property(lib ${lib} _qt_public_module_target_name)
endif()
set(out_genex "$<TARGET_PROPERTY:${lib},_qt_internal_sync_headers_target>")
set_property(TARGET ${target}
APPEND PROPERTY _qt_internal_sync_headers_deps "${out_genex}")
endif()
endforeach()
# Set-up the target
@ -1018,6 +1035,24 @@ function(qt_internal_mark_as_internal_target target)
set_target_properties(${target} PROPERTIES _qt_is_internal_target TRUE)
endfunction()
# Marks a target with a property to skip it adding it as a dependency when building examples as
# ExternalProjects.
# Needed to create a ${repo}_src global target that examples can depend on in multi-config builds
# due to a bug in AUTOUIC.
#
# See QTBUG-110369.
function(qt_internal_skip_dependency_for_examples target)
set_target_properties(${target} PROPERTIES _qt_skip_dependency_for_examples TRUE)
endfunction()
function(qt_internal_is_target_skipped_for_examples target out_var)
get_property(is_skipped TARGET ${target} PROPERTY _qt_skip_dependency_for_examples)
if(NOT is_skipped)
set(is_skipped FALSE)
endif()
set(${out_var} "${is_skipped}" PARENT_SCOPE)
endfunction()
function(qt_internal_link_internal_platform_for_object_library target)
# We need to apply iOS bitcode flags to object libraries that are associated with internal
# modules or plugins (e.g. object libraries added by qt_internal_add_resource,
@ -1080,11 +1115,15 @@ endfunction()
# The function disables one or multiple internal global definitions that are defined by the
# qt_internal_add_global_definition function for a specific 'target'.
function(qt_internal_undefine_global_definition target)
if(NOT TARGET ${target})
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT ${in_batch})
message(FATAL_ERROR "${target} is not a target.")
endif()
if(NOT TARGET "${target}")
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()
@ -1135,3 +1174,157 @@ function(qt_internal_get_target_sources_property out_var)
endif()
set(${out_var} "${${out_var}}" PARENT_SCOPE)
endfunction()
# This function collects target properties that contain generator expressions and needs to be
# exported. This function is needed since the CMake EXPORT_PROPERTIES property doesn't support
# properties that contain generator expressions.
# Usage: qt_internal_add_genex_properties_export(target properties...)
function(qt_internal_add_genex_properties_export target)
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
set(config_check_begin "")
set(config_check_end "")
if(is_multi_config)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
# The genex snippet is evaluated to '$<NOT:$<BOOL:$<CONFIG>>>' in the generated cmake file.
# The check is only applicable to the 'main' configuration. If user project doesn't use
# multi-config generator, then the check supposed to return true and the value from the
# 'main' configuration supposed to be used.
string(JOIN "" check_if_config_empty
"$<1:$><NOT:"
"$<1:$><BOOL:"
"$<1:$><CONFIG$<ANGLE-R>"
"$<ANGLE-R>"
"$<ANGLE-R>"
)
# The genex snippet is evaluated to '$<CONFIG:'Qt config type'>' in the generated cmake
# file and checks if the config that user uses matches the generated cmake file config.
string(JOIN "" check_user_config
"$<1:$><CONFIG:$<CONFIG>$<ANGLE-R>"
)
# The genex snippet is evaluated to '$<$<OR:$<CONFIG:'Qt config type'>>:'Property content'>
# for non-main Qt configs and to
# $<$<OR:$<CONFIG:'Qt config type'>,$<NOT:$<BOOL:$<CONFIG>>>>:'Property content'> for the
# main Qt config. This guard is required to choose the correct value of the property for the
# user project according to the user config type.
# All genexes need to be escaped properly to protect them from evaluation by the
# file(GENERATE call in the qt_internal_export_genex_properties function.
string(JOIN "" config_check_begin
"$<1:$><"
"$<1:$><OR:"
"${check_user_config}"
"$<$<CONFIG:${first_config_type}>:$<COMMA>${check_if_config_empty}>"
"$<ANGLE-R>:"
)
set(config_check_end "$<ANGLE-R>")
endif()
set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
foreach(property IN LISTS ARGN)
set(target_property_genex "$<TARGET_PROPERTY:${target_name},${property}>")
# All properties that contain lists need to be protected of processing by JOIN genex calls.
# So this escapes the semicolons for these list.
set(target_property_list_escape
"$<JOIN:$<GENEX_EVAL:${target_property_genex}>,\;>")
set(property_value
"\"${config_check_begin}${target_property_list_escape}${config_check_end}\"")
set_property(TARGET ${target} APPEND PROPERTY _qt_export_genex_properties_content
"${property} ${property_value}")
endforeach()
endfunction()
# This function executes generator expressions for the properties that are added by the
# qt_internal_add_genex_properties_export function and sets the calculated values to the
# corresponding properties in the generated ExtraProperties.cmake file. The file then needs to be
# included after the target creation routines in Config.cmake files. It also supports Multi-Config
# builds.
# Arguments:
# EXPORT_NAME_PREFIX:
# The portion of the file name before ExtraProperties.cmake
# CONFIG_INSTALL_DIR:
# Installation location for the file.
# TARGETS:
# The internal target names.
function(qt_internal_export_genex_properties)
set(option_args "")
set(single_args
EXPORT_NAME_PREFIX
CONFIG_INSTALL_DIR
)
set(multi_args TARGETS)
cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN})
if(NOT arg_EXPORT_NAME_PREFIX)
message(FATAL_ERROR "qt_internal_export_genex_properties: "
"Missing EXPORT_NAME_PREFIX argument.")
endif()
if(NOT arg_TARGETS)
message(FATAL_ERROR "qt_internal_export_genex_properties: "
"TARGETS argument must contain at least one target")
endif()
foreach(target IN LISTS arg_TARGETS)
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
set(output_file_base_name "${arg_EXPORT_NAME_PREFIX}ExtraProperties")
set(should_append "")
set(config_suffix "")
if(is_multi_config)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
set(config_suffix "$<$<NOT:$<CONFIG:${first_config_type}>>:-$<CONFIG>>")
# If the generated file belongs to the 'main' config type, we should set property
# but not append it.
string(JOIN "" should_append
"$<$<NOT:$<CONFIG:${first_config_type}>>: APPEND>")
endif()
set(file_name "${output_file_base_name}${config_suffix}.cmake")
qt_path_join(output_file "${arg_CONFIG_INSTALL_DIR}"
"${file_name}")
if(NOT IS_ABSOLUTE "${output_file}")
qt_path_join(output_file "${QT_BUILD_DIR}" "${output_file}")
endif()
set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
string(JOIN "" set_property_begin "set_property(TARGET "
"${target_name}${should_append} PROPERTY "
)
set(set_property_end ")")
set(set_property_glue "${set_property_end}\n${set_property_begin}")
set(property_list
"$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_export_genex_properties_content>>")
string(JOIN "" set_property_content "${set_property_begin}"
"$<JOIN:${property_list},${set_property_glue}>"
"${set_property_end}")
if(is_multi_config)
set(config_includes "")
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
if(NOT first_config_type STREQUAL config)
set(include_file_name
"${output_file_base_name}-${config}.cmake")
list(APPEND config_includes
"include(\"\${CMAKE_CURRENT_LIST_DIR}/${include_file_name}\")")
endif()
endforeach()
list(JOIN config_includes "\n" config_includes_string)
set(config_includes_string
"\n$<$<CONFIG:${first_config_type}>:${config_includes_string}>")
endif()
file(GENERATE OUTPUT "${output_file}"
CONTENT "$<$<BOOL:${property_list}>:${set_property_content}${config_includes_string}>"
CONDITION "$<BOOL:${property_list}>"
)
endforeach()
qt_install(FILES "$<$<BOOL:${property_list}>:${output_file}>"
DESTINATION "${arg_CONFIG_INSTALL_DIR}"
COMPONENT Devel
)
endfunction()

View File

@ -247,6 +247,7 @@ function(qt_internal_add_test_to_batch batch_name name)
# Lazy-init the test batch
if(NOT TARGET ${target})
qt_internal_library_deprecation_level(deprecation_define)
qt_internal_add_executable(${target}
${exceptions_text}
${gui_text}
@ -254,11 +255,16 @@ function(qt_internal_add_test_to_batch batch_name name)
NO_INSTALL
OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build_dir"
SOURCES "${QT_CMAKE_DIR}/qbatchedtestrunner.in.cpp"
DEFINES QTEST_BATCH_TESTS
DEFINES QTEST_BATCH_TESTS ${deprecation_define}
INCLUDE_DIRECTORIES ${private_includes}
LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Core
${QT_CMAKE_EXPORT_NAMESPACE}::Test
${QT_CMAKE_EXPORT_NAMESPACE}::TestPrivate
# Add GUI by default so that the plugins link properly with non-standalone
# build of tests. Plugin handling is currently only done in
# qt_internal_add_executable if Gui is present. This should be reevaluated with
# multiple batches.
${QT_CMAKE_EXPORT_NAMESPACE}::Gui
)
set_property(TARGET ${target} PROPERTY _qt_has_exceptions ${arg_EXCEPTIONS})
@ -309,17 +315,12 @@ function(qt_internal_add_test_to_batch batch_name name)
list(PREPEND batched_test_list ${name})
set_property(GLOBAL PROPERTY _qt_batched_test_list_property ${batched_test_list})
qt_internal_library_deprecation_level(deprecation_define)
# Merge the current test with the rest of the batch
qt_internal_extend_target(${target}
INCLUDE_DIRECTORIES ${arg_INCLUDE_DIRECTORIES}
PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES}
LIBRARIES ${arg_LIBRARIES}
SOURCES ${arg_SOURCES}
DEFINES
${arg_DEFINES}
${deprecation_define}
COMPILE_OPTIONS ${arg_COMPILE_OPTIONS}
COMPILE_FLAGS ${arg_COMPILE_FLAGS}
LINK_OPTIONS ${arg_LINK_OPTIONS}
@ -336,7 +337,7 @@ function(qt_internal_add_test_to_batch batch_name name)
set_source_files_properties(${source}
TARGET_DIRECTORY ${target}
PROPERTIES COMPILE_DEFINITIONS
"BATCHED_TEST_NAME=\"${name}\"")
"BATCHED_TEST_NAME=\"${name}\";${arg_DEFINES}" )
endforeach()
set(${batch_name} ${target} PARENT_SCOPE)
@ -363,6 +364,34 @@ function(qt_internal_is_in_test_batch out name)
endif()
endfunction()
function(qt_internal_is_skipped_test out name)
get_target_property(is_skipped_test ${name} _qt_is_skipped_test)
set(${out} ${is_skipped_test} PARENT_SCOPE)
endfunction()
function(qt_internal_set_skipped_test name)
set_target_properties(${name} PROPERTIES _qt_is_skipped_test TRUE)
endfunction()
function(qt_internal_is_qtbase_test out)
get_filename_component(dir "${CMAKE_CURRENT_BINARY_DIR}" ABSOLUTE)
set(${out} FALSE PARENT_SCOPE)
while(TRUE)
get_filename_component(filename "${dir}" NAME)
if("${filename}" STREQUAL "qtbase")
set(${out} TRUE PARENT_SCOPE)
break()
endif()
set(prev_dir "${dir}")
get_filename_component(dir "${dir}" DIRECTORY)
if("${dir}" STREQUAL "${prev_dir}")
break()
endif()
endwhile()
endfunction()
function(qt_internal_get_batched_test_arguments out testname)
if(WASM)
# Add a query string to the runner document, so that the script therein
@ -403,6 +432,32 @@ function(qt_internal_add_test name)
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_validate_no_unity_build(arg)
set(batch_current_test FALSE)
if(QT_BUILD_TESTS_BATCHED AND NOT arg_NO_BATCH AND NOT arg_QMLTEST AND NOT arg_MANUAL
AND ("${QT_STANDALONE_TEST_PATH}" STREQUAL ""
OR DEFINED ENV{QT_BATCH_STANDALONE_TESTS}))
set(batch_current_test TRUE)
endif()
if(batch_current_test OR (QT_BUILD_TESTS_BATCHED AND arg_QMLTEST))
if (QT_SUPERBUILD OR DEFINED ENV{TESTED_MODULE_COIN})
set(is_qtbase_test FALSE)
if(QT_SUPERBUILD)
qt_internal_is_qtbase_test(is_qtbase_test)
elseif($ENV{TESTED_MODULE_COIN} STREQUAL "qtbase")
set(is_qtbase_test TRUE)
endif()
if(NOT is_qtbase_test)
file(GENERATE OUTPUT "dummy${name}.cpp" CONTENT "int main() { return 0; }")
# Add a dummy target to tackle some potential problems
qt_internal_add_executable(${name} SOURCES "dummy${name}.cpp")
# Batched tests outside of qtbase are unsupported and skipped
qt_internal_set_skipped_test(${name})
return()
endif()
endif()
endif()
if (NOT arg_OUTPUT_DIRECTORY)
set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
@ -421,9 +476,8 @@ function(qt_internal_add_test name)
"removed in a future Qt version. Use the LIBRARIES option instead.")
endif()
if(NOT arg_NO_BATCH AND QT_BUILD_TESTS_BATCHED AND NOT arg_QMLTEST AND NOT arg_MANUAL)
if(batch_current_test)
qt_internal_add_test_to_batch(name ${name} ${ARGN})
set(setting_up_batched_test TRUE)
elseif(arg_SOURCES)
if(QT_BUILD_TESTS_BATCHED AND arg_QMLTEST)
message(WARNING "QML tests won't be batched - unsupported (yet)")
@ -499,7 +553,6 @@ function(qt_internal_add_test name)
qt_internal_extend_target("${name}" CONDITION ANDROID
LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Gui
)
set(setting_up_batched_test FALSE)
set_target_properties(${name} PROPERTIES _qt_is_test_executable TRUE)
set_target_properties(${name} PROPERTIES _qt_is_manual_test ${arg_MANUAL})
endif()
@ -550,7 +603,7 @@ function(qt_internal_add_test name)
elseif(WASM)
# The test script expects an html file. In case of batched tests, the
# version specialized for running batches has to be supplied.
if(setting_up_batched_test)
if(batch_current_test)
get_target_property(batch_output_dir ${name} RUNTIME_OUTPUT_DIRECTORY)
set(test_executable "${batch_output_dir}/${name}.html")
else()
@ -562,11 +615,16 @@ function(qt_internal_add_test name)
list(APPEND extra_test_args "--silence_timeout=60")
# TODO: Add functionality to specify browser
list(APPEND extra_test_args "--browser=chrome")
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
list(APPEND extra_test_args "--kill_exit")
# We always want to enable asyncify for tests, as some of them use exec
# Tests may require asyncify if they use exec(). Enable asyncify for
# batched tests since this is the configuration used on the CI system.
# Optimize for size (-Os), since asyncify tends to make the resulting
# binary very large
target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
if(batch_current_test)
target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
endif()
# This tells cmake to run the tests with this script, since wasm files can't be
# executed directly
@ -588,9 +646,11 @@ function(qt_internal_add_test name)
endif()
if(NOT arg_MANUAL)
if(setting_up_batched_test)
if(batch_current_test)
qt_internal_get_batched_test_arguments(batched_test_args ${testname})
list(PREPEND extra_test_args ${batched_test_args})
elseif(WASM AND CMAKE_BUILD_TYPE STREQUAL "Debug")
list(PREPEND extra_test_args "qvisualoutput")
endif()
qt_internal_collect_command_environment(test_env_path test_env_plugin_path)
@ -661,10 +721,29 @@ function(qt_internal_add_test name)
foreach(testdata IN LISTS arg_TESTDATA)
list(APPEND builtin_files ${testdata})
endforeach()
foreach(file IN LISTS builtin_files)
set_source_files_properties(${file}
PROPERTIES QT_SKIP_QUICKCOMPILER TRUE
)
endforeach()
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
list(APPEND builtin_files ${blacklist_path})
if(batch_current_test)
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
get_target_property(blacklist_files ${name} _qt_blacklist_files)
if(NOT blacklist_files)
set_target_properties(${name} PROPERTIES _qt_blacklist_files "")
set(blacklist_files "")
cmake_language(EVAL CODE "cmake_language(DEFER DIRECTORY \"${CMAKE_SOURCE_DIR}\" CALL \"_qt_internal_finalize_batch\" \"${name}\") ")
endif()
list(PREPEND blacklist_files "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
set_target_properties(${name} PROPERTIES _qt_blacklist_files "${blacklist_files}")
endif()
else()
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
list(APPEND builtin_files ${blacklist_path})
endif()
endif()
list(REMOVE_DUPLICATES builtin_files)
@ -762,7 +841,8 @@ for this function. Will be ignored")
endif()
set(executable_name ${arg_NAME})
if(QT_BUILD_TESTS_BATCHED)
qt_internal_is_in_test_batch(is_in_batch ${executable_name})
if(is_in_batch)
_qt_internal_test_batch_target_name(executable_name)
endif()
add_test(NAME "${arg_NAME}" COMMAND "${CMAKE_COMMAND}" "-P" "${arg_OUTPUT_FILE}"
@ -828,8 +908,8 @@ function(qt_internal_add_test_helper name)
set(extra_args_to_pass)
if(NOT arg_OVERRIDE_OUTPUT_DIRECTORY)
if(QT_BUILD_TESTS_BATCHED)
_qt_internal_test_batch_target_name(test_batch_target_name)
_qt_internal_test_batch_target_name(test_batch_target_name)
if(QT_BUILD_TESTS_BATCHED AND TARGET ${test_batch_target_name})
get_target_property(
test_batch_output_dir ${test_batch_target_name} RUNTIME_OUTPUT_DIRECTORY)
set(extra_args_to_pass OUTPUT_DIRECTORY "${test_batch_output_dir}")

View File

@ -8,7 +8,8 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
target_link_options("${wasmTarget}" INTERFACE
"SHELL:-s MAX_WEBGL_VERSION=2"
"SHELL:-s FETCH=1"
"SHELL:-s WASM_BIGINT=1")
"SHELL:-s WASM_BIGINT=1"
"SHELL:-s STACK_SIZE=5MB")
target_link_libraries("${wasmTarget}" INTERFACE embind)
@ -93,17 +94,25 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
# plugins are SIDE_MODULE
target_compile_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:" -s SIDE_MODULE=1>)
target_link_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:" -s SIDE_MODULE=1>)
set(side_modules
MODULE_LIBRARY SHARED_LIBRARY)
set(enable_side_module_if_needed
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,${side_modules}>:SHELL:-s SIDE_MODULE=1>")
set(enable_main_module_if_needed
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:-s MAIN_MODULE=1>")
set(set_shared_module_type_if_needed
"${enable_side_module_if_needed}"
"${enable_main_module_if_needed}"
)
# shared libs are SIDE_MODULE
target_compile_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:" -s SIDE_MODULE=1>)
# Add Qt libdir to linker library paths
set(qt_lib_location
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
target_link_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:" -s SIDE_MODULE=1>)
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:" -L${qt_lib_location}/>)
target_compile_options("${wasmTarget}" INTERFACE "${set_shared_module_type_if_needed}")
target_link_options("${wasmTarget}" INTERFACE "${set_shared_module_type_if_needed}")
else()
target_link_options("${wasmTarget}" INTERFACE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=1")

View File

@ -39,6 +39,20 @@ function(qt_internal_create_wrapper_scripts)
DESTINATION "${INSTALL_BINDIR}")
endif()
if(generate_unix)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create" @ONLY
NEWLINE_STYLE LF)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create"
DESTINATION "${INSTALL_BINDIR}")
endif()
if(generate_non_unix)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.bat.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.bat" @ONLY
NEWLINE_STYLE CRLF)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.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.

View File

@ -313,3 +313,16 @@ $ cd some/empty/directory
$ ~/Qt/6.0.0/bin/qt-cmake-standalone-test ~/source/of/qtbase/test/auto/corelib/io/qprocess
$ cmake --build .
```
## qt-cmake-create
Generates a simple CMakeLists.txt based on source files in specified project directory.
Example:
```
$ cd some/source/directory/
$ qt-cmake-create
$ qt-cmake -S . -B /build/directory
$ cmake --build /build/directory
```

View File

@ -17,7 +17,6 @@ The following table describes the mapping of configure options to CMake argument
| -no-feature-foo | -DFEATURE_foo=OFF | |
| -list-features | | At the moment: configure with cmake once, |
| | | then use ccmake or cmake-gui to inspect the features. |
| -list-libraries | | |
| -opensource | n/a | |
| -commercial | n/a | |
| -confirm-license | n/a | |
@ -60,6 +59,7 @@ The following table describes the mapping of configure options to CMake argument
| -R <string> | -DQT_EXTRA_RPATHS=path1;path2 | |
| -rpath | negative CMAKE_SKIP_BUILD_RPATH | |
| | negative CMAKE_SKIP_INSTALL_RPATH | |
| | negative CMAKE_MACOSX_RPATH | |
| -reduce-exports | -DFEATURE_reduce_exports=ON | |
| -reduce-relocations | -DFEATURE_reduce_relocations=ON | |
| -plugin-manifests | | |
@ -75,16 +75,9 @@ The following table describes the mapping of configure options to CMake argument
| -ccache | -DQT_USE_CCACHE=ON | |
| -unity-build | -DQT_UNITY_BUILD=ON | |
| -unity-build-batch-size <int> | -DQT_UNITY_BUILD_BATCH_SIZE=<int> | |
| -make-tool <tool> | n/a | |
| -mp | n/a | |
| -warnings-are-errors | -DWARNINGS_ARE_ERRORS=ON | |
| -silent | n/a | |
| -sysroot <dir> | -DCMAKE_SYSROOT=<dir> | Should be provided by a toolchain file that's |
| | | passed via -DCMAKE_TOOLCHAIN_FILE=<filename> |
| -no-gcc-sysroot | n/a | The corresponding CMake variables are CMAKE_SYSROOT_LINK |
| | | and CMAKE_SYSROOT_COMPILE. |
| | | They are usually set in a toolchain file. |
| -no-pkg-config | -DFEATURE_pkg_config=OFF | |
| -no-vcpkg | -DQT_USE_VCPKG=OFF | |
| -D <string> | -DQT_EXTRA_DEFINES=<string1>;<string2> | |
| -I <string> | -DQT_EXTRA_INCLUDEPATHS=<string1>;<string2> | |
| -L <string> | -DQT_EXTRA_LIBDIRS=<string1>;<string2> | |
@ -110,6 +103,7 @@ The following table describes the mapping of configure options to CMake argument
| | | build them separately, after configuration. |
| -nomake <part> | -DQT_BUILD_TESTS=OFF | A way to turn off tools explicitly is missing. |
| | -DQT_BUILD_EXAMPLES=OFF | |
| -install-examples-sources | -DQT_INSTALL_EXAMPLES_SOURCES=ON | |
| -no-gui | -DFEATURE_gui=OFF | |
| -no-widgets | -DFEATURE_widgets=OFF | |
| -no-dbus | -DFEATURE_dbus=OFF | |

View File

@ -1,11 +1,13 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qglobal.h>
#ifndef @header_base_name_upper@_H
#define @header_base_name_upper@_H
#include <QtCore/qcompilerdetection.h>
#include <QtCore/qtconfigmacros.h> // Q_@module_define_infix@_EXPORT
#include <QtCore/qtdeprecationmarkers.h> // QT_IF_DEPRECATED_SINCE
#if defined(QT_SHARED) || !defined(QT_STATIC)
# if defined(QT_BUILD_@module_define_infix@_LIB)
# define Q_@module_define_infix@_EXPORT Q_DECL_EXPORT

View File

@ -4,6 +4,8 @@
#ifndef @header_base_name_upper@_P_H
#define @header_base_name_upper@_P_H
// This file is autogenerated. Changes will be overwritten.
//
// W A R N I N G
// -------------