52 Commits

Author SHA1 Message Date
Alexandru Croitor
dbf44b61c1 CMake: Add a few more internal sbom helper functions
Add a few internal functions to allow
- getting the sbom project supplier
- project supplier url
- project namespace
- computing a project namespace
- computing a project file name
- getting a sanitized spdx id given a hint

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: I0dc3df274eaf6882a6af021aabee75501b5083f8
Reviewed-by: Moss Heim <moss.heim@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-24 19:36:09 +01:00
Alexandru Croitor
ffe972d72c CMake: Fix SBOM inline comment
Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: I53696003b144ad628169a345743e343cdfc022ae
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-24 19:36:08 +01:00
Alexandru Croitor
0be13fb699 CMake: Add qt exported target name and package name into SBOM
Add them to the PackageComment field of the SBOM.
Can be useful to map back the SPDX Package to the CMake target or
package.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: Icbbb90132038c489b55c4ee7a038aea593ce1ff6
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-24 19:36:08 +01:00
Alexandru Croitor
d2dea0bc08 CMake: Add a fake deterministic SBOM generation option
Replaces content like timestamps, version strings and checksums with
constant values to make the SBOM generation deterministic.
This is useful for reproducible builds, to allow cleaner inter-diffs
while developing new SBOM features.

Can be enabled by configuring with
-DQT_SBOM_FAKE_DETERMINISTIC_BUILD=ON

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: Id0003bdd23fe57abd70213a2a108885861693242
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-24 19:36:08 +01:00
Alexandru Croitor
2857d8d5ea CMake: Add SUPPLIER as an option to SBOM packages
Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: I22cae71dcc7582126320e17271a8c55bea1ad393
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-24 19:36:07 +01:00
Alexandru Croitor
41a92bf6f1 CMake: Fix sbom git vars not being available in various scopes
Initially the git vars were assigned to the parent scope of the
_qt_internal_sbom_begin_project function, with the intent to set them
in the global scope. But the function was later wrapped in other
functions, so the variables stopped being accessible.

Instead of playing with recursive PARENT_SCOPEs, save the variables in
global properties like we do for other info, and use a new
_qt_internal_sbom_get_git_version_vars() function to query the vars in
the code that needs them.

This fixes generated purls to contain the git version and hashes.

Also add a new internal API wrapper macro called
qt_internal_sbom_get_git_version_vars to allow calling it
in other repos.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: I061b34f418c1ecc1c66c8c01ef758d2f40611ede
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-10 18:42:23 +01:00
Alexandru Croitor
27d2b54b5d CMake: Split SBOM implementation into separate files
The SBOM implementation got somewhat large. Split the code into
several new QtPublicSbomFooHelpers.cmake files, to make it more
manageable.

No code or behavior was changed.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: Ia0ca1792eec21d12c4bb4cabe63279e1f5c07e3d
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-10 18:42:22 +01:00
Alexandru Croitor
4c5d9a3ca3 CMake: Fix purl variant list iteration
The correct syntax is IN LISTS, not IN_LIST.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: Ibf64e48ffcf0b061887b7b015096d588b14bce57
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-10 10:54:03 +01:00
Alexandru Croitor
2affe46b25 CMake: Fix LINK_LIBRARIES not being properly processed for SBOM
There was a typo in the link_libraries variable name, where an upper
case 'L' was used instead of a lower case 'l'.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Change-Id: I206a161107cf7510856ad8740dada88e12341e94
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-10 10:54:01 +01:00
Alexandru Croitor
bc3bbb51b7 CMake: Replace placeholders in CPE and PURL strings in SBOMs
Replace instances of $<VERSION> in CPE and PURL strings read from
qt_attribution.json files with the version of the package being
processed.

This avoids duplicating the version in qt_attribution.json files in 3
different fields Version, CPE, and PURL.

Pick-to: 6.8 6.9
Task-number: QTBUG-132181
Change-Id: I91af17c82dbb936739f4811bf86043e00ee49a78
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-09 19:33:15 +01:00
Alexandru Croitor
b8f5e5f554 CMake: Add way to convert JSON SPDX to tag/value SPDX document
Add a new qt_internal_sbom_generate_tag_value_spdx_document function
that takes an input SPDX JSON file and generates a tag/value SPDX
file. This is needed by WebEngine to convert the Chromium JSON file to
a tag/value SPDX file so we can reference it as an external document.

