summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexey Edelev <alexey.edelev@qt.io>2021-04-06 18:57:11 +0200
committerAlexey Edelev <alexey.edelev@qt.io>2021-05-20 19:40:45 +0200
commit425ff34aa10a02524f2d52f544dc00b539ef9a26 (patch)
tree9cc29e0bfb507c60ff0b7cc8209704e5bab04720 /cmake
parent640eb55c130c6c2c982dc212a8a5bd2b8fb7a225 (diff)
Merge main and private targets of the internal modules
In cmake, targets are used as an entity for modules. This causes a number of problems when we want to manipulate a module as a separate entity with properties associated with it. The _qt_internal_module_interface_name target property is introduced to represent the module entity. All modules write a name to this property, which will subsequently expand into the module name matched with the module name in qmake. The 'qt_internal_module_info' function is responsible for providing the correct values ​​for the module properties used when working with a module target. Unlike qmake, for internal modules in cmake it is expected that the Private suffix will be specified explicitly. In case the user wants to have a different module name, an additional argument MODULE_INTERFACE_NAME of the qt_internal_add_module function is introduced. This also changes the way how target dependencies are collected and resolved. Since the 'Private' suffix no longer means an unique identifier of the module 'Private' part, we look for the both Private and non-Private package names when resolving dependencies. TODO: This change doesn't affect the existing internal modules, so to keep compatibility with the existing code the existing internal modules create 'Private' aliases. The code that provides backward compatibility must be removed once all internal modules will get the proper names. Taks-number: QTBUG-87775 Change-Id: Ib4f28341506fb2e73eee960a709e24c42bbcd5ec Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtFindPackageHelpers.cmake16
-rw-r--r--cmake/QtFrameworkHelpers.cmake12
-rw-r--r--cmake/QtModuleDependencies.cmake.in11
-rw-r--r--cmake/QtModuleHelpers.cmake96
-rw-r--r--cmake/QtPluginDependencies.cmake.in9
-rw-r--r--cmake/QtPostProcessHelpers.cmake94
-rw-r--r--cmake/QtSyncQtHelpers.cmake2
7 files changed, 157 insertions, 83 deletions
diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake
index 85dc1ff7db..5bfc0ff4f6 100644
--- a/cmake/QtFindPackageHelpers.cmake
+++ b/cmake/QtFindPackageHelpers.cmake
@@ -254,7 +254,7 @@ function(qt_record_extra_qt_main_tools_package_dependency main_target_name
"${main_target_name}" "${qtfied_package_name_versioned}" "${dep_package_version}")
endfunction()
-# This function stores the list of Qt modules a library depend on,
+# This function stores the list of Qt targets a library depend on,
# along with their version info, for usage in ${target}Depends.cmake file
function(qt_register_target_dependencies target public_libs private_libs)
get_target_property(target_deps "${target}" _qt_target_deps)
@@ -272,15 +272,13 @@ function(qt_register_target_dependencies target public_libs private_libs)
foreach(lib IN LISTS lib_list)
if ("${lib}" MATCHES "^Qt::(.*)")
set(lib "${CMAKE_MATCH_1}")
- if (lib STREQUAL Platform
- OR lib STREQUAL GlobalConfig
- OR lib STREQUAL GlobalConfigPrivate
- OR lib STREQUAL PlatformModuleInternal
- OR lib STREQUAL PlatformPluginInternal
- OR lib STREQUAL PlatformToolInternal)
+ if (lib STREQUAL "Platform"
+ OR lib STREQUAL "GlobalConfig"
+ OR lib STREQUAL "GlobalConfigPrivate"
+ OR lib STREQUAL "PlatformModuleInternal"
+ OR lib STREQUAL "PlatformPluginInternal"
+ OR lib STREQUAL "PlatformToolInternal")
list(APPEND target_deps "Qt6\;${PROJECT_VERSION}")
- elseif ("${lib}" MATCHES "(.*)Private")
- list(APPEND target_deps "${INSTALL_CMAKE_NAMESPACE}${CMAKE_MATCH_1}\;${PROJECT_VERSION}")
else()
list(APPEND target_deps "${INSTALL_CMAKE_NAMESPACE}${lib}\;${PROJECT_VERSION}")
endif()
diff --git a/cmake/QtFrameworkHelpers.cmake b/cmake/QtFrameworkHelpers.cmake
index 6289ce98b1..59555522e4 100644
--- a/cmake/QtFrameworkHelpers.cmake
+++ b/cmake/QtFrameworkHelpers.cmake
@@ -69,10 +69,18 @@ function(qt_copy_framework_headers target)
get_target_property(fw_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
get_target_property(fw_name ${target} OUTPUT_NAME)
set(fw_headers_dir ${fw_dir}/${fw_name}.framework/Versions/${fw_version}/Headers/)
+
+ # The module name might be different of the actual target name.
+ get_target_property(module_interface_name ${target} _qt_module_interface_name)
+ if(module_interface_name)
+ set(module "Qt${module_interface_name}")
+ else()
+ set(module "Qt${target}")
+ endif()
if(ARG_PRIVATE)
- string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/private/")
+ string(APPEND fw_headers_dir "${fw_bundle_version}/${module}/private/")
elseif(ARG_QPA)
- string(APPEND fw_headers_dir "${fw_bundle_version}/Qt${target}/qpa/")
+ string(APPEND fw_headers_dir "${fw_bundle_version}/${module}/qpa/")
endif()
set(out_files)
diff --git a/cmake/QtModuleDependencies.cmake.in b/cmake/QtModuleDependencies.cmake.in
index 5ec9345209..e9159a20d2 100644
--- a/cmake/QtModuleDependencies.cmake.in
+++ b/cmake/QtModuleDependencies.cmake.in
@@ -81,14 +81,23 @@ if(NOT "${QT_HOST_PATH}" STREQUAL "")
set(CMAKE_FIND_ROOT_PATH ${BACKUP_@target@_CMAKE_FIND_ROOT_PATH})
endif()
+# TODO: The dependencies lookup mechanism is common for Modules and Plugins.
+# It should be moved to the common public helper file.
+#
# note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0"
set(_target_deps "@target_deps@")
foreach(_target_dep ${_target_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
- if (NOT ${pkg}_FOUND)
+ if(NOT ${pkg}_FOUND)
+ set(pkg_names ${pkg})
+ if(pkg MATCHES "(.*)Private$")
+ set(pkg_names "${CMAKE_MATCH_1};${pkg}")
+ endif()
find_dependency(${pkg} ${version}
+ NAMES
+ ${pkg_names}
PATHS
"${CMAKE_CURRENT_LIST_DIR}/.."
${_qt_additional_packages_prefix_path}
diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake
index 4d976173df..e53843dc92 100644
--- a/cmake/QtModuleHelpers.cmake
+++ b/cmake/QtModuleHelpers.cmake
@@ -16,6 +16,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
)
set(${single_args}
MODULE_INCLUDE_NAME
+ MODULE_INTERFACE_NAME
CONFIG_MODULE_NAME
PRECOMPILED_HEADER
CONFIGURE_FILE_PATH
@@ -48,9 +49,16 @@ endmacro()
# Don't generate a Qt6*AdditionalTargetInfo.cmake file.
# The caller is responsible for creating one.
#
+# MODULE_INTERFACE_NAME
+# The custom name of the module interface. This name is used as a part of the include paths
+# associated with the module and other interface names. The default value is the target name.
+# If the INTERNAL_MODULE option is specified, MODULE_INTERFACE_NAME is not specified and the
+# target name ends with the suffix 'Private', the MODULE_INTERFACE_NAME value defaults to the
+# non-suffixed target name, e.g.:
+# For the SomeInternalModulePrivate target, the MODULE_INTERFACE_NAME will be
+# SomeInternalModule
+#
function(qt_internal_add_module target)
- qt_internal_module_info(module "${target}")
-
qt_internal_get_internal_add_module_keywords(
option_args
single_args
@@ -64,16 +72,25 @@ function(qt_internal_add_module target)
${ARGN}
)
- qt_internal_add_qt_repo_known_module("${target}")
-
- if(NOT DEFINED arg_CONFIG_MODULE_NAME)
- set(arg_CONFIG_MODULE_NAME "${module_lower}")
+ if(arg_INTERNAL_MODULE)
+ set(arg_INTERNAL_MODULE "INTERNAL_MODULE")
+ set(arg_NO_PRIVATE_MODULE TRUE)
+ # Assume the interface name of the internal module should be the module name without the
+ # 'Private' suffix.
+ if(NOT arg_MODULE_INTERFACE_NAME)
+ if(target MATCHES "(.*)Private$")
+ set(arg_MODULE_INTERFACE_NAME "${CMAKE_MATCH_1}")
+ else()
+ message(WARNING "The internal module target should end with the 'Private' suffix.")
+ endif()
+ endif()
+ else()
+ unset(arg_INTERNAL_MODULE)
endif()
- # Module define needs to take into account the config module name.
- string(TOUPPER "${arg_CONFIG_MODULE_NAME}" module_define_infix)
- string(REPLACE "-" "_" module_define_infix "${module_define_infix}")
- string(REPLACE "." "_" module_define_infix "${module_define_infix}")
+ if(NOT arg_MODULE_INTERFACE_NAME)
+ set(arg_MODULE_INTERFACE_NAME "${target}")
+ endif()
### Define Targets:
set(is_interface_lib 0)
@@ -93,6 +110,23 @@ function(qt_internal_add_module target)
set(is_static_lib 1)
endif()
+ set_target_properties(${target} PROPERTIES
+ _qt_module_interface_name "${arg_MODULE_INTERFACE_NAME}"
+ )
+ set_property(TARGET ${target} APPEND PROPERTY EXPORT_PROPERTIES _qt_module_interface_name)
+
+ qt_internal_module_info(module "${target}")
+ qt_internal_add_qt_repo_known_module("${target}")
+
+ if(NOT arg_CONFIG_MODULE_NAME)
+ set(arg_CONFIG_MODULE_NAME "${module_lower}")
+ endif()
+
+ # Module define needs to take into account the config module name.
+ string(TOUPPER "${arg_CONFIG_MODULE_NAME}" module_define_infix)
+ string(REPLACE "-" "_" module_define_infix "${module_define_infix}")
+ string(REPLACE "." "_" module_define_infix "${module_define_infix}")
+
set(property_prefix "INTERFACE_")
if(NOT arg_HEADER_MODULE)
qt_set_common_target_properties(${target})
@@ -144,15 +178,30 @@ function(qt_internal_add_module target)
qt_skip_warnings_are_errors_when_repo_unclean("${target}")
_qt_internal_apply_strict_cpp("${target}")
+ # No need to compile Q_IMPORT_PLUGIN-containing files for non-executables.
+ if(is_static_lib)
+ _qt_internal_disable_static_default_plugins("${target}")
+ endif()
+
# Add _private target to link against the private headers:
+ set(target_private "${target}Private")
if(NOT ${arg_NO_PRIVATE_MODULE})
- set(target_private "${target}Private")
add_library("${target_private}" INTERFACE)
qt_internal_add_target_aliases("${target_private}")
set_target_properties(${target_private} PROPERTIES
_qt_config_module_name ${arg_CONFIG_MODULE_NAME}_private)
set_property(TARGET "${target_private}" APPEND PROPERTY
EXPORT_PROPERTIES _qt_config_module_name)
+ elseif(arg_INTERNAL_MODULE)
+ # TODO: We need to create temporary alias targets for the internal modules to keep the
+ # existing code compatible to the internal modules that don't have the 'Private' suffix yet.
+ # Remove this once the migration is complete.
+ set(versionless_private_alias "Qt::${target_private}")
+ set(versionfull_private_alias "Qt${PROJECT_VERSION_MAJOR}::${target_private}")
+ add_library("${versionless_private_alias}" ALIAS "${target}")
+ add_library("${versionfull_private_alias}" ALIAS "${target}")
+ unset(versionless_private_alias)
+ unset(versionfull_private_alias)
endif()
if(NOT arg_HEADER_MODULE)
@@ -620,12 +669,6 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}")
- if (${arg_INTERNAL_MODULE})
- set(arg_INTERNAL_MODULE "INTERNAL_MODULE")
- else()
- unset(arg_INTERNAL_MODULE)
- endif()
-
### 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)
@@ -671,7 +714,9 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
"${module_headers_clean}")
endif()
- if(NOT ${arg_NO_PRIVATE_MODULE})
+ if(arg_INTERNAL_MODULE)
+ target_include_directories("${target}" INTERFACE ${interface_includes})
+ elseif(NOT ${arg_NO_PRIVATE_MODULE})
target_include_directories("${target_private}" INTERFACE ${interface_includes})
target_link_libraries("${target_private}" INTERFACE "${target}")
endif()
@@ -706,7 +751,7 @@ function(qt_finalize_module target)
qt_generate_module_pri_file("${target}" ${ARGN})
endfunction()
-# Get a set of Qt module related values based on the target name.
+# Get a set of Qt module related values based on the target.
# When doing qt_internal_module_info(foo Core) this method will set
# the following variables in the caller's scope:
# * foo with the value "QtCore"
@@ -720,11 +765,16 @@ endfunction()
# e.g for QtQuick it would be qtdeclarative_build_dir/include/QtQuick for a prefix build or
# qtbase_build_dir/include/QtQuick for a non-prefix build
function(qt_internal_module_info result target)
- set(module "Qt${target}")
+ get_target_property(module_interface_name ${target} _qt_module_interface_name)
+ if(NOT module_interface_name)
+ message(FATAL_ERROR "${target} is not a module.")
+ endif()
+
+ qt_internal_qtfy_target(module ${module_interface_name})
set("${result}" "${module}" PARENT_SCOPE)
- set("${result}_versioned" "Qt${PROJECT_VERSION_MAJOR}${target}" PARENT_SCOPE)
- string(TOUPPER "${target}" upper)
- string(TOLOWER "${target}" lower)# * foo_upper with the value "CORE"
+ set("${result}_versioned" "${module_versioned}" PARENT_SCOPE)
+ string(TOUPPER "${module_interface_name}" upper)
+ string(TOLOWER "${module_interface_name}" lower)# * foo_upper with the value "CORE"
set("${result}_upper" "${upper}" PARENT_SCOPE)
set("${result}_lower" "${lower}" PARENT_SCOPE)
set("${result}_repo_include_dir" "${QT_BUILD_DIR}/include" PARENT_SCOPE)
diff --git a/cmake/QtPluginDependencies.cmake.in b/cmake/QtPluginDependencies.cmake.in
index 7bd1eef9aa..f64cc77714 100644
--- a/cmake/QtPluginDependencies.cmake.in
+++ b/cmake/QtPluginDependencies.cmake.in
@@ -32,6 +32,9 @@ if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(__qt_use_no_default_path_for_qt_packages "")
endif()
+# TODO: The dependencies lookup mechanism is common for Modules and Plugins.
+# It should be moved to the common public helper file.
+#
# note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0"
set(_target_deps "@target_deps@")
foreach(_target_dep ${_target_deps})
@@ -39,7 +42,13 @@ foreach(_target_dep ${_target_deps})
list(GET _target_dep 1 version)
if (NOT ${pkg}_FOUND)
+ set(pkg_names ${pkg})
+ if(pkg MATCHES "(.*)Private$")
+ set(pkg_names "${CMAKE_MATCH_1};${pkg}")
+ endif()
find_dependency(${pkg} ${version}
+ NAMES
+ ${pkg_names}
PATHS
@find_dependency_paths@
${_qt_additional_packages_prefix_path}
diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake
index c8d310d93d..9307ea8a20 100644
--- a/cmake/QtPostProcessHelpers.cmake
+++ b/cmake/QtPostProcessHelpers.cmake
@@ -3,7 +3,7 @@ function(qt_internal_write_depends_file module)
set(contents "/* This file was generated by cmake with the info from ${module} target. */\n")
string(APPEND contents "#ifdef __cplusplus /* create empty PCH in C mode */\n")
foreach (m ${ARGN})
- string(APPEND contents "# include <Qt${m}/Qt${m}>\n")
+ string(APPEND contents "# include <${m}/${m}>\n")
endforeach()
string(APPEND contents "#endif\n")
@@ -64,6 +64,41 @@ macro(qt_collect_third_party_deps target)
endforeach()
endmacro()
+# Filter the dependency targets to collect unique set of the dependencies.
+# non-Private and Private targets are treated as the single object in this context
+# since they are defined by the same CMake package. For internal modules
+# the CMake package will be always Private.
+function(qt_internal_remove_qt_dependency_duplicates out_deps deps)
+ set(${out_deps} "")
+ foreach(dep ${deps})
+ if(dep)
+ list(FIND ${out_deps} "${dep}" dep_seen)
+
+ # If the library depends on the Private and non-Private targets,
+ # we only need to 'find_dependency' for one of them.
+ if(dep_seen EQUAL -1 AND "${dep}" MATCHES "(.+)Private\;(.+)")
+ list(FIND ${out_deps} "${CMAKE_MATCH_1};${CMAKE_MATCH_2}" dep_seen)
+ endif()
+ if(dep_seen EQUAL -1)
+ list(LENGTH dep len)
+ if(NOT (len EQUAL 2))
+ message(FATAL_ERROR "List '${dep}' should look like QtFoo;version")
+ endif()
+ list(GET dep 0 dep_name)
+ list(GET dep 1 dep_ver)
+
+ # Skip over Qt6 dependency, because we will manually handle it in the Dependencies
+ # file before everything else, to ensure that find_package(Qt6Core)-style works.
+ if(dep_name STREQUAL "${INSTALL_CMAKE_NAMESPACE}")
+ continue()
+ endif()
+ list(APPEND ${out_deps} "${dep_name}\;${dep_ver}")
+ endif()
+ endif()
+ endforeach()
+ set(${out_deps} "${${out_deps}}" PARENT_SCOPE)
+endfunction()
+
function(qt_internal_create_module_depends_file target)
get_target_property(target_type "${target}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
@@ -93,7 +128,7 @@ function(qt_internal_create_module_depends_file target)
if(NOT arg_HEADER_MODULE)
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
endif()
- if(NOT extra_depends STREQUAL "${extra_depends}-NOTFOUND")
+ if(NOT extra_depends MATCHES "-NOTFOUND$")
list(APPEND target_deps "${extra_depends}")
endif()
@@ -152,13 +187,11 @@ function(qt_internal_create_module_depends_file target)
endif()
endif()
endif()
- if (dep MATCHES "(.*)Private")
- set(dep "${CMAKE_MATCH_1}")
- endif()
list(FIND known_modules "${dep}" _pos)
if (_pos GREATER -1)
- list(APPEND qtdeps "${dep}")
+ qt_internal_module_info(module ${QT_CMAKE_EXPORT_NAMESPACE}::${dep})
+ list(APPEND qtdeps ${module})
# Make the ModuleTool package depend on dep's ModuleTool package.
list(FIND tool_deps_seen ${dep} dep_seen)
@@ -178,33 +211,16 @@ function(qt_internal_create_module_depends_file target)
"${INSTALL_CMAKE_NAMESPACE}${target}Tools\;${PROJECT_VERSION}")
endif()
- # Dirty deduplication hack because of https://gitlab.kitware.com/cmake/cmake/issues/19200
foreach(dep ${target_deps})
- if(dep)
- list(FIND target_deps_seen "${dep}" dep_seen)
- if(dep_seen EQUAL -1)
- list(LENGTH dep len)
- if(NOT (len EQUAL 2))
- message(FATAL_ERROR "List '${dep}' should look like QtFoo;version")
- endif()
- list(GET dep 0 dep_name)
- list(GET dep 1 dep_ver)
-
- # Skip over Qt6 dependency, because we will manually handle it in the Dependencies
- # file before everything else, to ensure that find_package(Qt6Core)-style works.
- if(dep_name STREQUAL INSTALL_CMAKE_NAMESPACE)
- continue()
- endif()
-
- list(APPEND target_deps_seen "${dep_name}\;${dep_ver}")
-
- if (dep_name MATCHES "${INSTALL_CMAKE_NAMESPACE}(.*)")
- list(APPEND qt_module_dependencies "${CMAKE_MATCH_1}")
- endif()
- endif()
+ if(NOT dep MATCHES ".+Private$" AND
+ dep MATCHES "${INSTALL_CMAKE_NAMESPACE}(.+)")
+ list(APPEND qt_module_dependencies "${CMAKE_MATCH_1}")
endif()
endforeach()
- set(target_deps "${target_deps_seen}")
+ list(REMOVE_DUPLICATES qt_module_dependencies)
+
+ qt_internal_remove_qt_dependency_duplicates(target_deps "${target_deps}")
+
if (DEFINED qtdeps)
list(REMOVE_DUPLICATES qtdeps)
@@ -251,23 +267,7 @@ function(qt_internal_create_plugin_depends_file target)
qt_collect_third_party_deps(${target})
- # Dirty hack because https://gitlab.kitware.com/cmake/cmake/issues/19200
- foreach(dep ${target_deps})
- if(dep)
- list(FIND target_deps_seen "${dep}" dep_seen)
- if(dep_seen EQUAL -1)
- list(LENGTH dep len)
- if(NOT (len EQUAL 2))
- message(FATAL_ERROR "List '${dep}' should look like QtFoo;version")
- endif()
- list(GET dep 0 dep_name)
- list(GET dep 1 dep_ver)
-
- list(APPEND target_deps_seen "${dep_name}\;${dep_ver}")
- endif()
- endif()
- endforeach()
- set(target_deps "${target_deps_seen}")
+ qt_internal_remove_qt_dependency_duplicates(target_deps "${target_deps}")
if(third_party_deps OR target_deps)
# Setup build and install paths
diff --git a/cmake/QtSyncQtHelpers.cmake b/cmake/QtSyncQtHelpers.cmake
index 2014405017..9e968cd0f3 100644
--- a/cmake/QtSyncQtHelpers.cmake
+++ b/cmake/QtSyncQtHelpers.cmake
@@ -40,7 +40,7 @@ endfunction()
function(qt_install_injections target build_dir install_dir)
set(injections ${ARGN})
- set(module "Qt${target}")
+ qt_internal_module_info(module ${target})
get_target_property(target_type ${target} TYPE)
if (target_type STREQUAL "INTERFACE_LIBRARY")
set(is_framework FALSE)