CMake: Rework SBOM PURL handling
Previously, only 3 purl entries could be added to a target, which tightly coupled to Qt's needs: a QT one pointing to code.qt.io, a MIRROR one pointing to github, and an upstream one pointing to some upstream third party location. Rework the implementation to allow for an unlimited number of PURL entries and to allow more flexibility when adding PURLs in a user project. The new syntax for adding PURLs to a target, which is also the basis for a future public API is as follows: qt_internal_add_sbom(<target> PURLS [[PURL_ENTRY PURL_ID <id> PURL_TYPE <type> PURL_NAMESPACE <namespace> PURL_NAME <name> PURL_VERSION <version>]...] PURL_VALUES [purl-string...] ) The PURLS keyword is used to specify multiple PURL entries, each starting with the PURL_ENTRY keyword. The PURL_VALUES keyword is used to specify a list of pre-built purl strings. PURL_ID is an optional argument used to identify a specific purl entry, which is mostly needed for Qt's needs, to post-process them further. The rest of the options are pre-existing from the previous implementation. Implementation-wise, there's a new custom parser to be able to parse and validate PURL_ENTRY arguments. The VERSION option was renamed to PACKAGE_VERSION, to avoid some issues in cmake_parse_arguments parsing with nested VERSION options. The NO_PURL option was removed because it makes no sense in the new implementation, because if you specify some PURL arguments, there is already an intention to generate a PURL entry. Qt entities no longer have a restriction on which specific purl ids they can have. The new Qt specific purl IDs have been renamed: - QT -> GENERIC - MIRROR -> GITHUB Amends f7e1123620b623be0c321b54eaba7a1d618a7ce1 Pick-to: 6.8 6.9 Task-number: QTBUG-122899 Change-Id: I050decece1c6d9e6e0e06547043f864d6f497ea7 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
fd622bc3ae
commit
a28a9e194c
@ -478,14 +478,14 @@ function(_qt_internal_sbom_setup_fake_deterministic_build)
|
||||
set(QT_SBOM_FAKE_CHECKSUM "${value}" CACHE BOOL "SBOM fake checksums")
|
||||
endfunction()
|
||||
|
||||
# Helper to get purl parsing options.
|
||||
# Helper to get purl entry-specific options.
|
||||
macro(_qt_internal_get_sbom_purl_parsing_options opt_args single_args multi_args)
|
||||
set(${opt_args}
|
||||
NO_PURL
|
||||
NO_DEFAULT_QT_PURL
|
||||
PURL_USE_PACKAGE_VERSION
|
||||
)
|
||||
set(${single_args}
|
||||
PURL_ID
|
||||
PURL_TYPE
|
||||
PURL_NAMESPACE
|
||||
PURL_NAME
|
||||
@ -498,7 +498,7 @@ macro(_qt_internal_get_sbom_purl_parsing_options opt_args single_args multi_args
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Helper to get the purl variant option names that should be recongized by sbom functions like
|
||||
# Helper to get the purl options that should be recongized by sbom functions like
|
||||
# _qt_internal_sbom_add_target.
|
||||
macro(_qt_internal_get_sbom_purl_add_target_options opt_args single_args multi_args)
|
||||
set(${opt_args}
|
||||
@ -506,25 +506,19 @@ macro(_qt_internal_get_sbom_purl_add_target_options opt_args single_args multi_a
|
||||
)
|
||||
set(${single_args} "")
|
||||
set(${multi_args}
|
||||
PURL_QT_ARGS
|
||||
PURL_3RDPARTY_UPSTREAM_ARGS
|
||||
PURL_MIRROR_ARGS
|
||||
PURL_QT_VALUES
|
||||
PURL_3RDPARTY_UPSTREAM_VALUES
|
||||
PURL_MIRROR_VALUES
|
||||
PURLS
|
||||
PURL_VALUES
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Helper to get purl options that should be forwarded from _qt_internal_sbom_add_target to
|
||||
# _qt_internal_sbom_handle_purl_values.
|
||||
macro(_qt_internal_get_sbom_purl_handling_options opt_args single_args multi_args)
|
||||
set(${opt_args}
|
||||
IS_QT_ENTITY_TYPE
|
||||
)
|
||||
set(${opt_args} "")
|
||||
set(${single_args}
|
||||
SUPPLIER
|
||||
TYPE
|
||||
VERSION
|
||||
PACKAGE_VERSION
|
||||
)
|
||||
set(${multi_args} "")
|
||||
|
||||
@ -947,11 +941,7 @@ function(_qt_internal_sbom_add_target target)
|
||||
endif()
|
||||
|
||||
if(package_version)
|
||||
list(APPEND purl_args VERSION "${package_version}")
|
||||
endif()
|
||||
|
||||
if(is_qt_entity_type)
|
||||
list(APPEND purl_args IS_QT_ENTITY_TYPE)
|
||||
list(APPEND purl_args PACKAGE_VERSION "${package_version}")
|
||||
endif()
|
||||
|
||||
if(arg_USE_ATTRIBUTION_FILES AND qa_purls)
|
||||
@ -965,7 +955,7 @@ function(_qt_internal_sbom_add_target target)
|
||||
OUT_VAR qa_purls_replaced
|
||||
)
|
||||
|
||||
list(APPEND purl_args PURL_3RDPARTY_UPSTREAM_VALUES "${qa_purls_replaced}")
|
||||
list(APPEND purl_args PURL_VALUES ${qa_purls_replaced})
|
||||
endif()
|
||||
list(APPEND purl_args OUT_VAR purl_package_options)
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Parse purl arguments for a specific purl variant, e.g. for parsing all values of arg_PURL_QT_ARGS.
|
||||
# Parse purl arguments for a specific purl entry.
|
||||
# arguments_var_name is the variable name that contains the args.
|
||||
macro(_qt_internal_sbom_parse_purl_variant_options prefix arguments_var_name)
|
||||
# prefix is the prefix passed to cmake_parse_arguments.
|
||||
macro(_qt_internal_sbom_parse_purl_entry_options prefix arguments_var_name)
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
|
||||
cmake_parse_arguments(arg "${purl_opt_args}" "${purl_single_args}" "${purl_multi_args}"
|
||||
cmake_parse_arguments(${prefix} "${purl_opt_args}" "${purl_single_args}" "${purl_multi_args}"
|
||||
${${arguments_var_name}})
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
_qt_internal_validate_all_args_are_parsed(${prefix})
|
||||
endmacro()
|
||||
|
||||
# Helper macro to prepare forwarding all set purl options to some other function.
|
||||
@ -40,25 +41,51 @@ macro(_qt_internal_sbom_forward_purl_handling_options args_var_name)
|
||||
endmacro()
|
||||
|
||||
# Handles purl arguments specified to functions like qt_internal_add_sbom.
|
||||
# Currently accepts arguments for 3 variants of purls, each of which will generate a separate purl.
|
||||
# If no arguments are specified, for qt entity types, default values will be chosen.
|
||||
#
|
||||
# Purl variants:
|
||||
# - PURL_QT_ARGS
|
||||
# args to override Qt's generic purl for Qt modules or patched 3rd party libs
|
||||
# defaults to something like pkg:generic/TheQtCompany/${repo_name}-${target}@SHA1
|
||||
# - PURL_MIRROR_ARGS
|
||||
# args to override Qt's mirror purl, which is hosted on github
|
||||
# defaults to something like pkg:github/qt/${repo_name}@SHA1
|
||||
# - PURL_3RDPARTY_UPSTREAM_ARGS
|
||||
# args to specify a purl pointing to an upstream repo, usually to github or another forge
|
||||
# no defaults, but could look like: pkg:github/harfbuzz/harfbuzz@v8.5.0
|
||||
# Example values for harfbuzz:
|
||||
# PURL_3RDPARTY_UPSTREAM_ARGS
|
||||
# PURL_TYPE "github"
|
||||
# PURL_NAMESPACE "harfbuzz"
|
||||
# PURL_NAME "harfbuzz"
|
||||
# PURL_VERSION "v8.5.0" # tag
|
||||
# Synopsis
|
||||
#
|
||||
# qt_internal_add_sbom(<target>
|
||||
# PURLS
|
||||
# [[PURL_ENTRY
|
||||
# PURL_ID <id>
|
||||
# PURL_TYPE <type>
|
||||
# PURL_NAMESPACE <namespace>
|
||||
# PURL_NAME <name>
|
||||
# PURL_VERSION <version>]...]
|
||||
# PURL_VALUES
|
||||
# [purl-string...]
|
||||
# )
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# qt_internal_add_sbom(<target>
|
||||
# PURLS
|
||||
# PURL_ENTRY
|
||||
# PURL_ID "UPSTREAM"
|
||||
# PURL_TYPE "github"
|
||||
# PURL_NAMESPACE "harfbuzz"
|
||||
# PURL_NAME "harfbuzz"
|
||||
# PURL_VERSION "v8.5.0"
|
||||
# PURL_ENTRY
|
||||
# PURL_ID "MIRROR"
|
||||
# PURL_TYPE "git"
|
||||
# PURL_NAMESPACE "harfbuzz"
|
||||
# PURL_NAME "harfbuzz"
|
||||
# PURL_QUALIFIERS "vcs_url=https://code.qt.io/qt/qtbase"
|
||||
# ....
|
||||
# PURL_VALUES
|
||||
# pkg:git/harfbuzz/harfbuzz@v8.5.0
|
||||
# pkg:github/harfbuzz/harfbuzz@v8.5.0
|
||||
# ....
|
||||
#
|
||||
#
|
||||
# PURLS accepts multiple purl entries, each starting with the PURL_ENTRY keyword.
|
||||
# PURL_VALUES takes a list of pre-built purl strings.
|
||||
#
|
||||
# If no arguments are specified, for qt entity types (e.g. libraries built as part of Qt repos),
|
||||
# default purls will be generated.
|
||||
#
|
||||
# There is no limit to the number of purls that can be added to a target.
|
||||
function(_qt_internal_sbom_handle_purl_values target)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
@ -70,129 +97,113 @@ function(_qt_internal_sbom_handle_purl_values target)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
# List of purl variants to process.
|
||||
set(purl_variants "")
|
||||
|
||||
_qt_internal_sbom_get_git_version_vars()
|
||||
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
|
||||
_qt_internal_sbom_forward_purl_handling_options(purl_handling_args)
|
||||
_qt_internal_sbom_handle_qt_entity_purl_variants(${purl_handling_args}
|
||||
OUT_VAR_VARIANTS qt_purl_variants
|
||||
OUT_VAR_IS_QT_PURL_ENTITY_TYPE is_qt_purl_entity_type
|
||||
)
|
||||
if(qt_purl_variants)
|
||||
list(APPEND purl_variants "${qt_purl_variants}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(known_purl_variants QT MIRROR 3RDPARTY_UPSTREAM)
|
||||
foreach(known_purl_variant IN LISTS known_purl_variants)
|
||||
if(arg_PURL_${known_purl_variant}_ARGS AND NOT known_purl_variant IN_LIST purl_variants)
|
||||
list(APPEND purl_variants ${known_purl_variant})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
|
||||
set(project_package_options "")
|
||||
|
||||
foreach(purl_variant IN LISTS purl_variants)
|
||||
# Collect each PURL_ENTRY args into a separate variable.
|
||||
set(purl_idx -1)
|
||||
set(purl_entry_indices "")
|
||||
foreach(purl_arg IN LISTS arg_PURLS)
|
||||
if(purl_arg STREQUAL "PURL_ENTRY")
|
||||
math(EXPR purl_idx "${purl_idx}+1")
|
||||
list(APPEND purl_entry_indices "${purl_idx}")
|
||||
elseif(purl_idx GREATER_EQUAL 0)
|
||||
list(APPEND purl_${purl_idx}_args "${purl_arg}")
|
||||
else()
|
||||
message(FATAL_ERROR "Missing PURL_ENTRY keyword.")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Validate the args for each collected entry.
|
||||
foreach(purl_idx IN LISTS purl_entry_indices)
|
||||
list(LENGTH purl_${purl_idx}_args num_args)
|
||||
if(num_args LESS 1)
|
||||
message(FATAL_ERROR "Empty PURL_ENTRY encountered.")
|
||||
endif()
|
||||
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
|
||||
endforeach()
|
||||
|
||||
# Append qt specific placeholder entries when handling Qt entities.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
|
||||
_qt_internal_sbom_forward_purl_handling_options(purl_handling_args)
|
||||
_qt_internal_sbom_handle_qt_entity_purl_entries(${purl_handling_args}
|
||||
OUT_VAR_IDS qt_purl_ids
|
||||
)
|
||||
if(qt_purl_ids)
|
||||
# Create purl placeholder indices for each qt purl id.
|
||||
foreach(qt_purl_id IN LISTS qt_purl_ids)
|
||||
math(EXPR purl_idx "${purl_idx}+1")
|
||||
list(APPEND purl_entry_indices "${purl_idx}")
|
||||
list(APPEND purl_${purl_idx}_args PURL_ID "${qt_purl_id}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(purl_idx IN LISTS purl_entry_indices)
|
||||
# Clear previous values.
|
||||
foreach(option_name IN LISTS purl_opt_args purl_single_args purl_multi_args)
|
||||
unset(arg_${option_name})
|
||||
endforeach()
|
||||
|
||||
_qt_internal_sbom_parse_purl_variant_options(arg arg_PURL_${purl_variant}_ARGS)
|
||||
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
|
||||
|
||||
# Check if custom purl args were specified.
|
||||
set(purl_args_available FALSE)
|
||||
if(arg_PURL_${purl_variant}_ARGS)
|
||||
set(purl_args_available TRUE)
|
||||
set(purl_args "")
|
||||
|
||||
# Override the purl version with the package version.
|
||||
if(arg_PURL_USE_PACKAGE_VERSION AND arg_PACKAGE_VERSION)
|
||||
set(arg_PURL_VERSION "${arg_PACKAGE_VERSION}")
|
||||
endif()
|
||||
|
||||
# We want to create a purl either if it's one of Qt's entities and one of it's default
|
||||
# purl types, or if custom args were specified.
|
||||
set(consider_purl_processing FALSE)
|
||||
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL AND is_qt_purl_entity_type)
|
||||
set(purl_args_available TRUE)
|
||||
# Append a vcs_url to the qualifiers if specified.
|
||||
if(arg_PURL_VCS_URL)
|
||||
list(APPEND arg_PURL_QUALIFIERS "vcs_url=${arg_PURL_VCS_URL}")
|
||||
endif()
|
||||
|
||||
if(purl_args_available AND NOT arg_NO_PURL)
|
||||
set(consider_purl_processing TRUE)
|
||||
endif()
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR purl_args
|
||||
FORWARD_OPTIONS
|
||||
${purl_opt_args}
|
||||
FORWARD_SINGLE
|
||||
${purl_single_args}
|
||||
FORWARD_MULTI
|
||||
${purl_multi_args}
|
||||
)
|
||||
|
||||
if(consider_purl_processing)
|
||||
set(purl_args "")
|
||||
# Qt entity types get special treatment to gather the required args.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
|
||||
AND arg_PURL_ID
|
||||
AND arg_PURL_ID IN_LIST qt_purl_ids)
|
||||
|
||||
# Override the purl version with the package version.
|
||||
if(arg_PURL_USE_PACKAGE_VERSION AND arg_VERSION)
|
||||
set(arg_PURL_VERSION "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
# Append a vcs_url to the qualifiers if specified.
|
||||
if(arg_PURL_VCS_URL)
|
||||
list(APPEND arg_PURL_QUALIFIERS "vcs_url=${arg_PURL_VCS_URL}")
|
||||
endif()
|
||||
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR purl_args
|
||||
FORWARD_OPTIONS
|
||||
${purl_opt_args}
|
||||
FORWARD_SINGLE
|
||||
${purl_single_args}
|
||||
FORWARD_MULTI
|
||||
${purl_multi_args}
|
||||
_qt_internal_sbom_handle_qt_entity_purl("${target}"
|
||||
${purl_handling_args}
|
||||
PURL_ID "${arg_PURL_ID}"
|
||||
OUT_PURL_ARGS qt_purl_args
|
||||
)
|
||||
|
||||
# Qt entity types get special treatment purl.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
|
||||
_qt_internal_sbom_forward_purl_handling_options(purl_handling_args)
|
||||
if(is_qt_purl_entity_type)
|
||||
list(APPEND purl_handling_args IS_QT_PURL_ENTITY_TYPE)
|
||||
endif()
|
||||
_qt_internal_sbom_handle_qt_entity_purl("${target}" ${purl_handling_args}
|
||||
PURL_VARIANT "${purl_variant}"
|
||||
OUT_PURL_ARGS qt_purl_args
|
||||
)
|
||||
if(qt_purl_args)
|
||||
list(APPEND purl_args "${qt_purl_args}")
|
||||
endif()
|
||||
if(qt_purl_args)
|
||||
list(APPEND purl_args "${qt_purl_args}")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_assemble_purl(${target}
|
||||
${purl_args}
|
||||
OUT_VAR package_manager_external_ref
|
||||
)
|
||||
list(APPEND project_package_options ${package_manager_external_ref})
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_assemble_purl(${target}
|
||||
${purl_args}
|
||||
OUT_VAR package_manager_external_ref
|
||||
)
|
||||
list(APPEND project_package_options ${package_manager_external_ref})
|
||||
endforeach()
|
||||
|
||||
set(direct_values
|
||||
PURL_QT_VALUES
|
||||
PURL_MIRROR_VALUES
|
||||
PURL_3RDPARTY_UPSTREAM_VALUES
|
||||
)
|
||||
foreach(purl_value IN LISTS arg_PURL_VALUES)
|
||||
_qt_internal_sbom_get_purl_value_extref(
|
||||
VALUE "${purl_value}" OUT_VAR package_manager_external_ref)
|
||||
|
||||
foreach(direct_value IN LISTS direct_values)
|
||||
if(arg_${direct_value})
|
||||
set(direct_values_per_type "")
|
||||
foreach(direct_value IN LISTS arg_${direct_value})
|
||||
_qt_internal_sbom_get_purl_value_extref(
|
||||
VALUE "${direct_value}" OUT_VAR package_manager_external_ref)
|
||||
|
||||
list(APPEND direct_values_per_type ${package_manager_external_ref})
|
||||
endforeach()
|
||||
# The order in which the purls are generated, matters for tools that consume the SBOM.
|
||||
# Some tools can only handle one PURL per package, so the first one should be the
|
||||
# important one.
|
||||
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
|
||||
# file) are the more important ones. So we prepend them.
|
||||
list(PREPEND project_package_options ${direct_values_per_type})
|
||||
endif()
|
||||
# The order in which the purls are generated, matters for tools that consume the SBOM.
|
||||
# Some tools can only handle one PURL per package, so the first one should be the
|
||||
# important one.
|
||||
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
|
||||
# file) are the more important ones. So we prepend them.
|
||||
list(PREPEND project_package_options ${package_manager_external_ref})
|
||||
endforeach()
|
||||
|
||||
set(${arg_OUT_VAR} "${project_package_options}" PARENT_SCOPE)
|
||||
|
@ -203,7 +203,7 @@ function(_qt_internal_sbom_handle_qt_entity_cpe target)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Returns a vcs url where for purls where qt entities of the current repo are hosted.
|
||||
# Returns a vcs url for purls where qt entities of the current repo are hosted.
|
||||
function(_qt_internal_sbom_get_qt_entity_vcs_url target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
@ -267,7 +267,6 @@ function(_qt_internal_sbom_get_qt_entity_purl_args target)
|
||||
REPO_NAME
|
||||
SUPPLIER
|
||||
VERSION
|
||||
PURL_VARIANT
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
@ -280,21 +279,18 @@ function(_qt_internal_sbom_get_qt_entity_purl_args target)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(supported_purl_variants QT MIRROR)
|
||||
if(NOT arg_PURL_VARIANT IN_LIST supported_purl_variants)
|
||||
message(FATAL_ERROR "PURL_VARIANT unknown: ${arg_PURL_VARIANT}")
|
||||
if(arg_VERSION)
|
||||
set(purl_version "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_VARIANT STREQUAL "QT")
|
||||
if(arg_PURL_ID STREQUAL "GENERIC")
|
||||
set(purl_type "generic")
|
||||
set(purl_namespace "${arg_SUPPLIER}")
|
||||
set(purl_name "${arg_NAME}")
|
||||
set(purl_version "${arg_VERSION}")
|
||||
elseif(arg_PURL_VARIANT STREQUAL "MIRROR")
|
||||
elseif(arg_PURL_ID STREQUAL "GITHUB")
|
||||
set(purl_type "github")
|
||||
set(purl_namespace "qt")
|
||||
set(purl_name "${arg_REPO_NAME}")
|
||||
set(purl_version "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_TYPE)
|
||||
@ -336,12 +332,27 @@ function(_qt_internal_sbom_get_qt_entity_purl_args target)
|
||||
set(${arg_OUT_VAR} "${purl_args}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper function to decide which purl variants to add for a qt entity.
|
||||
function(_qt_internal_sbom_handle_qt_entity_purl_variants)
|
||||
# Helper to get the list of default purl ids for a qt entity.
|
||||
#
|
||||
# Qt entities have two purls by default:
|
||||
# - a GITHUB one pointing to the qt github mirror
|
||||
# - a GENERIC one pointing to code.qt.io via vcs_url
|
||||
#
|
||||
# Third party libraries vendored in Qt also have the same purls, like regular Qt
|
||||
# libraries, but might also have an upstream one which is specified explicitly.
|
||||
function(_qt_internal_sbom_get_qt_entity_default_purl_ids out_var)
|
||||
set(supported_purl_ids GITHUB GENERIC)
|
||||
set(${out_var} "${supported_purl_ids}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper function to decide which purl ids to add for a qt entity.
|
||||
# Returns either a list of qt purl ids, or an empty list if it's not a qt entity type or qt 3rd
|
||||
# party type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_purl_entries)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args
|
||||
OUT_VAR # This is unused, but added by the calling function.
|
||||
OUT_VAR_VARIANTS OUT_VAR_IS_QT_PURL_ENTITY_TYPE
|
||||
OUT_VAR_IDS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
@ -351,100 +362,85 @@ function(_qt_internal_sbom_handle_qt_entity_purl_variants)
|
||||
QT_THIRD_PARTY_SOURCES
|
||||
)
|
||||
|
||||
set(purl_variants "")
|
||||
set(purl_ids "")
|
||||
|
||||
if(arg_IS_QT_ENTITY_TYPE)
|
||||
# Qt entities have two purls by default, a QT generic one and a MIRROR hosted on github.
|
||||
list(APPEND purl_variants MIRROR QT)
|
||||
elseif(arg_TYPE IN_LIST third_party_types)
|
||||
# Third party libraries vendored in Qt also have at least two purls, like regular Qt
|
||||
# libraries, but might also have an upstream one.
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
|
||||
|
||||
# The order in which the purls are generated matters for tools that consume the SBOM. Some
|
||||
# tools can only handle one PURL per package, so the first one should be the important one.
|
||||
# For now, I deem that the upstream one if present. Otherwise the github mirror.
|
||||
if(arg_PURL_3RDPARTY_UPSTREAM_ARGS)
|
||||
list(APPEND purl_variants 3RDPARTY_UPSTREAM)
|
||||
endif()
|
||||
|
||||
list(APPEND purl_variants MIRROR QT)
|
||||
if(is_qt_entity_type OR is_qt_3rd_party_entity_type)
|
||||
_qt_internal_sbom_get_qt_entity_default_purl_ids(purl_ids)
|
||||
endif()
|
||||
|
||||
if(arg_IS_QT_ENTITY_TYPE
|
||||
OR arg_TYPE STREQUAL "QT_THIRD_PARTY_MODULE"
|
||||
OR arg_TYPE STREQUAL "QT_THIRD_PARTY_SOURCES")
|
||||
set(is_qt_purl_entity_type TRUE)
|
||||
else()
|
||||
set(is_qt_purl_entity_type FALSE)
|
||||
endif()
|
||||
|
||||
if(purl_variants)
|
||||
set(${arg_OUT_VAR_VARIANTS} "${purl_variants}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(is_qt_purl_entity_type)
|
||||
set(${arg_OUT_VAR_IS_QT_PURL_ENTITY_TYPE} "${is_qt_purl_entity_type}" PARENT_SCOPE)
|
||||
if(purl_ids)
|
||||
set(${arg_OUT_VAR_IDS} "${purl_ids}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add purl values for a specific purl variant of a qt entity type.
|
||||
# Helper function to add purl values for a specific purl entry of a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_purl target)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND opt_args IS_QT_PURL_ENTITY_TYPE)
|
||||
list(APPEND single_args
|
||||
OUT_VAR # This is unused, but added by the calling function.
|
||||
OUT_PURL_ARGS
|
||||
PURL_VARIANT
|
||||
PURL_ID
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(purl_args "")
|
||||
|
||||
# Qt entity types get special treatment purl.
|
||||
if(arg_IS_QT_PURL_ENTITY_TYPE AND NOT arg_NO_DEFAULT_QT_PURL AND
|
||||
(arg_PURL_VARIANT STREQUAL "QT" OR arg_PURL_VARIANT STREQUAL "MIRROR"))
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
_qt_internal_sbom_get_git_version_vars()
|
||||
|
||||
# Add a vcs_url to the generic QT variant.
|
||||
if(arg_PURL_VARIANT STREQUAL "QT")
|
||||
set(entity_vcs_url_version_option "")
|
||||
# Can be empty.
|
||||
if(QT_SBOM_GIT_HASH_SHORT)
|
||||
set(entity_vcs_url_version_option VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
endif()
|
||||
# Return early if not handling one of the default qt purl ids, or if requested not to add a
|
||||
# default purl.
|
||||
_qt_internal_sbom_get_qt_entity_default_purl_ids(default_purl_ids)
|
||||
|
||||
_qt_internal_sbom_get_qt_entity_vcs_url(${target}
|
||||
REPO_NAME "${repo_project_name_lowercase}"
|
||||
${entity_vcs_url_version_option}
|
||||
OUT_VAR vcs_url)
|
||||
list(APPEND purl_args PURL_QUALIFIERS "vcs_url=${vcs_url}")
|
||||
endif()
|
||||
if(arg_NO_DEFAULT_QT_PURL OR (NOT arg_PURL_ID IN_LIST default_purl_ids))
|
||||
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Add the subdirectory path where the target was created as a custom qualifier.
|
||||
_qt_internal_sbom_get_qt_entity_repo_source_dir(${target} OUT_VAR sub_path)
|
||||
if(sub_path)
|
||||
list(APPEND purl_args PURL_SUBPATH "${sub_path}")
|
||||
endif()
|
||||
|
||||
# Add the target name as a custom qualifer.
|
||||
list(APPEND purl_args PURL_QUALIFIERS "library_name=${target}")
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
|
||||
# Add a vcs_url to the GENERIC purl entry.
|
||||
if(arg_PURL_ID STREQUAL "GENERIC")
|
||||
set(entity_vcs_url_version_option "")
|
||||
# Can be empty.
|
||||
if(QT_SBOM_GIT_HASH_SHORT)
|
||||
list(APPEND purl_args VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
set(entity_vcs_url_version_option VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
endif()
|
||||
|
||||
# Get purl args the Qt entity type, taking into account defaults.
|
||||
_qt_internal_sbom_get_qt_entity_purl_args(${target}
|
||||
NAME "${repo_project_name_lowercase}-${target}"
|
||||
_qt_internal_sbom_get_qt_entity_vcs_url(${target}
|
||||
REPO_NAME "${repo_project_name_lowercase}"
|
||||
SUPPLIER "${arg_SUPPLIER}"
|
||||
PURL_VARIANT "${arg_PURL_VARIANT}"
|
||||
${purl_args}
|
||||
OUT_VAR purl_args
|
||||
)
|
||||
${entity_vcs_url_version_option}
|
||||
OUT_VAR vcs_url)
|
||||
list(APPEND purl_args PURL_QUALIFIERS "vcs_url=${vcs_url}")
|
||||
endif()
|
||||
|
||||
# Add the subdirectory path where the target was created as a custom qualifier.
|
||||
_qt_internal_sbom_get_qt_entity_repo_source_dir(${target} OUT_VAR sub_path)
|
||||
if(sub_path)
|
||||
list(APPEND purl_args PURL_SUBPATH "${sub_path}")
|
||||
endif()
|
||||
|
||||
# Add the target name as a custom qualifer.
|
||||
list(APPEND purl_args PURL_QUALIFIERS "library_name=${target}")
|
||||
|
||||
# Can be empty.
|
||||
if(QT_SBOM_GIT_HASH_SHORT)
|
||||
list(APPEND purl_args VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
endif()
|
||||
|
||||
# Get purl args the Qt entity type, taking into account defaults.
|
||||
_qt_internal_sbom_get_qt_entity_purl_args(${target}
|
||||
NAME "${repo_project_name_lowercase}-${target}"
|
||||
REPO_NAME "${repo_project_name_lowercase}"
|
||||
SUPPLIER "${arg_SUPPLIER}"
|
||||
PURL_ID "${arg_PURL_ID}"
|
||||
${purl_args}
|
||||
OUT_VAR purl_args
|
||||
)
|
||||
|
||||
if(purl_args)
|
||||
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
Loading…
x
Reference in New Issue
Block a user