To ensure the external document is found, we now always add the
current sbom build directories as install prefixes. This was
previously done only for top-level builds.

To ensure the converted external document is referenced only after it
is converted, it needs to be converted before any targets mention
packages from within it.

A sample usage might be:

qt_internal_sbom_generate_tag_value_spdx_document(
    OPERATION_ID qt5compat
    INPUT_JSON_FILE_PATH "${external_sbom_file_path}"
    OUT_VAR_OUTPUT_FILE_NAME external_output_file_name
    OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH external_output_file_path
)

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I5d5397f788c8c7960b6fc233c2868244e5816e0b
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-09 19:33:15 +01:00
Alexandru Croitor
d079fdd76c CMake: Allow adding custom SBOM relationships to targets and projects
Add a new SBOM_RELATIONSHIPS option to qt_internal_extend_target and
friends that allows adding custom relationships to the current target.

Add a new function qt_internal_sbom_add_project_relationship that
allows adding custom relationships to the current project SBOM
document.

A sample usage might be:

qt_internal_sbom_get_project_spdx_id(project_spdx_id)
qt_internal_sbom_get_target_spdx_id(Svg svg_spdx_id)

qt_internal_extend_target(Svg
    SBOM_RELATIONSHIPS
        "${svg_spdx_id} DESCENDANT_OF ${project_spdx_id}"
)

qt_internal_sbom_add_project_relationship(
    RELATIONSHIPS
        "${svg_spdx_id} CONTAINS NOASSERTION"
        "${svg_spdx_id} DESCRIBES NOASSERTION"
        "${project_spdx_id} DESCRIBES NOASSERTION"
)

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: Ie0119ca71b047c7515e1deaf84a5a67ea01b5274
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-01-09 19:33:15 +01:00
Alexandru Croitor
9a3998692c CMake: Add API to allow referencing external packages in the SPDX SBOM
This change modifies the existing implementation of the
external references API to have better named options and better
behavior.
It also adds comments and exposes an internal API wrapper around the
existing implementation.
It's meant to be used by qtwebengine to reference the
Chromium-generated SBOM.

As a drive-by, it removes the previously unused RENAME option.

A sample usage could be:

qt_internal_sbom_get_external_document_ref_spdx_id(
    "qt5compat" document_ref_spdx_id)
qt_internal_sbom_add_external_reference(
    EXTERNAL_DOCUMENT_FILE_PATH "/path/to/qt5compat-6.8.1.spdx.json"
    EXTERNAL_DOCUMENT_SPDX_ID "${document_ref_spdx_id}"
)

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I13d0fe4d803449bec42f8b454c8131e4d727669a
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
2025-01-09 19:33:14 +01:00
Alexandru Croitor
b085fe6ad9 CMake: Add SBOM support for translations, custom files and friends
This change introduces a new SBOM API to add info about various kinds
of files to a target SBOM package. The new function name is called
qt_internal_sbom_add_files().

The motivating case is including SBOM information for qt translation
files, resources (e.g. webengine data files) and any other kind of
custom files.

A sample call might look like:

qt_internal_sbom_add_files(Translations
    FILES "${qm_files}"
    SOURCE_FILES_ONE_PER_INPUT_FILE "${ts_files}"
    FILE_TYPE "QT_TRANSLATION"
    INSTALL_PATH "${INSTALL_TRANSLATIONSDIR}"
)

While the motivating case is Qt-specific, the function implementation
is being somewhat future proofed for the not-yet created public SBOM
API.

The new API supports adding files to any target that is backed by an
SBOM package, so all targets created by qt_internal_add_module()
and friends, as well as ones created by qt_internal_add_sbom().

It can be called multiple times for the same target, with a different
set of files, to e.g. assign a different license, or file type per
file set. Note that the file set doesn't have anything to do with
CMake's concept of file sets.
The function is also multi-config aware, and allows specifying
different install paths per config, as well as generator expressions
in file names. But the multi-config support is a bit wonky, and might
need some rethinking in the future.

