CMake: Change SBOM generation to be enabled by default (mostly)

Previously SBOM generation was opt-in.

This patch changes the generation of the plain-text tag:value SBOM
to be enabled by default, except for:
- developer builds
- no-prefix builds
- standalone tests or examples
- cmake build tests

The JSON SBOM generation and the verification steps have also been
changed to be enabled by default, but only if the Python dependencies
can be found. If the dependencies are not found, the build will
skip the generation and verification steps.

Four new configure options have been added to control these aspects:
-(no-)sbom-json: Allows explicitly enabling or disabling JSON SBOM
  generation

-(no-)sbom-json-required: Fails the build if JSON SBOM generation
  Python dependencies are not found

-(no-)sbom-verify: Allows explicitly enabling or disabling SBOM
  verification

-(no-)sbom-verify-required: Fails the build if SBOM verification
  Python dependencies are not found

There are corresponding CMake variables for each of the configure
options, see the cmake mapping document.

[ChangeLog][Build Systems] SBOM generation is now enabled by default,
when building Qt, except for developer builds and no-prefix builds.
JSON SBOM generation is enabled by default if the required Python
dependencies are available.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I6dbe1869f8342154a89ff2ab84ac53c9ef1b2eb7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2024-10-14 17:05:23 +02:00
parent f15b3c864e
commit 96c5e55c11
7 changed files with 139 additions and 16 deletions

View File

@ -421,6 +421,8 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_setup_build_tools()
qt_internal_setup_sbom()
# Depends on qt_internal_setup_default_install_prefix
qt_internal_setup_build_examples()

View File

