CMake: Support manual multiple projects within-a-repo SBOM generation
Certain repositories like qtwebengine contain multiple projects from the perspective of online installer packaging. In this case the QtWebEngine and QtPdf projects are expected to have separate SBOM documents. Introduce a new QT_SKIP_SBOM_AUTO_PROJECT variable that can be set before qt_build_repo to disable the auto-generation of an SBOM document for the current repo project. Introduce two new internal functions qt_internal_sbom_begin/end_qt_repo_project to allow to manually start and end the SBOM generation for a project within a repo. Because the intermediate file names that assemble the SBOM use the project name as a key, and the project name would be the same for qtwebengine, allow differentiating between the current project name and the real qt repo project name. The current project name is used for the file names, whereas the real qt repo project name is used to extract the dependencies on other repos, to ensure correct dependency build rules. As a drive-by, improve the document dir path search list when an SBOM document can't be found. Pick-to: 6.8 Task-number: QTBUG-128893 Task-number: QTBUG-122899 Change-Id: I61b68098242e7c49b98420265c29af78303c3233 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
ffef516884
commit
43e166bd08
@ -352,10 +352,7 @@ macro(qt_build_repo_begin)
|
||||
set_property(GLOBAL PROPERTY _qt_synced_modules ${QT_INTERNAL_SYNCED_MODULES})
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_begin_project(
|
||||
INSTALL_SBOM_DIR "${INSTALL_SBOMDIR}"
|
||||
QT_CPE
|
||||
)
|
||||
_qt_internal_sbom_auto_begin_qt_repo_project()
|
||||
endmacro()
|
||||
|
||||
# Runs delayed actions on some of the Qt targets.
|
||||
@ -419,7 +416,7 @@ macro(qt_build_repo_end)
|
||||
set(QT_INTERNAL_FRESH_REQUESTED "FALSE" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_end_project()
|
||||
_qt_internal_sbom_auto_end_qt_repo_project()
|
||||
|
||||
if(NOT QT_SUPERBUILD)
|
||||
qt_internal_qt_configure_end()
|
||||
|
@ -18,9 +18,25 @@ function(qt_internal_sbom_set_default_option_value_and_error_if_empty option_nam
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper that returns the relative sbom build dir.
|
||||
# To accommodate multiple projects within a qt repo (like qtwebengine), we need to choose separate
|
||||
# build dirs for each project.
|
||||
function(_qt_internal_get_current_project_sbom_relative_dir out_var)
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
_qt_internal_sbom_get_qt_repo_project_name_lower_case(real_qt_repo_project_name_lowercase)
|
||||
|
||||
if(repo_project_name_lowercase STREQUAL real_qt_repo_project_name_lowercase)
|
||||
set(sbom_dir "qt_sbom")
|
||||
else()
|
||||
set(sbom_dir "qt_sbom/${repo_project_name_lowercase}")
|
||||
endif()
|
||||
set(${out_var} "${sbom_dir}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper that returns the directory where the intermediate sbom files will be generated.
|
||||
function(_qt_internal_get_current_project_sbom_dir out_var)
|
||||
set(sbom_dir "${PROJECT_BINARY_DIR}/qt_sbom")
|
||||
_qt_internal_get_current_project_sbom_relative_dir(relative_dir)
|
||||
set(sbom_dir "${PROJECT_BINARY_DIR}/${relative_dir}")
|
||||
set(${out_var} "${sbom_dir}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@ -414,6 +430,7 @@ function(_qt_internal_sbom_end_project_generate)
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
_qt_internal_sbom_get_qt_repo_project_name_lower_case(real_qt_repo_project_name_lowercase)
|
||||
|
||||
# Create a build target to create a build-time sbom (no verification codes or sha1s).
|
||||
set(repo_sbom_target "sbom_${repo_project_name_lowercase}")
|
||||
@ -427,7 +444,7 @@ function(_qt_internal_sbom_end_project_generate)
|
||||
USES_TERMINAL # To avoid running two configs of the command in parallel
|
||||
)
|
||||
|
||||
get_cmake_property(qt_repo_deps _qt_repo_deps_${repo_project_name_lowercase})
|
||||
get_cmake_property(qt_repo_deps _qt_repo_deps_${real_qt_repo_project_name_lowercase})
|
||||
if(qt_repo_deps)
|
||||
foreach(repo_dep IN LISTS qt_repo_deps)
|
||||
set(repo_dep_sbom "sbom_${repo_dep}")
|
||||
@ -767,6 +784,7 @@ function(_qt_internal_sbom_generate_add_external_reference)
|
||||
set(content "
|
||||
set(relative_file_name \"${arg_FILENAME}\")
|
||||
set(document_dir_paths ${install_prefixes})
|
||||
list(JOIN document_dir_paths \"\\n\" document_dir_paths_per_line)
|
||||
foreach(document_dir_path IN LISTS document_dir_paths)
|
||||
set(document_file_path \"\${document_dir_path}/\${relative_file_name}\")
|
||||
if(EXISTS \"\${document_file_path}\")
|
||||
@ -775,7 +793,7 @@ function(_qt_internal_sbom_generate_add_external_reference)
|
||||
endforeach()
|
||||
if(NOT EXISTS \"\${document_file_path}\")
|
||||
message(FATAL_ERROR \"Could not find external SBOM document \${relative_file_name}\"
|
||||
\" in any of the document dir paths: \${document_dir_paths} \"
|
||||
\" in any of the document dir paths: \${document_dir_paths_per_line} \"
|
||||
)
|
||||
endif()
|
||||
file(SHA1 \"\${document_file_path}\" ext_sha1)
|
||||
|
@ -38,6 +38,7 @@ function(_qt_internal_sbom_begin_project)
|
||||
DOCUMENT_NAMESPACE
|
||||
VERSION
|
||||
SBOM_PROJECT_NAME
|
||||
QT_REPO_PROJECT_NAME
|
||||
CPE
|
||||
)
|
||||
set(multi_args
|
||||
@ -69,6 +70,13 @@ function(_qt_internal_sbom_begin_project)
|
||||
else()
|
||||
_qt_internal_sbom_set_root_project_name("${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
if(arg_QT_REPO_PROJECT_NAME)
|
||||
_qt_internal_sbom_set_qt_repo_project_name("${arg_QT_REPO_PROJECT_NAME}")
|
||||
else()
|
||||
_qt_internal_sbom_set_qt_repo_project_name("${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_get_root_project_name_for_spdx_id(repo_project_name_for_spdx_id)
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
|
||||
@ -376,6 +384,75 @@ function(_qt_internal_sbom_end_project)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${attribution_files}")
|
||||
endfunction()
|
||||
|
||||
# Automatically begins sbom generation for a qt git repo unless QT_SKIP_SBOM_AUTO_PROJECT is TRUE.
|
||||
function(_qt_internal_sbom_auto_begin_qt_repo_project)
|
||||
# Allow skipping auto generation of sbom project, in case it needs to be manually adjusted with
|
||||
# extra parameters.
|
||||
if(QT_SKIP_SBOM_AUTO_PROJECT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_begin_qt_repo_project()
|
||||
endfunction()
|
||||
|
||||
# Sets up sbom generation for a qt git repo or qt-git-repo-sub-project (e.g. qtpdf in qtwebengine).
|
||||
#
|
||||
# In the case of a qt-git-repo-sub-project, the function expects the following options:
|
||||
# - SBOM_PROJECT_NAME (e.g. QtPdf)
|
||||
# - QT_REPO_PROJECT_NAME (e.g. QtWebEngine)
|
||||
#
|
||||
# Expects the following variables to always be set before the function call:
|
||||
# - QT_STAGING_PREFIX
|
||||
# - INSTALL_SBOMDIR
|
||||
function(_qt_internal_sbom_begin_qt_repo_project)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
SBOM_PROJECT_NAME
|
||||
QT_REPO_PROJECT_NAME
|
||||
)
|
||||
set(multi_args "")
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(sbom_project_args "")
|
||||
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR sbom_project_args
|
||||
FORWARD_OPTIONS
|
||||
${opt_args}
|
||||
FORWARD_SINGLE
|
||||
${single_args}
|
||||
FORWARD_MULTI
|
||||
${multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_sbom_begin_project(
|
||||
INSTALL_SBOM_DIR "${INSTALL_SBOMDIR}"
|
||||
QT_CPE
|
||||
${sbom_project_args}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Automatically ends sbom generation for a qt git repo unless QT_SKIP_SBOM_AUTO_PROJECT is TRUE.
|
||||
function(_qt_internal_sbom_auto_end_qt_repo_project)
|
||||
# Allow skipping auto generation of sbom project, in case it needs to be manually adjusted with
|
||||
# extra parameters.
|
||||
if(QT_SKIP_SBOM_AUTO_PROJECT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_end_qt_repo_project()
|
||||
endfunction()
|
||||
|
||||
# Endssbom generation for a qt git repo or qt-git-repo-sub-project.
|
||||
|
||||
function(_qt_internal_sbom_end_qt_repo_project)
|
||||
_qt_internal_sbom_end_project()
|
||||
endfunction()
|
||||
|
||||
# Helper to get purl parsing options.
|
||||
macro(_qt_internal_get_sbom_purl_parsing_options opt_args single_args multi_args)
|
||||
set(${opt_args}
|
||||
@ -2608,11 +2685,17 @@ macro(_qt_internal_sbom_get_attribution_key json_key out_var out_prefix)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Set sbom project name for the root project.
|
||||
# Sets the sbom project name for the root project.
|
||||
function(_qt_internal_sbom_set_root_project_name project_name)
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_repo_project_name "${project_name}")
|
||||
endfunction()
|
||||
|
||||
# Sets the real qt repo project name for a given project (e.g. set QtWebEngine for project QtPdf).
|
||||
# This is needed to be able to extract the qt repo dependencies in a top-level build.
|
||||
function(_qt_internal_sbom_set_qt_repo_project_name project_name)
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_qt_repo_project_name "${project_name}")
|
||||
endfunction()
|
||||
|
||||
# Get repo project_name spdx id reference, needs to start with Package- to be NTIA compliant.
|
||||
function(_qt_internal_sbom_get_root_project_name_for_spdx_id out_var)
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
@ -2620,7 +2703,7 @@ function(_qt_internal_sbom_get_root_project_name_for_spdx_id out_var)
|
||||
set(${out_var} "${sbom_repo_project_name}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Just a lower case sbom project name.
|
||||
# Returns the lower case sbom project name.
|
||||
function(_qt_internal_sbom_get_root_project_name_lower_case out_var)
|
||||
get_cmake_property(project_name _qt_internal_sbom_repo_project_name)
|
||||
|
||||
@ -2632,6 +2715,19 @@ function(_qt_internal_sbom_get_root_project_name_lower_case out_var)
|
||||
set(${out_var} "${repo_project_name_lowercase}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Returns the lower case real qt repo project name (e.g. returns 'qtwebengine' when building the
|
||||
# project qtpdf).
|
||||
function(_qt_internal_sbom_get_qt_repo_project_name_lower_case out_var)
|
||||
get_cmake_property(project_name _qt_internal_sbom_qt_repo_project_name)
|
||||
|
||||
if(NOT project_name)
|
||||
message(FATAL_ERROR "No real Qt repo SBOM project name was set.")
|
||||
endif()
|
||||
|
||||
string(TOLOWER "${project_name}" repo_project_name_lowercase)
|
||||
set(${out_var} "${repo_project_name_lowercase}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Get a spdx id to reference an external document.
|
||||
function(_qt_internal_sbom_get_external_document_ref_spdx_id repo_name out_var)
|
||||
set(${out_var} "DocumentRef-${repo_name}" PARENT_SCOPE)
|
||||
|
@ -22,3 +22,12 @@ endfunction()
|
||||
function(qt_find_package_extend_sbom)
|
||||
_qt_find_package_extend_sbom(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_begin_qt_repo_project)
|
||||
_qt_internal_sbom_begin_qt_repo_project(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_end_qt_repo_project)
|
||||
_qt_internal_sbom_end_qt_repo_project(${ARGN})
|
||||
endfunction()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user