Note that the custom files must be installed and available in the
specified qt install path, because the file contents will be
checksummed at install time and embedded into the sbom document.
Calling the new API does not do installation itself.

Implementation wise, the function call flow is
- project calls qt_internal_sbom_add_files() one or more times
- at finalization time, the _qt_internal_sbom_add_target finalizer is
  called for a target, which then calls
  _qt_internal_sbom_handle_target_custom_files()
- the latter calls _qt_internal_sbom_handle_target_custom_file_set()
  for each file set that was added to the target
- the latter calls _qt_internal_sbom_handle_multi_config_custom_file()
  for each input file in the file set, which ultimately calls
  _qt_internal_sbom_add_custom_file()

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Task-number: QTBUG-128320
Change-Id: Iafde26ebd68f4168b49e55fbc8ad1c251e98d4b0
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-09 19:33:14 +01:00
Alexandru Croitor
42a58d6619 CMake: Remove SBOM multi-config dead code
These variables were not used anywhere.

Pick-to: 6.8 6.9
Task-number: QTBUG-128893
Task-number: QTBUG-122899
Change-Id: If53b3fd8200971dcfde69cefa4df07b67d5669c5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-09 19:33:14 +01:00
Alexandru Croitor
2fa815341c CMake: Move SBOM project ops setup to run at project begin time
Previously Python and other sbom tooling was looked up at SBOM
project end time.
This was fine for the use cases we had so far, but it prevents
introducing new API that wants call the spdx tools before the end of
the project. Such API will be introduced in a follow up change.

Move the python interpreter, python dependency lookup and other sbom
tooling setup to happen at project begin time.

Pick-to: 6.8 6.9
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: Ic8884e378c0ffd9720ede26b0c61f4122f3bb9d9
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-01-09 19:33:13 +01:00
Alexandru Croitor
43e166bd08 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>
2024-12-05 15:37:00 +01:00
Alexandru Croitor
ffef516884 CMake: Support cmake --install . --prefix <path> for SBOM generation
Before this change, the SBOM generation only considered the
CMAKE_INSTALL_PREFIX set at configure time for the purposes of file
checksum computation, external document lookup, and SBOM file
installation.

When cmake --install . --prefix <path> is used, the install time
CMAKE_INSTALL_PREFIX variable is overridden with the provided path,
and can be different from the configure time value.

This path was applied to the installation of regular files, libraries,
etc, but not to the SBOM generation. This caused issues like not being
able to find a library to compute its checksum.

Instead of hard-coding the value to QT_STAGING_PREFIX, just don't pass
a value at all, and rely on the new default of using an
install-time-evaluated \${CMAKE_INSTALL_PREFIX}.

Keep the ability of specifying a custom prefix just in case.

Modify all the code that used a hard-coded CMAKE_INSTALL_PREFIX to use
a install-time-evaluated one instead.

As a drive-by, also set a proper default value for the INSTALL_SBOM_DIR
option.

Pick-to: 6.8
Fixes: QTBUG-131883
Change-Id: Ifde6ab282ac40f10c5bf51976121065c7dc631eb
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-12-05 15:37:00 +01:00
Alexandru Croitor
df30953228 CMake: Fix standalone build of sqldrivers with SBOM
The standalone build of the sqldrivers plugin never called the SBOM
project begin and end functions.
This cause an error in qt_internal_add_plugin which tried to read the
SBOM project name.

Replace the calls to qt_prepare_standalone_project and
qt_print_feature_summary with qt_build_repo_begin and
qt_build_repo_end.
This ensures the SBOM project is setup, as well as many other
behaviors that a standalone internal build of a module is expected to
have.

Additionally we need to tell the SBOM project where to find the
licenses for the standalone build. This is done by setting the new
QT_SBOM_LICENSE_DIRS variable to the qtbase license directory.