@ -300,6 +300,63 @@ macro(qt_internal_setup_build_tools)
unset(_qt_build_tools_by_default_default)
endmacro()
# A heuristic to determine that the currently processed project is a cmake build test project.
function(qt_internal_current_project_is_cmake_build_test_project out_var)
set(current_dir "${CMAKE_CURRENT_SOURCE_DIR}")
set(result FALSE)
if(current_dir MATCHES "tests/auto/cmake")
set(result TRUE)
endif()
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_compute_sbom_default out_var)
# Default to generating the SBOM, except for:
# - developer-builds
# - no-prefix builds.
# - standalone tests or examples
# - cmake build tests
# Regular developers of Qt (which would pass -developer-build) likely don't need SBOMs.
# -no-prefix builds don't make much sense for SBOMs because the installed file checksums
# will be missing, and thus the SBOMs will not be complete / valid.
# Honor any explicitly or previously set value.
qt_internal_current_project_is_cmake_build_test_project(is_cmake_build_test)
if(FEATURE_developer_build
OR QT_FEATURE_developer_build
OR FEATURE_no_prefix
OR QT_FEATURE_no_prefix
OR QT_BUILD_STANDALONE_EXAMPLES
OR QT_BUILD_STANDALONE_TESTS
OR QT_INTERNAL_BUILD_STANDALONE_PARTS
OR is_cmake_build_test
)
set(enable_sbom OFF)
else()
set(enable_sbom ON)
endif()
set(${out_var} "${enable_sbom}" PARENT_SCOPE)
endfunction()
macro(qt_internal_setup_sbom)
qt_internal_compute_sbom_default(_qt_generate_sbom_default)
option(QT_GENERATE_SBOM "Generate SBOM documents in SPDX v2.3 tag:value format."
"${_qt_generate_sbom_default}")
option(QT_SBOM_GENERATE_JSON
"Generate SBOM documents in SPDX v2.3 JSON format if dependencies are available" ON)
option(QT_SBOM_REQUIRE_GENERATE_JSON
"Error out if JSON SBOM generation dependencies are not found." OFF)
option(QT_SBOM_VERIFY "Verify generated SBOM documents." ON)
option(QT_SBOM_REQUIRE_VERIFY
"Error out if SBOM verification dependencies are not found." OFF)
endmacro()
macro(qt_internal_setup_build_examples)
option(QT_BUILD_EXAMPLES "Build Qt examples" OFF)
option(QT_BUILD_EXAMPLES_BY_DEFAULT

View File

@ -150,8 +150,6 @@ while(NOT "${configure_args}" STREQUAL "")
elseif(arg STREQUAL "-no-prefix")
set(no_prefix_option TRUE)
push("-DFEATURE_no_prefix=ON")
elseif(arg STREQUAL "-sbom")
push("-DQT_GENERATE_SBOM=ON")
elseif(arg STREQUAL "-cmake-file-api")
set(cmake_file_api TRUE)
elseif(arg STREQUAL "-no-cmake-file-api")
@ -317,6 +315,11 @@ endfunction()
# Add the common command line options for every qt repo.
macro(qt_add_common_commandline_options)
qt_commandline_option(headersclean TYPE boolean)
qt_commandline_option(sbom TYPE boolean)
qt_commandline_option(sbom-json TYPE boolean)
qt_commandline_option(sbom-json-required TYPE boolean)
qt_commandline_option(sbom-verify TYPE boolean)
qt_commandline_option(sbom-verify-required TYPE boolean)
endmacro()
function(qt_commandline_prefix arg var)
@ -927,6 +930,11 @@ translate_boolean_input(unity_build QT_UNITY_BUILD)
translate_string_input(unity_build_batch_size QT_UNITY_BUILD_BATCH_SIZE)
translate_boolean_input(ccache QT_USE_CCACHE)
translate_boolean_input(vcpkg QT_USE_VCPKG)
translate_boolean_input(sbom QT_GENERATE_SBOM)
translate_boolean_input(sbom-json QT_SBOM_GENERATE_JSON)
translate_boolean_input(sbom-json-required QT_SBOM_REQUIRE_GENERATE_JSON)
translate_boolean_input(sbom-verify QT_SBOM_VERIFY)
translate_boolean_input(sbom-verify-required QT_SBOM_REQUIRE_VERIFY)
translate_boolean_input(shared BUILD_SHARED_LIBS)
translate_boolean_input(warnings_are_errors WARNINGS_ARE_ERRORS)
translate_boolean_input(qtinlinenamespace QT_INLINE_NAMESPACE)

View File

@ -229,8 +229,10 @@ endfunction()
function(_qt_internal_sbom_end_project_generate)
set(opt_args
GENERATE_JSON
GENERATE_JSON_REQUIRED
GENERATE_SOURCE_SBOM
VERIFY
VERIFY_SBOM
VERIFY_SBOM_REQUIRED
VERIFY_NTIA_COMPLIANT
LINT_SOURCE_SBOM
LINT_SOURCE_SBOM_NO_ERROR
@ -258,13 +260,33 @@ function(_qt_internal_sbom_end_project_generate)
_qt_internal_get_staging_area_spdx_file_path(staging_area_spdx_file)
if(arg_GENERATE_JSON AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(REQUIRED OP_KEY "GENERATE_JSON")
_qt_internal_sbom_generate_json()
set(op_args
OP_KEY "GENERATE_JSON"
OUT_VAR_DEPS_FOUND deps_found
)
if(arg_GENERATE_JSON_REQUIRED)
list(APPEND op_args REQUIRED)
endif()
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(${op_args})
if(deps_found)
_qt_internal_sbom_generate_json()
endif()
endif()
if(arg_VERIFY AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(REQUIRED OP_KEY "VERIFY_SBOM")
_qt_internal_sbom_verify_valid()
if(arg_VERIFY_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
set(op_args
OP_KEY "VERIFY_SBOM"
OUT_VAR_DEPS_FOUND deps_found
)
if(arg_VERIFY_SBOM_REQUIRED)
list(APPEND op_args REQUIRED)
endif()
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(${op_args})
if(deps_found)
_qt_internal_sbom_verify_valid()
endif()
endif()
if(arg_VERIFY_NTIA_COMPLIANT AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)

View File

@ -245,24 +245,44 @@ function(_qt_internal_sbom_end_project)
endif()
set(end_project_options "")
if(QT_INTERNAL_SBOM_VERIFY OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options VERIFY)
if(QT_SBOM_GENERATE_JSON OR QT_INTERNAL_SBOM_GENERATE_JSON OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options GENERATE_JSON)
endif()
# Tring to generate the JSON might fail if the python dependencies are not available.
# The user can explicitly request to fail the build if dependencies are not found.
# error out. For internal options that the CI uses, we always want to fail the build if the
# deps are not found.
if(QT_SBOM_REQUIRE_GENERATE_JSON OR QT_INTERNAL_SBOM_GENERATE_JSON
OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options GENERATE_JSON_REQUIRED)
endif()
if(QT_SBOM_VERIFY OR QT_INTERNAL_SBOM_VERIFY OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options VERIFY_SBOM)
endif()
# Do the same requirement check for SBOM verification.
if(QT_SBOM_REQUIRE_VERIFY OR QT_INTERNAL_SBOM_VERIFY OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options VERIFY_SBOM_REQUIRED)
endif()
if(QT_INTERNAL_SBOM_VERIFY_NTIA_COMPLIANT OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options VERIFY_NTIA_COMPLIANT)
endif()
if(QT_INTERNAL_SBOM_SHOW_TABLE OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options SHOW_TABLE)
endif()
if(QT_INTERNAL_SBOM_AUDIT OR QT_INTERNAL_SBOM_AUDIT_NO_ERROR)
list(APPEND end_project_options AUDIT)
endif()
if(QT_INTERNAL_SBOM_AUDIT_NO_ERROR)
list(APPEND end_project_options AUDIT_NO_ERROR)
endif()
if(QT_INTERNAL_SBOM_GENERATE_JSON OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND end_project_options GENERATE_JSON)
endif()
if(QT_GENERATE_SOURCE_SBOM)
list(APPEND end_project_options GENERATE_SOURCE_SBOM)

View File

@ -45,7 +45,11 @@ The following table describes the mapping of configure options to CMake argument
| -device-option <key=value> | -DQT_QMAKE_DEVICE_OPTIONS=key1=value1;key2=value2 | Only used for generation qmake-compatibility files. |
| | | The device options are written into mkspecs/qdevice.pri. |
| -appstore-compliant | -DFEATURE_appstore_compliant=ON | |
| -sbom | -DQT_GENERATE_SBOM=ON | Enables generation and installation of an SBOM |
| -sbom | -DQT_GENERATE_SBOM=ON | Enables generation and installation of a SPDX SBOM documents |
| -sbom-json | -DQT_SBOM_GENERATE_JSON=ON | Enables generation of SPDX SBOM in JSON format |
| -sbom-json-required | -DQT_SBOM_REQUIRE_GENERATE_JSON=ON | Fails the build if Python deps are not found |
| -sbom-verify | -DQT_SBOM_VERIFY=ON | Enables verification of generated SBOMs |
| -sbom-verify-required | -DQT_SBOM_REQUIRE_VERIFY=ON | Fails the build if Python deps are not found |
| -qtinlinenamespace | -DQT_INLINE_NAMESPACE=ON | Make the namespace specified by -qtnamespace an inline one. |
| -qtnamespace <name> | -DQT_NAMESPACE=<name> | |
| -qtlibinfix <infix> | -DQT_LIBINFIX=<infix> | |

View File

@ -105,8 +105,18 @@ Build options:
through an app store by default, in particular Android,
iOS, tvOS, and watchOS. [auto]
-sbom ................ Enable Software Bill of Materials (SBOM) generation
[no]
-sbom ................ Enable generation of Software Bill of Materials (SBOM)
documents in SPDX tag:value format
[yes; no for developer builds]
-sbom-json ........... Enable SBOM generation in SPDX JSON format [auto]
(if Python dependencies are available)
-sbom-json-required .. Fails the build if the Python dependencies for JSON
generation are not found [no]
-sbom-verify ......... Verify generated SBOM files [auto] (if Python
dependencies are available)
-sbom-verify-required Fails the build if the Python dependencies for SBOM
verification are not found [no]
-qt-host-path <path> . Specify path to a Qt host build for cross-compiling.
-qtnamespace <name> .. Wrap all Qt library code in 'namespace <name> {...}'.