From 31126b2b775ae52a0d74aadf1aff8f6d79d0c6be Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 20 Jun 2024 19:21:53 +0200 Subject: [PATCH] CMake: Make ninja 'sbom' work for top-level builds We need to pass all dirs where sboms will be generated, for external document referencing. We also need to set up dependencies between the repo sbom custom targets, so that qtsvg sbom is only run after qtbase sbom. We use the dependencies.yaml info to set up the dependencies. Pick-to: 6.8 Task-number: QTBUG-122899 Change-Id: Id3331e11742bc2c86e7ed52ce26b3ff21eace359 Reviewed-by: Joerg Bornemann --- cmake/QtBuildRepoHelpers.cmake | 1 + cmake/QtPublicSbomGenerationHelpers.cmake | 24 ++++++++++++++++++++++- cmake/QtPublicSbomHelpers.cmake | 21 +++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/cmake/QtBuildRepoHelpers.cmake b/cmake/QtBuildRepoHelpers.cmake index d55e8559bcb..dafeb03b913 100644 --- a/cmake/QtBuildRepoHelpers.cmake +++ b/cmake/QtBuildRepoHelpers.cmake @@ -252,6 +252,7 @@ macro(qt_build_repo_begin) qt_internal_read_repo_dependencies(qt_repo_deps "${PROJECT_SOURCE_DIR}") if(qt_repo_deps) + set_property(GLOBAL PROPERTY _qt_repo_deps_${project_name_lower} ${qt_repo_deps}) foreach(qt_repo_dep IN LISTS qt_repo_deps) if(TARGET qt_plugins_${qt_repo_dep}) message(DEBUG diff --git a/cmake/QtPublicSbomGenerationHelpers.cmake b/cmake/QtPublicSbomGenerationHelpers.cmake index 587bcabad0c..81d704fe60b 100644 --- a/cmake/QtPublicSbomGenerationHelpers.cmake +++ b/cmake/QtPublicSbomGenerationHelpers.cmake @@ -93,6 +93,7 @@ function(_qt_internal_sbom_begin_project_generate) set(opt_args "") set(single_args OUTPUT + OUTPUT_RELATIVE_PATH LICENSE COPYRIGHT DOWNLOAD_LOCATION @@ -119,6 +120,8 @@ function(_qt_internal_sbom_begin_project_generate) "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/${default_sbom_file_name}") qt_internal_sbom_set_default_option_value(OUTPUT "${default_install_sbom_path}") + qt_internal_sbom_set_default_option_value(OUTPUT_RELATIVE_PATH + "${default_sbom_file_name}") qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION") qt_internal_sbom_set_default_option_value(PROJECT_FOR_SPDX "${PROJECT_NAME}") @@ -215,6 +218,7 @@ Relationship: SPDXRef-DOCUMENT DESCRIBES ${project_spdx_id} get_filename_component(computed_sbom_file_name "${arg_OUTPUT}" NAME_WLE) get_filename_component(computed_sbom_file_name_ext "${arg_OUTPUT}" LAST_EXT) + get_filename_component(computed_sbom_relative_dir "${arg_OUTPUT_RELATIVE_PATH}" DIRECTORY) get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG) if(is_multi_config) @@ -226,7 +230,14 @@ Relationship: SPDXRef-DOCUMENT DESCRIBES ${project_spdx_id} set(computed_sbom_file_name "${computed_sbom_file_name}${multi_config_suffix}${computed_sbom_file_name_ext}") - set(build_sbom_path "${sbom_dir}/${computed_sbom_file_name}") + # In a super build, put all the build time sboms into the same dir in qtbase. + if(QT_SUPERBUILD) + set(build_sbom_dir "${QtBase_BINARY_DIR}/qt_sbom") + else() + set(build_sbom_dir "${sbom_dir}") + endif() + set(build_sbom_path + "${build_sbom_dir}/${computed_sbom_relative_dir}/${computed_sbom_file_name}") # Create cmake file to append the document intro spdx to the staging file. set(create_staging_file "${sbom_dir}/append_document_to_staging${multi_config_suffix}.cmake") @@ -375,6 +386,17 @@ function(_qt_internal_sbom_end_project_generate) VERBATIM 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}) + if(qt_repo_deps) + foreach(repo_dep IN LISTS qt_repo_deps) + set(repo_dep_sbom "sbom_${repo_dep}") + if(TARGET "${repo_dep_sbom}") + add_dependencies(${repo_sbom_target} ${repo_dep_sbom}) + endif() + endforeach() + endif() + add_dependencies(sbom ${repo_sbom_target}) set(extra_code_begin "") diff --git a/cmake/QtPublicSbomHelpers.cmake b/cmake/QtPublicSbomHelpers.cmake index d5e85f7112d..8dfec929999 100644 --- a/cmake/QtPublicSbomHelpers.cmake +++ b/cmake/QtPublicSbomHelpers.cmake @@ -165,6 +165,7 @@ function(_qt_internal_sbom_begin_project) _qt_internal_sbom_begin_project_generate( OUTPUT "${repo_spdx_install_path}" + OUTPUT_RELATIVE_PATH "${repo_spdx_relative_install_path}" LICENSE "${repo_license}" COPYRIGHT "${repo_copyright}" SUPPLIER "${repo_supplier}" # This must not contain spaces! @@ -192,6 +193,9 @@ function(_qt_internal_sbom_begin_project) set_property(GLOBAL PROPERTY _qt_internal_sbom_project_spdx_id "${repo_project_spdx_id}") + _qt_internal_get_current_project_sbom_dir(sbom_dir) + set_property(GLOBAL APPEND PROPERTY _qt_internal_sbom_dirs "${sbom_dir}") + file(GLOB license_files "${PROJECT_SOURCE_DIR}/LICENSES/LicenseRef-*.txt") foreach(license_file IN LISTS license_files) get_filename_component(license_id "${license_file}" NAME_WLE) @@ -975,7 +979,22 @@ function(_qt_internal_sbom_add_external_target_dependency # Only add a reference to the external document package, if we haven't done so already. if(NOT known_external_document) + set(install_prefixes "") + get_cmake_property(install_prefix _qt_internal_sbom_install_prefix) + list(APPEND install_prefixes "${install_prefix}") + + # Add the current sbom build dirs as install prefixes, so that we can use ninja 'sbom' + # in top-level builds. This is needed because the external references will point + # to sbom docs in different build dirs, not just one. + if(QT_SUPERBUILD) + get_cmake_property(build_sbom_dirs _qt_internal_sbom_dirs) + if(build_sbom_dirs) + foreach(build_sbom_dir IN LISTS build_sbom_dirs) + list(APPEND install_prefixes "${build_sbom_dir}") + endforeach() + endif() + endif() set(external_document "${relative_installed_repo_document_path}") @@ -984,7 +1003,7 @@ function(_qt_internal_sbom_add_external_target_dependency EXTERNAL "${dep_spdx_id}" FILENAME "${external_document}" SPDXID "${external_document_ref}" - INSTALL_PREFIXES ${install_prefix} + INSTALL_PREFIXES ${install_prefixes} ) set_property(GLOBAL PROPERTY