Pick-to: 6.8
Fixes: QTBUG-131799
Change-Id: I2e31ecffdff28561d1c4a6b8fbcd8125188d2c48
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-12-03 21:18:21 +01:00
Alexandru Croitor
9cb0d48aae CMake: Fix unescaped path MATCH condition in QtPublicSbomHelpers
Use string(FIND) instead of if(MATCH) since paths containing special
regex symbols like "+", can either cause an invalid MATCH result or it
can lead to regex compilation errors like
 RegularExpression::compile(): Nested *?+.
 RegularExpression::compile(): Error in compile.

Amends 6e7f871edfd35174b40c7eb7386282bfe019f276

Pick-to: 6.8
Fixes: QTBUG-131782
Task-number: QTBUG-122899
Task-number: QTBUG-130557
Change-Id: I59a2c3e4fe2431303c7cbca8fd54360f254da90f
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-12-02 20:32:04 +01:00
Alexandru Croitor
aee347e0a7 CMake: Fix CMP0174 warnings in SBOM generation code
Pick-to: 6.8
Change-Id: Iabe959eda65a0bf7dd94b20cfce7d55642f9096d
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-11-19 19:22:30 +01:00
Alexandru Croitor
6e7f871edf CMake: Improve handling of file paths embedded into SBOM
Filter out source files that are not actually sources, like pkg config
files and json.gen files.

To make the output more reproducible, replace the absolute source and
build directories with relative paths prepended with a marker like
/src_dir/ and /build_dir/.

Apply this to source file paths and to qt attribution json file paths.

Genex wrapped sources still need to be handled, but that will come in
a later change.

Amends 37a5e001277db9e1392a242171ab2b88cb6c3049

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-130557
Change-Id: Ic38cd9df827c1da770c1f337bc4725748bed5560
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-28 23:54:56 +02:00
Alexandru Croitor
b6ee361bc7 CMake: When available add the repo configure line to the SBOM
When Qt is configured using the configure script, rather than directly
via CMake, we can obtain the full list of configure arguments passed
from the config.opt file.

Add the configure line to the repo project SBOM package comment field
when it is available.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I0c5554dcda2f71ec4ba034b14c82a99757dc790c
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-19 21:16:25 +02:00
Alexandru Croitor
96c5e55c11 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>
2024-10-19 21:16:17 +02:00
Alexandru Croitor
f15b3c864e CMake: Split SBOM verification and NTIA compliance into separate ops
This will allow us to run only the first, but not the second, if the
second won't have it's dependencies met.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I141b4bd3b76a71495c760a118bdf1397ee7e16b5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-19 21:16:15 +02:00
Alexandru Croitor
4e120f265c CMake: Check for target existence before recording system lib spdx id
Otherwise the spdx id recording function might fail when trying to
retrieve the spdx id from the non-existent target.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I1f6b3d7bc88ff4aa28de1468cd86152747cc3bdb
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-19 21:16:08 +02:00
Alexandru Croitor
e579b2884e CMake: Add configure-time dependency on project attribution files
Otherwise the SBOM is not regenerated if the attribution files are
modified.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I5b3f62e254aa70021ed06fac73f881bcbb110c31
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-15 13:05:13 +02:00
Alexandru Croitor
3809ebcb13 CMake: Update default copyright for Qt SBOM packages
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I087ff034023724e5bae736dbd8168198dc6bfce3
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
2024-09-12 16:35:27 +02:00
Alexandru Croitor
3cadd4b1f6 CMake: Add the Qt-specific CPE to 3rd party entity types in SBOM
Some vendored 3rd party sources or libraries may not have a CPE
because the upstream disappeared, we don't know where the files
originally originated from, or no CPE was ever issued.

Given that the 3rd party files are shipped with Qt, they can
be considered as part of the "Qt" CPE for vulnerability tracking
reasons.

In such cases, we should add the Qt-specific CPE to the SBOM to ensure
that the SBOM is as complete as possible when tooling analyzes the
third party packages.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I32a70e24742a860198f3a6b12bdb4a06057f1ab3
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-09-03 16:42:24 +02:00
Alexandru Croitor
ce7a01f0ec CMake: Add a function to detect qt 3rd party entity types for SBOM
Removes some condition duplication.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ib245a96b5f8c78b2744cb4fd09a392b2924bf45c
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-09-03 16:42:24 +02:00
Alexandru Croitor
797ce76ee9 CMake: Handle multi-value PURLs and CPEs in attribution files
Qt attribution json files might want to specify more than one PURL or
CPE for a given entry. Change the build system code to detect whether
a JSON PURL or CPE key contains an array of values, and if so, convert
it to a cmake list and use that for further SBOM handling.

