CMake: Record package provided targets in Dependencies.cmake files
Each qt_find_package can specify a PROVIDED_TARGETS option, to inform which targets will be created by that package. The call then saves the package name, version, etc on each of the provided targets. Currently the provided targets info is not persisted anywhere after configuration ends. We will need this for SBOM creation, so that we can collect information about such dependencies when configuring leaf repos, where find_dependency calls are implicit, and don't contain the PROVIDED_TARGETS option, and we need to go from package name to target name (and any recorded info it the target has). This is especially relevant for static library builds, where private dependencies become public dependencies. Collect the provided targets information at post process time and persist it for each 'package name + components requested' combination into the Dependencies.cmake file. This information will be used in a later change for SBOM generation. Change-Id: I1693f81b1ad3beaf9b02e44b09a5e977923f0d85 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
parent
28c8f8e92a
commit
58eefbd0b6
@ -212,6 +212,15 @@ macro(qt_find_package)
|
|||||||
${components_as_string})
|
${components_as_string})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Record the package + component + optional component provided targets.
|
||||||
|
qt_internal_record_package_component_provided_targets(
|
||||||
|
PACKAGE_NAME "${ARGV0}"
|
||||||
|
ON_TARGET ${qt_find_package_target_name}
|
||||||
|
PROVIDED_TARGETS ${arg_PROVIDED_TARGETS}
|
||||||
|
COMPONENTS ${arg_COMPONENTS}
|
||||||
|
OPTIONAL_COMPONENTS ${arg_OPTIONAL_COMPONENTS}
|
||||||
|
)
|
||||||
|
|
||||||
get_property(is_global TARGET ${qt_find_package_target_name} PROPERTY
|
get_property(is_global TARGET ${qt_find_package_target_name} PROPERTY
|
||||||
IMPORTED_GLOBAL)
|
IMPORTED_GLOBAL)
|
||||||
qt_internal_should_not_promote_package_target_to_global(
|
qt_internal_should_not_promote_package_target_to_global(
|
||||||
@ -237,6 +246,56 @@ macro(qt_find_package)
|
|||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
# Records information about a package's provided targets, given a specific list of components.
|
||||||
|
#
|
||||||
|
# A package might contain multiple components, and create only a subset of targets based on which
|
||||||
|
# components are looked for.
|
||||||
|
# This function computes a unique key / id using the package name and the components that are
|
||||||
|
# passed.
|
||||||
|
# Then it saves the id in a property on the ON_TARGET target. The ON_TARGET target is one
|
||||||
|
# of the provided targets for that package id. This allows us to create a relationship to find
|
||||||
|
# the package id, given a target.
|
||||||
|
# The function also appends the list of provided targets for that package id to a global property.
|
||||||
|
# This information will later be saved into the module Dependencies.cmake file.
|
||||||
|
function(qt_internal_record_package_component_provided_targets)
|
||||||
|
set(opt_args "")
|
||||||
|
set(single_args
|
||||||
|
PACKAGE_NAME
|
||||||
|
ON_TARGET
|
||||||
|
)
|
||||||
|
set(multi_args
|
||||||
|
COMPONENTS
|
||||||
|
OPTIONAL_COMPONENTS
|
||||||
|
PROVIDED_TARGETS
|
||||||
|
)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||||
|
_qt_internal_validate_all_args_are_parsed(arg)
|
||||||
|
|
||||||
|
if(NOT arg_PACKAGE_NAME)
|
||||||
|
message(FATAL_ERROR "PACKAGE_NAME is required.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT arg_ON_TARGET)
|
||||||
|
message(FATAL_ERROR "ON_TARGET is required.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_qt_internal_get_package_components_id(
|
||||||
|
PACKAGE_NAME "${arg_PACKAGE_NAME}"
|
||||||
|
COMPONENTS ${arg_COMPONENTS}
|
||||||
|
OPTIONAL_COMPONENTS ${arg_OPTIONAL_COMPONENTS}
|
||||||
|
OUT_VAR_KEY package_key
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${arg_ON_TARGET} PROPERTIES
|
||||||
|
_qt_package_components_id "${package_key}"
|
||||||
|
)
|
||||||
|
|
||||||
|
_qt_internal_append_to_cmake_property_without_duplicates(
|
||||||
|
_qt_find_package_${package_key}_provided_targets
|
||||||
|
"${arg_PROVIDED_TARGETS}"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Save found packages in the cache. They will be read on next reconfiguration to skip looking
|
# Save found packages in the cache. They will be read on next reconfiguration to skip looking
|
||||||
# for packages that were not previously found.
|
# for packages that were not previously found.
|
||||||
# Only applies to -developer-builds by default.
|
# Only applies to -developer-builds by default.
|
||||||
|
@ -30,6 +30,7 @@ endif()
|
|||||||
|
|
||||||
# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;"
|
# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;"
|
||||||
set(__qt_@target@_third_party_deps "@third_party_deps@")
|
set(__qt_@target@_third_party_deps "@third_party_deps@")
|
||||||
|
@third_party_deps_extra_info@
|
||||||
_qt_internal_find_third_party_dependencies("@target@" __qt_@target@_third_party_deps)
|
_qt_internal_find_third_party_dependencies("@target@" __qt_@target@_third_party_deps)
|
||||||
|
|
||||||
# Find Qt tool package.
|
# Find Qt tool package.
|
||||||
|
@ -67,6 +67,11 @@ macro(qt_collect_third_party_deps target)
|
|||||||
set(package_optional_components "")
|
set(package_optional_components "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
get_target_property(package_components_id ${dep} _qt_package_components_id)
|
||||||
|
if(package_components_id)
|
||||||
|
list(APPEND third_party_deps_package_components_ids ${package_components_id})
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND third_party_deps
|
list(APPEND third_party_deps
|
||||||
"${package_name}\;${package_is_optional}\;${package_version}\;${package_components}\;${package_optional_components}")
|
"${package_name}\;${package_is_optional}\;${package_version}\;${package_components}\;${package_optional_components}")
|
||||||
endif()
|
endif()
|
||||||
@ -74,6 +79,42 @@ macro(qt_collect_third_party_deps target)
|
|||||||
endforeach()
|
endforeach()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
# Collect provided targets for the given list of package component ids.
|
||||||
|
#
|
||||||
|
# ${target} is merely used as a key infix to avoid name clashes in the Dependencies.cmake files.
|
||||||
|
# package_component_ids is a list of '${package_name}-${components}-${optional_components}' keys
|
||||||
|
# that are sanitized not to contain spaces or semicolons.
|
||||||
|
#
|
||||||
|
# The output is a list of variable assignments to add to the dependencies file.
|
||||||
|
# Each variable assignment is the list of provided targets for a given package component id.
|
||||||
|
#
|
||||||
|
# We use these extra assignments instead of adding the info to the existing 'third_party_deps' list
|
||||||
|
# to make the information more readable. That list already has 5 items per package, making it
|
||||||
|
# quite hard to read.
|
||||||
|
function(qt_internal_collect_third_party_dep_packages_info
|
||||||
|
target
|
||||||
|
package_components_ids
|
||||||
|
out_packages_info)
|
||||||
|
|
||||||
|
# There might be multiple calls to find the same package, so remove the duplicates.
|
||||||
|
list(REMOVE_DUPLICATES package_components_ids)
|
||||||
|
|
||||||
|
set(packages_info "")
|
||||||
|
|
||||||
|
foreach(package_key IN LISTS package_components_ids)
|
||||||
|
get_cmake_property(provided_targets _qt_find_package_${package_key}_provided_targets)
|
||||||
|
if(provided_targets)
|
||||||
|
set(key "__qt_${target}_third_party_package_${package_key}_provided_targets")
|
||||||
|
|
||||||
|
# Escape the semicolon, so it is preserved in the list(JOIN) below
|
||||||
|
string(REPLACE ";" "\;" provided_targets "${provided_targets}")
|
||||||
|
string(APPEND packages_info "set(${key} \"${provided_targets}\")\n")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(${out_packages_info} "${packages_info}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Filter the dependency targets to collect unique set of the dependencies.
|
# 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
|
# 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
|
# since they are defined by the same CMake package. For internal modules
|
||||||
@ -149,6 +190,7 @@ function(qt_internal_create_module_depends_file target)
|
|||||||
# ModuleDependencies.cmake.
|
# ModuleDependencies.cmake.
|
||||||
set(third_party_deps "")
|
set(third_party_deps "")
|
||||||
set(third_party_deps_seen "")
|
set(third_party_deps_seen "")
|
||||||
|
set(third_party_deps_package_components_ids "")
|
||||||
|
|
||||||
# Used for collecting Qt tool dependencies that should be find_package()'d in
|
# Used for collecting Qt tool dependencies that should be find_package()'d in
|
||||||
# ModuleToolsDependencies.cmake.
|
# ModuleToolsDependencies.cmake.
|
||||||
@ -216,6 +258,14 @@ function(qt_internal_create_module_depends_file target)
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
qt_collect_third_party_deps(${target})
|
qt_collect_third_party_deps(${target})
|
||||||
|
qt_internal_collect_third_party_dep_packages_info(${target}
|
||||||
|
"${third_party_deps_package_components_ids}"
|
||||||
|
packages_info)
|
||||||
|
|
||||||
|
set(third_party_deps_extra_info "")
|
||||||
|
if(packages_info)
|
||||||
|
string(APPEND third_party_deps_extra_info "${packages_info}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add dependency to the main ModuleTool package to ModuleDependencies file.
|
# Add dependency to the main ModuleTool package to ModuleDependencies file.
|
||||||
if(${target} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS)
|
if(${target} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS)
|
||||||
|
@ -4,3 +4,52 @@
|
|||||||
function(qt_internal_disable_find_package_global_promotion target)
|
function(qt_internal_disable_find_package_global_promotion target)
|
||||||
set_target_properties("${target}" PROPERTIES _qt_no_promote_global TRUE)
|
set_target_properties("${target}" PROPERTIES _qt_no_promote_global TRUE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# Transforms a list of package components into a string, so it can serve as a valid infix
|
||||||
|
# in a property name.
|
||||||
|
function(_qt_internal_get_package_components_as_valid_key_infix value out_var)
|
||||||
|
string(REPLACE ";" "_" valid_value "${value}")
|
||||||
|
set(${out_var} "${valid_value}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# This function computes a unique key / id using the package name and the components that are
|
||||||
|
# passed.
|
||||||
|
# The result is later used as property name, to store provided targets for a specific
|
||||||
|
# package + components combination.
|
||||||
|
function(_qt_internal_get_package_components_id)
|
||||||
|
set(opt_args "")
|
||||||
|
set(single_args
|
||||||
|
PACKAGE_NAME
|
||||||
|
OUT_VAR_KEY
|
||||||
|
)
|
||||||
|
set(multi_args
|
||||||
|
COMPONENTS
|
||||||
|
OPTIONAL_COMPONENTS
|
||||||
|
)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||||
|
_qt_internal_validate_all_args_are_parsed(arg)
|
||||||
|
|
||||||
|
if(NOT arg_PACKAGE_NAME)
|
||||||
|
message(FATAL_ERROR "PACKAGE_NAME is required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT arg_OUT_VAR_KEY)
|
||||||
|
message(FATAL_ERROR "OUT_VAR_KEY is required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(key "${arg_PACKAGE_NAME}")
|
||||||
|
|
||||||
|
if(arg_COMPONENTS)
|
||||||
|
_qt_internal_get_package_components_as_valid_key_infix("${arg_COMPONENTS}"
|
||||||
|
components_as_string)
|
||||||
|
string(APPEND key "-${components_as_string}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(arg_OPTIONAL_COMPONENTS)
|
||||||
|
_qt_internal_get_package_components_as_valid_key_infix("${arg_OPTIONAL_COMPONENTS}"
|
||||||
|
components_as_string)
|
||||||
|
string(APPEND key "-${components_as_string}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${arg_OUT_VAR_KEY} "${key}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user