As a result, the PURL_QT_VALUE, PURL_3RDPARTY_UPSTREAM_VALUE, and
PURL_MIRROR_VALUE getting an 'S' at the end, aka they are renamed to
PURL_QT_VALUES, PURL_3RDPARTY_UPSTREAM_VALUES, and PURL_MIRROR_VALUES.

Also the attribution key is now called just PURL instead of
UpstreamPURL.

The CPE json attribution key and option name stay the same.

Amends 47fd38be4bce0958fcfce8080d1580c4e3c2a15b
Amends 95b7fe49900904d19fca21876c84f97c2a6ae03d
Amends f7e1123620b623be0c321b54eaba7a1d618a7ce1

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ieec919901c3b44df80bc196536f68632a9761d92
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-08-29 20:21:15 +02:00
Alexandru Croitor
d624592ca4 CMake: Don't forward FRIENDLY_PACKAGE_NAME to sub-attribution targets
Instead, the package name should be determined by the sub-attribution
target name. Otherwise the build system will try to generate multiple
files with the same name, but different content.

Amends 5daabb5a74c4e7c5d087da7f9207d79d2ee05b13

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I10b4ec2fe8f38d70d13918dc980d1bd1d9145cb6
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-08-20 03:01:40 +02:00
Alexandru Croitor
55b399fdcd CMake: Don't use root attribution file for system libraries
A project's root qt_attribution.json file might be picked up by the
build system when recording system libraries for SBOM processing.
One such case is qtgrpc.

This caused generation errors in qtgrpc with the following message:

CMake Error: Files to be generated by multiple different commands:
 qt_sbom/SPDXRef-Package-qtgrpc-qt-3rdparty-sources-WrapProtobuf.cmake

This started happening since the SBOM options are now implicitly
propagated to auto-created attribution targets, and each attribution
target attempted to generate to the same partial sbom file.

Any qt attribution file in the project root is not intended to be
used for system libraries, so explicitly disable using the
root attribution file for all system libraries.

As a more long-term fix, we should consider making the partial sbom
files be more unique.

Amends 5daabb5a74c4e7c5d087da7f9207d79d2ee05b13

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I67544c299e630597f26602d270cd1dfd54cccfb6
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-08-20 03:01:40 +02:00
Alexandru Croitor
47fd38be4b CMake: Read CPEs from attribution files when generating SBOMs
Also split up the CPE handling to allow for more values to be set,
rather than preferring the first one that is encountered.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I3209cb5d66f5483c7294b40816431d9df75e00e5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-17 12:50:03 +02:00
Alexandru Croitor
95b7fe4990 CMake: Read UpstreamPURL from attribution files when generating SBOMs
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Id65770cdee17c6bf4701b10565ab428f3e28887f
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-17 12:49:58 +02:00
Alexandru Croitor
f7e1123620 CMake: Rework SBOM PURL handling to handle multiple values
Using a single PURL for a target is not enough to represent all the
information that an SBOM processing tool might want to know about.

For example for the bundled harfbuzz package, we want to inform at
least about two versions: the upstream version that was originally
imported into Qt sources, and the Qt version or sha1 of the sources
that were used, because the 3rdparty code might have been modified and
there might be new Qt-specific vulnerabilities.

To handle this, we need to generate multiple PURLs for a single
target.

Introduce six new options to be understood by qt_internal_add_module
and other SBOM functions:
 - PURL_QT_ARGS
 - PURL_MIRROR_ARGS
 - PURL_3RDPARTY_UPSTREAM_ARGS
 - PURL_QT_VALUE
 - PURL_3RDPARTY_UPSTREAM_VALUE
 - PURL_MIRROR_VALUE

The first three options take multiple arguments, and will generate a
PURL for each used variant, based on the purl parsing options that
were previously handled. For example passing:
  PURL_3RDPARTY_UPSTREAM_ARGS
      PURL_TYPE "github"
      PURL_NAMESPACE "harfbuzz"
      PURL_NAME "harfbuzz"
      PURL_VERSION "v8.5.0" # tag

will generate a PURL pointing to the upstream harfbuzz repo hosted
on github.

The next three options allow specifying a purl value directly as a
single string, rather than as separate parts. This might be useful
when the PURL is pre-constructed and read from a qt_attribution file.
Example:
  PURL_3RDPARTY_UPSTREAM_VALUE "pkg:github/harfbuzz/harfbuzz@v8.5.0"

When no arguments are specified, targets like Qt modules or Qt
3rd party libraries will have automatically generated QT and MIRROR
variant PURLs that point to code.qt.io and github.com, along with
important info like the version and subdir source path for a given
target.

Third party libraries are expected to be manually annotated with a
3RDPARTY_UPSTREAM variant PURL that points to the original upstream.
In a future change, these will be read from a qt_attribution.json
file.

The final set of generated PURLs for the harfbuzz package might look
like:

  pkg:github/harfbuzz/harfbuzz@v8.5.0
  pkg:github/qt/qtbase@5018b71e99f?library_name=BundledHarfbuzz#src/3rdparty/harfbuzz-ng
  pkg:generic/TheQtCompany/qtbase-BundledHarfbuzz@5018b71e99f?vcs_url=https://code.qt.io/qt/qtbase.git@5018b71e99f&library_name=BundledHarfbuzz#src/3rdparty/harfbuzz-ng

Additionally a few more purl parsing options are added.

Add a PURL_USE_PACKAGE_VERSION option that will use the
qt_attribution.json or custom PACKAGE_VERSION value as the PURL
version, so it doesn't have to be manually specified.

This is an opt-in, and not the default, because some attribution
files contain plain text, white-space separated, strings as the
version value (like the 'sha3' 3rd party lib) which ends up generating
a broken PURL and a failing JSON conversion of the SBOM.
So we have to manually annotate targets that should use the
attribution json package version, until a better way to handle this
can be found.

Add a PURL_VCS_URL option that will generate a PURL qualifier (a HTTP
query parameter) with the given value, to indicate to SBOM-processing
tools what is the upstream repo URL for the package.
They can use this information to display known vulnerabilities for the
package hosted at that URL.
This is mostly useful for the generic QT purl variant, and is
automatically generated for Qt entity types.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ie000b01b478bef4bff6f4803dd39e37b7a8055d5
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-08-17 12:49:56 +02:00
Alexandru Croitor
b17dfbbb99 CMake: Detect 3rd party header modules during SBOM generation
They should inherit the version of the 3rd party library they are part
of, and not be treated as Qt modules.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ibf99f4481fbc1acca488fc96cca048298b080d35
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-17 12:49:54 +02:00
Alexandru Croitor
5daabb5a74 CMake: Propagate SBOM options to auto-created attribution targets
Previously if an option like CPE was passed to a 3rd party target that
would create nested attribution targets, one per entry in the
attribution file, the CPE option would only apply to the first /
parent target, but not to the nested targets.

This change will now propagate all SBOM options to the nested targets,
but only if the parent target is not a Qt entity type like a module,
plugin, etc, which means it will only apply to 3rd party attribution
targets. The restriction is there because because mostly only 3rd
party attribution targets should inherit the same set of CPEs and
similar SBOM values.
If the restriction proves to be too strict, it will be re-assessed in
a future change.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I96cfa046ad611c10877b7a06504b35615b539bbe
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-17 12:49:52 +02:00
Alexandru Croitor
3e7fc98063 CMake: Expose the short git hash during SBOM generation
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Id87afba7bce4d67984c7e8811444fd35be758bec
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-17 12:49:50 +02:00
Alexandru Croitor
6d9b429174 CMake: Allow generating and verifying a source SBOM using 'reuse' tool
Add code to generate and install a source SBOM SPDX file for every
repo. It relies on the python 'reuse' tool being installed and
available in PATH.

Also add code to allow running 'reuse lint', which checks compliance
with the reuse specification.

The features are only enabled when configuring with
 -DQT_GENERATE_SBOM=ON
 -DQT_GENERATE_SOURCE_SBOM=ON
 -DQT_LINT_SOURCE_SBOM=ON
which will be the case for our CI in a follow up patch.

Because most of our repos are not yet reuse compliant, the actual
generation of the source SBOM and the linting is skipped if the
project root directory does not contain a REUSE.toml file.

This allows incremental handling of each repository, while also
enforcing the compliance at installation time when the REUSE.toml file
is actually there.

The source SBOM generation and linting will run at installation time,
but they can also be manually triggered at build time using the
ninja 'sbom' and 'reuse_lint' custom targets.

Various opt outs are provided as a fail safe:
- QT_FORCE_SOURCE_SBOM_GENERATION to force source sbom generation
  even if a REUSE.toml file is not present in the root source dir
- QT_FORCE_REUSE_LINT_ERROR to force linting to error out, even if
  a REUSE.toml file is not present
- QT_FORCE_SKIP_REUSE_LINT_ON_INSTALL to skip linting at installation
  time, but allow running it at build time

These can be set either locally or conditionally passed to CMake
inside repo-specific Coin instructions.

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-125211
Change-Id: I664e69830936c4427688143ee86b98782c1733ab
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-07-24 14:37:54 +02:00
Alexandru Croitor
f6fdc1fe5f CMake: Improve SBOM PURL handling
Tools that consume SBOMs expect that each SBOM package will contain a
unique purl: https://github.com/package-url/purl-spec

Each Qt target maps to an SBOM package, so generate a target-specific
PURL for each Qt target, by using the combination of the repo name
and target name as the purl name.
The purl external reference will then look something like:

ExternalRef: PACKAGE-MANAGER purl pkg:/TheQtCompany/qtbase-Gui@6.8.0

Also allow customizing the purl for each target by specifying one of
the following options to functions like qt_internal_add_module or
qt_internal_extend_sbom:
- PURL_TYPE
- PURL_NAMESPACE
- PURL_NAME
- PURL_VERSION
- PURL_SUBPATH
- PURL_QUALIFIERS
- NO_PURL
- NO_DEFAULT_QT_PURL

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I6926dd773a0ef6fc688664bcac7b23483ecbabe6
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-07-23 16:29:26 +02:00
Alexandru Croitor
04ade5acc9 CMake: Allow marking incomplete 3rd party deps for a target's SBOM
For some targets, it might not be possible to specify all 3rd party
dependencies information for SBOM generation.

qtwebengine is one of these cases, where the 3rd party targets are
only known to GN, and not CMake.

Add a new SBOM_INCOMPLETE_3RD_PARTY_DEPENDENCIES option which can be
passed to qt_internal_add_module and friends.
This will include an informational message into the SBOM package
comment field that the dependency information might be incomplete.

Also add an SBOM_PACKAGE_COMMENT option, which can be used to provide
further information if necessary.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I5e893e1e205aae4a5591a457be88d5db54fa8fc3
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
2024-07-22 15:16:14 +02:00
Alexandru Croitor
d24936dbdc CMake: Fix SBOM unsupported type for internal apps targeting Android
Usually apps created by qt_internal_add_app() are not meant for
installation on Android, and are excluded from installation using
qt_exclude_tool_directories_from_default_target().

Some repos might be missing the exclusion call, which means the app
would be built and installed on Android.

qt_internal_add_app creates MODULE_LIBRARYs instead of EXECUTABLEs
when targeting Android. While the SBOM machinery only expects
EXECUTABLEs for apps.

If the app target is not excluded (in which case the SBOM would be
skipped), this would cause the SBOM code to error out saying the
target type is unsupported.

To prevent further errors like this, add MODULE_LIBRARY as a valid
target type for qt apps.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I3ec80add22f0584638990171c59b78c24725c052
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-07-12 21:53:27 +02:00
Alexandru Croitor
31126b2b77 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 <joerg.bornemann@qt.io>
2024-06-25 20:57:50 +02:00
Alexandru Croitor
34b5dc041b CMake: Skip handling binary files in SBOM for excluded targets
If a target has the _qt_internal_excluded_from_default_target property
set, don't try to add file SBOM information for the target, because
the file will not be built nor installed by default.

We check for a new custom _qt_internal_excluded_from_default_target
property instead of EXCLUDE_FROM_ALL, because EXCLUDE_FROM_ALL might
be set to a genex that excludes all configs except the main one, but
we are interested whether the target is entirely excluded.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I79d6a4b0c65356da14f7ff50ee3639705f5fabbd
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-06-25 20:57:50 +02:00
Alexandru Croitor
0ea3164969 CMake: Allow force disabling generation of SBOM
We need it to disable generation for certain repos like qtqa, even
if the platform config says that SBOMs should be enabled.

We can't just set QT_GENERATE_SBOM to OFF, because the general SBOM
CI instructions are added later that module specific ones, and thus
would override the value back to ON.

Providing a separate internal variable allows us to disable it with a
higher priority.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: If7803ae4aac0886d605a542e3f05ad9533bb8108
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-06-25 20:57:50 +02:00
Alexandru Croitor
089111aee0 CMake: Handle system alias targets when recording them for the SBOM
Un-alias system target names before processing them for the SBOM,
otherwise we'll get errors about trying to set properties on alias
targets.

Amends 37a5e001277db9e1392a242171ab2b88cb6c3049

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ifef2108be123549505ed67f0b9c258a10431c84e
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-06-25 20:57:50 +02:00
Alexandru Croitor
0f5699ee3d CMake: Only record existing system library targets for SBOM
In certain cases the qt_find_package(PROVIDED_TARGETS) might not
exist, so we shouldn't record the targets for SBOM spdx id
registration in that case.

Amends 37a5e001277db9e1392a242171ab2b88cb6c3049

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Iada6b5a20a3e7526f18ae4385db8a29fee68ab36
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-06-25 20:57:49 +02:00
Alexandru Croitor
fe90ba7041 CMake: Improve license handling for SBOMs
Add a NO_ATTRIBUTION_LICENSE_ID option to allow to skip including
license references from qt_attribution.json files.

Add a QT_LICENSE_ID option that can take an "id" value and return one
of the common license expressions we use throughout Qt repositories:
- GPL3 with exception for tools / apps
- GFDL for documentation
- GPL3 only modules
etc.

Add a QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES variable that can be set
at directory scope (or root repo scope) to use a specific license id
for all qt modules / plugins created within that repo, e.g. the
Commercial + GPL3 variant. These can be opted out, to fallback to the
"default" license by passing NO_DEFAULT_QT_LICENSE_ID_LIBRARIES.

Add a similar variable  QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES
for tools / apps, including a NO_DEFAULT_QT_LICENSE_ID_EXECUTABLES
option.

Modify the logic for setting licenses for qt targets:
- use whatever is set in QT_SBOM_DEFAULT_QT_LICENSE_EXECUTABLES
  for tools and apps
- or use the 'GPL3 with exception' variant for tools and apps
- use whatever is set in QT_SBOM_DEFAULT_QT_LICENSE_LIBARRIES for
  modules ands plugins
- or use the default Commercial + LGPL3 + GPL variant for
  modules and plugins

Amends 37a5e001277db9e1392a242171ab2b88cb6c3049

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I3a8abac62b9f4b342f91ef139064884f02aa935e
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-06-18 10:49:27 +02:00
Alexandru Croitor
81162cc8b6 CMake: Allow specifying most SBOM options to qt_internal_add_foo
Previously, only a very short subset of options related to attribution
files could be specified to qt_internal_add_module /
qt_internal_extend_target.

It is more convenient to allow specifying most (safe) options, instead
of calling another function.

Unsafe are considered paths like INSTALL_PATH and derivatives, TYPE
which is too generic, and some other ones like LIBRARIES which would
be duplicated, and causes warnings in cmake_parse_arguments if
duplicated.

Change the code to allow specifying most SBOM options and forwarding
them to _qt_internal_extend_sbom.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I6eb723e165edf59973d83c66eace43acdce237de
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-06-18 10:49:26 +02:00