From 8c36f4ba3f12db1bd1204218b1f25450585e71cd Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Thu, 12 Sep 2024 13:12:31 +0200 Subject: [PATCH 01/19] refactor: compliance with US and German federal guidelines This required a change in function signature, which made previous optional arguments required and limited some options for argument values. --- cmake/sbom.cmake | 126 +++++++++++++++++----------------- readme.md | 172 ++++++++++++++++++++++------------------------- 2 files changed, 146 insertions(+), 152 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index c2989c2..e6152f5 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -572,8 +572,8 @@ function(sbom_generate) message(FATAL_ERROR "Unknown arguments: ${SBOM_GENERATE_UNPARSED_ARGUMENTS}") endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_NAME) - set(SBOM_GENERATE_PACKAGE_NAME ${PROJECT_NAME}) + if(NOT DEFINED GIT_VERSION) + version_extract() endif() if(NOT DEFINED SBOM_GENERATE_CREATOR) @@ -582,7 +582,7 @@ function(sbom_generate) cmake_parse_arguments(SBOM_GENERATE_CREATOR "" "PERSON;ORGANIZATION;EMAIL" "" ${SBOM_GENERATE_CREATOR}) if(SBOM_GENERATE_CREATOR_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown subarguments: ${SBOM_GENERATE_CREATOR_UNPARSED_ARGUMENTS} for CREATOR.") + message(FATAL_ERROR "Unknown subarguments for CREATOR: ${SBOM_GENERATE_CREATOR_UNPARSED_ARGUMENTS}.") endif() if((NOT DEFINED SBOM_GENERATE_CREATOR_PERSON) AND (NOT DEFINED SBOM_GENERATE_CREATOR_ORGANIZATION)) message(FATAL_ERROR "Missing for argument CREATOR.") @@ -590,27 +590,12 @@ function(sbom_generate) message(FATAL_ERROR "Specify either PERSON or ORGANIZATION, not both.") endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_URL) - if(NOT DEFINED SBOM_GENERATE_NAMESPACE) - message(FATAL_ERROR "Specify NAMESPACE when PACKAGE_URL is omitted.") - endif() - endif() - - if(NOT DEFINED SBOM_GENERATE_NAMESPACE) - if((NOT DEFINED SBOM_GENERATE_PACKAGE_URL) OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NONE") OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NOASSERTION")) - message(FATAL_ERROR "Specifiy PACKAGE_URL when NAMESPACE is omitted.") - endif() - set(SBOM_GENERATE_NAMESPACE "${SBOM_GENERATE_PACKAGE_URL}/spdxdocs/${SBOM_GENERATE_PACKAGE_NAME}-${SBOM_GENERATE_PACKAGE_VERSION}") - endif() - - if(NOT DEFINED GIT_VERSION) - version_extract() + if(NOT DEFINED SBOM_GENERATE_PACKAGE_LICENSE) + message(FATAL_ERROR "Missing required argument PACKAGE_LICENSE.") endif() - string(TIMESTAMP NOW_UTC UTC) - - if(NOT DEFINED SBOM_GENERATE_OUTPUT) - set(SBOM_GENERATE_OUTPUT "./${CMAKE_INSTALL_DATAROOTDIR}/${SBOM_GENERATE_PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx") + if(NOT DEFINED SBOM_GENERATE_PACKAGE_NAME) + set(SBOM_GENERATE_PACKAGE_NAME ${PROJECT_NAME}) endif() if(NOT DEFINED SBOM_GENERATE_PACKAGE_VERSION) @@ -633,10 +618,14 @@ function(sbom_generate) endif() endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_LICENSE) - set(SBOM_GENERATE_PACKAGE_LICENSE "NOASSERTION") + if(NOT DEFINED SBOM_GENERATE_PACKAGE_URL) + if(NOT DEFINED SBOM_GENERATE_NAMESPACE) + message(FATAL_ERROR "Specify NAMESPACE when PACKAGE_URL is omitted.") + endif() endif() + string(TIMESTAMP NOW_UTC UTC) + if(NOT DEFINED SBOM_GENERATE_PACKAGE_COPYRIGHT) string(TIMESTAMP NOW_YEAR "%Y" UTC) @@ -667,6 +656,17 @@ function(sbom_generate) _sbom_parse_package_purpose("${SBOM_GENERATE_PACKAGE_PURPOSE}" SBOM_GENERATE_PACKAGE_PURPOSE) endif() + if(NOT DEFINED SBOM_GENERATE_OUTPUT) + set(SBOM_GENERATE_OUTPUT "./${CMAKE_INSTALL_DATAROOTDIR}/${SBOM_GENERATE_PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx") + endif() + + if(NOT DEFINED SBOM_GENERATE_NAMESPACE) + if((NOT DEFINED SBOM_GENERATE_PACKAGE_URL) OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NONE") OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NOASSERTION")) + message(FATAL_ERROR "Specifiy PACKAGE_URL when NAMESPACE is omitted.") + endif() + set(SBOM_GENERATE_NAMESPACE "${SBOM_GENERATE_PACKAGE_URL}/spdxdocs/${SBOM_GENERATE_PACKAGE_NAME}-${SBOM_GENERATE_PACKAGE_VERSION}") + endif() + if(${SBOM_GENERATE_ENABLE_CHECKS}) set(SBOM_CHECKS_ENABLED ON CACHE BOOL "Warn on important missing fields.") else() @@ -813,6 +813,16 @@ function(_sbom_add_path PATH) set(_fields "") + set(_arg_add_path_LICENSE_DECLARED "NOASSERTION") + if(NOT DEFINED _arg_add_path_LICENSE) #??? maybe use package license as default? + message(FATAL_ERROR "Missing LICENSE argument for ${PATH}.") + endif() + _sbom_parse_license("CONCLUDED;${_arg_add_path_LICENSE}" _arg_add_path_LICENSE_CONCLUDED _arg_add_path_LICENSE_DECLARED _arg_add_path_LICENSE_COMMENT) + string(APPEND _fields "\nLicenseConcluded: ${_arg_add_path_LICENSE_CONCLUDED}") + if(DEFINED _arg_add_path_LICENSE_COMMENT) + string(APPEND _fields "\nLicenseComments: ${_arg_add_path_LICENSE_COMMENT}") + endif() + if(DEFINED _arg_add_path_FILETYPE) _sbom_parse_filetype("${_arg_add_path_FILETYPE}" _arg_add_path_FILETYPE) foreach(_filetype ${_arg_add_path_FILETYPE}) @@ -821,8 +831,8 @@ function(_sbom_add_path PATH) endif() if(DEFINED _arg_add_path_CHECKSUM) - set(_hash_algo "SHA1") # SHA1 is always required - set(_supported_algorithms "MD5;SHA224;SHA256;SHA384;SHA512;SHA3-256;SHA3-384;SHA3-512") + set(_hash_algo "SHA1;SHA256") # SHA1 is always required by SPDX, SHA256 required by TR-03183 + set(_supported_algorithms "MD5;SHA224;SHA384;SHA512;SHA3-256;SHA3-384;SHA3-512") foreach(_checksum ${_arg_add_path_CHECKSUM}) if("${_checksum}" IN_LIST _supported_algorithms) list(APPEND _hash_algo "${_checksum}") @@ -832,18 +842,8 @@ function(_sbom_add_path PATH) endforeach() endif() - set(_arg_add_path_LICENSE_CONCLUDED "NOASSERTION") - set(_arg_add_path_LICENSE_DECLARED "NOASSERTION") - if(DEFINED _arg_add_path_LICENSE) - _sbom_parse_license("CONCLUDED;${_arg_add_path_LICENSE}" _arg_add_path_LICENSE_CONCLUDED _arg_add_path_LICENSE_DECLARED _arg_add_path_LICENSE_COMMENT) - endif() - string(APPEND _fields "\nLicenseConcluded: ${_arg_add_path_LICENSE_CONCLUDED}") - if(DEFINED _arg_add_path_LICENSE_COMMENT) - string(APPEND _fields "\nLicenseComments: ${_arg_add_path_LICENSE_COMMENT}") - endif() - if(NOT DEFINED _arg_add_path_COPYRIGHT) - set(_arg_add_path_COPYRIGHT "NOASSERTION") + set(_arg_add_path_COPYRIGHT "NOASSERTION") #??? maybe use package copyright as default? endif() string(APPEND _fields "\nFileCopyrightText: ${_arg_add_path_COPYRIGHT}") @@ -1025,26 +1025,38 @@ function(sbom_add_package NAME) set(_fields "PackageName: ${NAME}\nSPDXID: ${_args_SPDXID}") - if(DEFINED _args_VERSION) - string(APPEND _fields "\nPackageVersion: ${_args_VERSION}") + set(_args_LICENSE_DECLARED "NOASSERTION") + if(NOT DEFINED _args_LICENSE) + message(FATAL_ERROR "Missing LICENSE argument for package ${NAME}.") + endif() + _sbom_parse_license("CONCLUDED;${_args_LICENSE}" _args_LICENSE_CONCLUDED _args_LICENSE_DECLARED _args_LICENSE_COMMENT) + string(APPEND _fields "\nPackageLicenseConcluded: ${_args_LICENSE_CONCLUDED}\nPackageLicenseDeclared: ${_args_LICENSE_DECLARED}") + if(DEFINED _args_LICENSE_COMMENT) + string(APPEND _fields "\nPackageLicenseComments: ${_args_LICENSE_COMMENT}") endif() - if(DEFINED _args_FILENAME) - string(APPEND _fields "\nPackageFileName: ${_args_FILENAME}") + if(NOT DEFINED _args_VERSION) + message(FATAL_ERROR "Missing VERSION argument for package ${NAME}.") endif() + string(APPEND _fields "\nPackageVersion: ${_args_VERSION}") - if(DEFINED _args_SUPPLIER) - set(_supplier_field_txt "") - _sbom_parse_package_supplier("${_args_SUPPLIER}" _args_SUPPLIER_TYPE _args_SUPPLIER_NAME _args_SUPPLIER_EMAIL) - if("${_args_SUPPLIER_TYPE}" STREQUAL "NOASSERTION") - set(_supplier_field_txt "PackageSupplier: NOASSERTION") - else() - set(_supplier_field_txt "PackageSupplier: ${_args_SUPPLIER_TYPE} ${_args_SUPPLIER_NAME}") - if(DEFINED _args_SUPPLIER_EMAIL) - set(_supplier_field_txt "${_supplier_field_txt} (${_args_SUPPLIER_EMAIL})") - endif() + if(NOT DEFINED _args_SUPPLIER) + message(FATAL_ERROR "Missing SUPPLIER argument for package ${NAME}.") + endif() + set(_supplier_field_txt "") + _sbom_parse_package_supplier("${_args_SUPPLIER}" _args_SUPPLIER_TYPE _args_SUPPLIER_NAME _args_SUPPLIER_EMAIL) + if("${_args_SUPPLIER_TYPE}" STREQUAL "NOASSERTION") + message(FATAL_ERROR "SUPPLIER must be a PERSON or ORGANIZATION.") + else() + set(_supplier_field_txt "PackageSupplier: ${_args_SUPPLIER_TYPE} ${_args_SUPPLIER_NAME}") + if(DEFINED _args_SUPPLIER_EMAIL) + set(_supplier_field_txt "${_supplier_field_txt} (${_args_SUPPLIER_EMAIL})") endif() - string(APPEND _fields "\n${_supplier_field_txt}") + endif() + string(APPEND _fields "\n${_supplier_field_txt}") + + if(DEFINED _args_FILENAME) + string(APPEND _fields "\nPackageFileName: ${_args_FILENAME}") endif() if(DEFINED _args_ORIGINATOR) @@ -1089,16 +1101,6 @@ function(sbom_add_package NAME) string(APPEND _fields "\nPackageSourceInfo: ${_args_URL}") endif() - set(_args_LICENSE_CONCLUDED "NOASSERTION") - set(_args_LICENSE_DECLARED "NOASSERTION") - if(DEFINED _args_LICENSE) - _sbom_parse_license("CONCLUDED;${_args_LICENSE}" _args_LICENSE_CONCLUDED _args_LICENSE_DECLARED _args_LICENSE_COMMENT) - endif() - string(APPEND _fields "\nPackageLicenseConcluded: ${_args_LICENSE_CONCLUDED}\nPackageLicenseDeclared: ${_args_LICENSE_DECLARED}") - if(DEFINED _args_LICENSE_COMMENT) - string(APPEND _fields "\nPackageLicenseComments: ${_args_LICENSE_COMMENT}") - endif() - if(NOT DEFINED _args_COPYRIGHT) set(_args_COPYRIGHT "NOASSERTION") endif() diff --git a/readme.md b/readme.md index f786f53..9dac868 100644 --- a/readme.md +++ b/readme.md @@ -1,17 +1,19 @@ # CMake SBOM Builder -This project provides a CMake module that helps your to generate Software Bill of Materials (SBOM) in `SPDX`-format for an arbitrary CMake project. +Generating SPDX Software Bill of Materials (SBOMs) for arbitrary CMake projects. -This Project only supports SPDX version 2.3. The SPDX specification is available [here](https://spdx.github.io/spdx-spec/v2.3/). +The CMake-SBOM-Builder aims to be compliant with: + +- [Technical Guideline TR-03183](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2.pdf?__blob=publicationFile&v=5) of the German Federal Office for Information Security (BSI) +- The US [Executive Order 14028](https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-security-supply-chains-software-1) +- [SPDX Specification 2.3](https://spdx.github.io/spdx-spec/v2.3/) It automates two tasks: - extracting version information from Git, and passing it to CMake, shell scripts, and C/C++ -- generating a SBOM in SPDX format, based on install artifacts - -The version extraction helps to get the version in the application and SBOM right. The SBOM contains the files you mention explicitly, just like you mention what to `install()` in CMake. +- generating a SBOM in SPDX format, based on install artifacts, and the package dependencies you specify -To integrate this library in your project, see [below](#how-to-use) for basic instructions or the example for a simple example project. +To get started, take a look at the [example](#example) and how to [add the SBOM-Builder to your project](#adding-sbom-builder-to-your-project). --- @@ -24,9 +26,10 @@ Major Changes include: - **Single-File Integration**: We condensed everything into a single file to facilitate integration with CMake's `file` command, making it simpler and more efficient to use. - **Multi Config Generator Enhancements**: The SBOM generation better integrates with multi-config generators like Visual Studio and Ninja Multi-Config. Different SBOM's are generated for each configuration. -- **Removed External Python Tools**: The verification process that relied on external Python tools has been removed to minimize dependencies and simplify the setup. - **Modernized CMake**: A higher minimum required version (>=3.16), ensuring better compatibility and taking advantage of newer functionalities. -- **Wider support for SPDX fields**: While the original project focused on the most important SPDX fields, to keep SBOM generation simple, we added support for more SPDX fields to provide more flexibility and customization, while maintaining the initial vision of auto-generating most fields. +- **Wider support for SPDX 2.3**: More SPDX fields are supported for better compliance with the SPDX 2.3 specification. +- **Compliance with BSI-Guidelines** +- **Improved Documentation** --- @@ -178,22 +181,22 @@ Generates the SBOM creator information and the package information of the packag ```cmake sbom_generate( - CREATOR [EMAIL ] - [OUTPUT ] - [NAMESPACE ] - [PACKAGE_NAME ] - [PACKAGE_VERSION ] - [PACKAGE_FILENAME ] - [PACKAGE_DOWNLOAD >] - [PACKAGE_URL >] - [PACKAGE_LICENSE >] - [PACKAGE_COPYRIGHT >] - [PACKAGE_NOTES [SUMMARY ] - [DESCRIPTION ] ] - [PACKAGE_PURPOSE ...] + CREATOR [EMAIL ] + PACKAGE_LICENSE + [PACKAGE_NAME ] + [PACKAGE_VERSION ] + [PACKAGE_FILENAME ] + [PACKAGE_DOWNLOAD >] + [PACKAGE_URL >]xg + [PACKAGE_COPYRIGHT >] + [PACKAGE_NOTES [SUMMARY ] + [DESCRIPTION ] ] + [PACKAGE_PURPOSE ...] + [OUTPUT ] + [NAMESPACE ] ) ``` @@ -207,13 +210,13 @@ sbom_generate( - ***Note:*** - The SPDX specification differentiates between the creator of the SBOM and the supplier of the package it describes. However, this project treats them as the same entity. This is based on the assumption that whoever uses this project, uses it to generate a SBOM for a package they are building. In this case, the creator of the SBOM and the supplier of the package are the same entity. - The SBOM-Builder is always added as an additional creator of the SBOM. -- `OUTPUT`: Output filename. - - Can be absolute or relative to `CMAKE_INSTALL_PREFIX`. - - Default location is `${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx`. - - `--prefix` option is honoured when added to the install command. - - `--prefix` and `${CMAKE_INSTALL_PREFIX}` have no effect when `OUTPUT` is an absolute path. -- `NAMESPACE`: Document namespace. - - If not specified, default to a URL based on `PACKAGE_URL`, `PACKAGE_NAME` and `PACKAGE_VERSION`. +- `PACKAGE_LICENSE`: License of the package described in the SBOM. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - ***Note:*** + - The SPDX specification differentiates between a declared and a concluded license. This argument sets both to the same value. + - We assume that the creator of the SBOM is the supplier of the package, there should be no difference between the declared and concluded license. + - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) & [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. + - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. - `PACKAGE_NAME`: Package name. - Defaults to `${PROJECT_NAME}`. - See [SPDX clause 7.1](https://spdx.github.io/spdx-spec/v2.3/package-information/#71-package-name-field) for more information. @@ -231,13 +234,6 @@ sbom_generate( - `NONE` or `NOASSERTION` require that `NAMESPACE` is provided. - otherwise `` is required. - See [SPDX clause 7.11](https://spdx.github.io/spdx-spec/v2.3/package-information/#711-package-home-page-field) for more information. -- `PACKAGE_LICENSE`: License of the package described in the SBOM. - - Requires one of `NOASSERTION`, `NONE`, or a valid SPDX license expression. - - If omitted, defaults to `NOASSERTION`. - - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) & [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. - - ***Note:*** - - The SPDX specification differentiates between a declared and a concluded license. This argument sets both to the same value. - - Assuming that the creator of the SBOM is the supplier of the package, there should be no difference between the declared and concluded license. - `PACKAGE_COPYRIGHT`: Copyright information. - Either `NOASSERTION`, `NONE`, or a ``. - Defaults to ` ` where `` is the `CREATOR` name. @@ -259,17 +255,24 @@ sbom_generate( - `sbom_generate(... PACKAGE_PURPOSE "APPLICATION" "FIRMWARE" ...)` - `sbom_generate(... PACKAGE_PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. +- `OUTPUT`: Output filename + path. + - Can be absolute or relative to `CMAKE_INSTALL_PREFIX`. + - Default location is `${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx`. + - `--prefix` option is honoured when added to the install command. + - `--prefix` and `${CMAKE_INSTALL_PREFIX}` have no effect when `OUTPUT` is an absolute path. +- `NAMESPACE`: Document namespace. + - If not specified, default to a URL based on `PACKAGE_URL`, `PACKAGE_NAME` and `PACKAGE_VERSION`. ### `sbom_add_file` ```cmake sbom_add_file( + LICENSE [COMMENT ] [SPDXID ] [RELATIONSHIP ] [FILETYPE ...] [CHECKSUM ...] - [LICENSE > [COMMENT ]] [COPYRIGHT >] [COMMENT ] [NOTICE ] @@ -281,6 +284,12 @@ sbom_add_file( - `filename`: A path to the file to add, relative to `CMAKE_INSTALL_PREFIX`. - Generator expressions are supported. - See [SPDX clause 8.1](https://spdx.github.io/spdx-spec/v2.3/file-information/#81-file-name-field) for more information. +- `LICENSE`: License of the file. + - See [SPDX clause 8.5](https://spdx.github.io/spdx-spec/v2.3/file-information/#85-concluded-license-field) for more information. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - No SBOM entry when omitted. + - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. - `SPDXID`: The ID to use for identifier generation. - If omitted generates a new one. - See [SPDX clause 8.2](https://spdx.github.io/spdx-spec/v2.3/file-information/#82-file-spdx-identifier-field) for more information. @@ -303,21 +312,14 @@ sbom_add_file( - `sbom_add_file(... FILETYPE "BINARY" ...)` - `sbom_add_file(... FILETYPE "ARCHIVE" ...)` - `CHECKSUM`: Checksums to be generated for the file. - - The SPDX-Specification requires a SHA1 checksum to be generated. This is always done automatically. + - SPDX and TR-03183 require a SHA1 and SHA256 respectively to be generated. This is always done automatically. - With this argument, additional checksums can be specified. - See [SPDX clause 8.4](https://spdx.github.io/spdx-spec/v2.3/file-information/#84-file-checksum-field) for more information. - One or many of the following keywords: - - `MD5`, `SHA224`, `SHA256`, `SHA384`, `SHA512`, `SHA3_256`, `SHA3_384`, `SHA3_512`. + - `MD5`, `SHA224`, `SHA384`, `SHA512`, `SHA3_256`, `SHA3_384`, `SHA3_512`. - These are the set of hash algorithms that CMake supports and are defined in the SPDX specification. - Usage: - - `sbom_add_file(... CHECKSUM SHA256 SHA3_512 ...)` -- `LICENSE`: License of the file. - - If omitted, defaults to `NOASSERTION`. - - See [SPDX clause 8.5](https://spdx.github.io/spdx-spec/v2.3/file-information/#85-concluded-license-field) for more information. - - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `LICENSE`. - - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. - - No SBOM entry when omitted. - - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. + - `sbom_add_file(... CHECKSUM MD5 SHA3_512 ...)` This would in total generate SHA1, SHA256, MD5, and SHA3_512 checksums. - `COPYRIGHT`: Copyright information. - When omitted defaults to `NOASSERTION`. - See [SPDX clause 8.8](https://spdx.github.io/spdx-spec/v2.3/file-information/#88-copyright-text-field) for more information. @@ -370,19 +372,19 @@ The supported options for `sbom_add_target` are the same as those for [`sbom_add ```cmake sbom_add_package( + LICENSE + [DECLARED > ] + [COMMENT ] + VERSION + SUPPLIER [EMAIL ] [SPDXID ] [RELATIONSHIP ] - [VERSION ] [FILENAME ] - [SUPPLIER [EMAIL ]] [ORIGINATOR [EMAIL ]] [DOWNLOAD >] [CHECKSUM < >...] [URL >] [SOURCE_INFO ] - [LICENSE > - [DECLARED > ] - [COMMENT ] ] [COPYRIGHT >] [NOTES [SUMMARY ] [DESC ] @@ -404,6 +406,32 @@ sbom_add_package( - Use the name that is given by the author or package manager. - The package files are not analysed further. - It is assumed that this package is a dependency of the project. +- `LICENSE`: License of the package described in the SBOM. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. + - This is the license that the creator of the SBOM concluded the package has, which may differ from the declared license of the package supplier. + - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) + - Add `DECLARED` to specify the declared license. + - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `DECLARED`. + - When omitted defaults to `NOASSERTION`. + - See [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. + - Add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - No SBOM entry when omitted. + - See [SPDX clause 7.16](https://spdx.github.io/spdx-spec/v2.3/package-information/#716-comments-on-license-field) for more information. + - SPDX recommends to use this field also when `NOASSERTION` is set. + - Usage: + - `sbom_add_package(... LICENSE "MIT" DECLARED "MIT" ...)` + - `sbom_add_package(... LICENSE "MIT" DECLARED NONE COMMENT "No package level license can be found. The files are licensed individually. All files are MIT licensed." ...)` +- `VERSION`: Package version field + - Required by the TR-03183. + - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. +- `SUPPLIER`: Supplier of the Package + - One of `` keywords must follow `SUPPLIER`. + - `EMAIL` is optional. + - Usage: + - `sbom_add_package(... SUPPLIER ORGANIZATION "Package Distributor" EMAIL "contact@email.com" ...)` + - `sbom_add_package(... SUPPLIER PERSON "Firstname Lastname" ...)` + - See [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. - `SPDXID`: The ID to use for identifier generation. (spdx clause 7.2) - By default, generate a new one. Whether or not this is specified, the variable `SBOM_LAST_SPDXID` is set to just generated/used SPDXID, which could be used for later relationship definitions. - `RELATIONSHIP`: A relationship definition related to this package. @@ -420,9 +448,6 @@ sbom_add_package( - This will ***replace*** the default relationship added, which is: `SPDXRef-${PACKAGE_NAME} DEPENDS_ON @SBOM_LAST_SPDXID@` - Only one relationship can be added. - The Relationship: `@SBOM_LAST_SPDXID@ CONTAINS NOASSERTION` is always added, which can cause confusion. -- `VERSION`: Package version field - - No SBOM entry when omitted. - - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. - `FILENAME`: Filename of the package. - No SBOM entry when omitted. - See [SPDX clause 7.4](https://spdx.github.io/spdx-spec/v2.3/package-information/#74-package-file-name-field) for more information. @@ -430,17 +455,6 @@ sbom_add_package( - Can include relative path from `CMAKE_INSTALL_PREFIX` if it part of your install artifacts. - Usage: - `sbom_add_package(... FILENAME "./lib/libmodbus.so" ...)` -- `SUPPLIER`: Supplier of the Package - - No SBOM entry when omitted. - - See [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. - - One of `` keywords must follow `SUPPLIER`. - - For `NOASSERTION`: `` and `EMAIL` are not used. - - `` is either a person or organization name. - - `EMAIL` is optional. - - Usage: - - `sbom_add_package(... SUPPLIER ORGANIZATION "Package Distributor" EMAIL "contact@email.com" ...)` - - `sbom_add_package(... SUPPLIER PERSON "Firstname Lastname" ...)` - - `sbom_add_package(... SUPPLIER NOASSERTION ...)` - `ORIGINATOR`: Originator of the Package - No SBOM entry when omitted. - See [SPDX clause 7.6](https://spdx.github.io/spdx-spec/v2.3/package-information/#76-package-originator-field) for more information. @@ -470,28 +484,6 @@ sbom_add_package( - `SOURCE_INFO`: Background information about the origin of the package. - No SBOM entry when omitted. - See [SPDX clause 7.12](https://spdx.github.io/spdx-spec/v2.3/package-information/#712-source-information-field) for more information. -- `LICENSE`: Concluded license of the package. - - When omitted defaults to `NOASSERTION`. - - This field is optional in the SPDX specification. - - If the field is not present in the SBOM, `NOASSERTION` is implied as per SPDX specification. - - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) for more information. - - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `LICENSE`. - - See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for valid expressions. - - The License expression is not verified by this project. - - This is the license that the creator of the SBOM concluded the package has, which may differ from the declared license of the package supplier. - - Add `DECLARED` to specify the declared license. - - When omitted defaults to `NOASSERTION`. - - Same reasoning as for the concluded license. - - See [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. - - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `DECLARED`. - - Add `COMMENT` to record any additional information that went in to arriving at the concluded license. - - No SBOM entry when omitted. - - See [SPDX clause 7.16](https://spdx.github.io/spdx-spec/v2.3/package-information/#716-comments-on-license-field) for more information. - - SPDX recommends to use this field also when `NOASSERTION` is set. - - Usage: - - `sbom_add_package(... LICENSE "MIT" DECLARED "MIT" ...)` - - `sbom_add_package(... LICENSE "MIT" DECLARED NONE COMMENT "No package level license can be found. The files are licensed individually. All files are MIT licensed." ...)` - - `sbom_add_package(... LICENSE NONE ...)` - `COPYRIGHT`: Copyright information. - When omitted defaults to `NOASSERTION`. - This field is optional in the SPDX specification. From 9b3009cf4a3c7058c2e0d7a403dc9f306b9d4dfb Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Thu, 12 Sep 2024 13:16:31 +0200 Subject: [PATCH 02/19] docs: update how-to-add-sbom.cmake in readme.md --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 9dac868..46e5a82 100644 --- a/readme.md +++ b/readme.md @@ -118,7 +118,7 @@ To download a specific version: file( DOWNLOAD https://github.com/sodgeit/CMake-SBOM-Builder/releases/download/v0.2.1/sbom.cmake - ${CMAKE_SOURCE_DIR}/cmake/sbom.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake EXPECTED_HASH SHA256=7b354f3a5976c4626c876850c93944e52c83ec59a159ae5de5be7983f0e17a2a ) ``` @@ -129,7 +129,7 @@ Or always download the latest release: file( DOWNLOAD https://github.com/sodgeit/CMake-SBOM-Builder/releases/latest/download/sbom.cmake - ${CMAKE_SOURCE_DIR}/cmake/sbom.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake EXPECTED_HASH SHA256=7b354f3a5976c4626c876850c93944e52c83ec59a159ae5de5be7983f0e17a2a ) ``` @@ -137,7 +137,7 @@ file( And then just include the file: ```cmake -include(cmake/sbom.cmake) +include(${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake) ``` ### Build and install your project From e4a1a8398551c1d96c64ab91f318be0cef0e542a Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Fri, 13 Sep 2024 14:29:13 +0200 Subject: [PATCH 03/19] docs: simplify function doc in readme Add a new file to document the full signature of the function. --- doc/full_signature.md | 330 ++++++++++++++++++++++++++++++++++++++++++ readme.md | 329 ++--------------------------------------- 2 files changed, 346 insertions(+), 313 deletions(-) create mode 100644 doc/full_signature.md diff --git a/doc/full_signature.md b/doc/full_signature.md new file mode 100644 index 0000000..cb4e5e3 --- /dev/null +++ b/doc/full_signature.md @@ -0,0 +1,330 @@ +# Full Function Signature + +- [sbom\_generate](#sbom_generate) +- [sbom\_add\_\[file|directory|target\]](#sbom_add_filedirectorytarget) +- [sbom\_add\_package](#sbom_add_package) + + +## sbom_generate + +```cmake +sbom_generate( + CREATOR [EMAIL ] + PACKAGE_LICENSE + [PACKAGE_NAME ] + [PACKAGE_VERSION ] + [PACKAGE_FILENAME ] + [PACKAGE_DOWNLOAD >] + [PACKAGE_URL >]xg + [PACKAGE_COPYRIGHT >] + [PACKAGE_NOTES [SUMMARY ] + [DESCRIPTION ] ] + [PACKAGE_PURPOSE ...] + [OUTPUT ] + [NAMESPACE ] +) +``` + +- `CREATOR`: Supplier of the Package and Creator of the sbom + - See [SPDX clause 6.8](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#68-creator-field) & [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. + - One of the `` keywords must be provided. + - `EMAIL` is optional. + - Usage: + - `sbom_generate(... CREATOR ORGANIZATION "My Company" EMAIL "contact@company.com" ...)` + - `sbom_generate(... CREATOR PERSON "Firstname Lastname" ...)` + - ***Note:*** + - The SPDX specification differentiates between the creator of the SBOM and the supplier of the package it describes. However, this project treats them as the same entity. This is based on the assumption that whoever uses this project, uses it to generate a SBOM for a package they are building. In this case, the creator of the SBOM and the supplier of the package are the same entity. + - The SBOM-Builder is always added as an additional creator of the SBOM. +- `PACKAGE_LICENSE`: License of the package described in the SBOM. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - ***Note:*** + - The SPDX specification differentiates between a declared and a concluded license. This argument sets both to the same value. + - We assume that the creator of the SBOM is the supplier of the package, there should be no difference between the declared and concluded license. + - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) & [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. + - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. +- `PACKAGE_NAME`: Package name. + - Defaults to `${PROJECT_NAME}`. + - See [SPDX clause 7.1](https://spdx.github.io/spdx-spec/v2.3/package-information/#71-package-name-field) for more information. +- `PACKAGE_VERSION`: Package version field + - Defaults to `${GIT_VERSION}`. (see [Version Extraction](#version-extraction)) + - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. +- `PACKAGE_FILENAME`: Filename of the distributed package. + - Defaults to `${PACKAGE_NAME}-${PACKAGE_VERSION}.zip`. + - See [SPDX clause 7.4](https://spdx.github.io/spdx-spec/v2.3/package-information/#74-package-file-name-field) for more information. +- `PACKAGE_DOWNLOAD`: Download location of the distributed package. + - Either `NOASSERTION`, `NONE`, or a ``. + - Defaults to `NOASSERTION`. + - See [SPDX clause 7.7](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) for more information. +- `PACKAGE_URL`: Package home page. + - `NONE` or `NOASSERTION` require that `NAMESPACE` is provided. + - otherwise `` is required. + - See [SPDX clause 7.11](https://spdx.github.io/spdx-spec/v2.3/package-information/#711-package-home-page-field) for more information. +- `PACKAGE_COPYRIGHT`: Copyright information. + - Either `NOASSERTION`, `NONE`, or a ``. + - Defaults to ` ` where `` is the `CREATOR` name. + - See [SPDX clause 7.17](https://spdx.github.io/spdx-spec/v2.3/package-information/#717-copyright-text-field) for more information. +- `PACKAGE_NOTES`: + - No SBOM entry when omitted. + - `SUMMARY`: A short description of the package. + - `DESC`: A detailed description of the package. + - Usage: + - `sbom_generate(... PACKAGE_NOTES SUMMARY "A short description" DESC "A detailed description" ...)` + - `sbom_generate(... PACKAGE_NOTES SUMMARY "A short description" ...)` + - `sbom_generate(... PACKAGE_NOTES DESC "A detailed description" ...)` + - See [SPDX clause 7.18](https://spdx.github.io/spdx-spec/v2.3/package-information/#718-package-summary-description-field) & [SPDX clause 7.19](https://spdx.github.io/spdx-spec/v2.3/package-information/#719-package-detailed-description-field) for more information. +- `PACKAGE_PURPOSE`: + - Optional. If omitted, no `PrimaryPackagePurpose` field is added to the SBOM. + - One or many of the following keywords: + - `APPLICATION`, `FRAMEWORK`, `LIBRARY`, `CONTAINER`, `OPERATING-SYSTEM`, `DEVICE`, `FIRMWARE`, `SOURCE`, `ARCHIVE`, `FILE`, `INSTALL`, `OTHER`. + - Usage: + - `sbom_generate(... PACKAGE_PURPOSE "APPLICATION" "FIRMWARE" ...)` + - `sbom_generate(... PACKAGE_PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` + - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. +- `OUTPUT`: Output filename + path. + - Can be absolute or relative to `CMAKE_INSTALL_PREFIX`. + - Default location is `${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx`. + - `--prefix` option is honoured when added to the install command. + - `--prefix` and `${CMAKE_INSTALL_PREFIX}` have no effect when `OUTPUT` is an absolute path. +- `NAMESPACE`: Document namespace. + - If not specified, default to a URL based on `PACKAGE_URL`, `PACKAGE_NAME` and `PACKAGE_VERSION`. + +## sbom_add_[file|directory|target] + +```cmake +sbom_add_[file|directory|target]( + + LICENSE [COMMENT ] + [SPDXID ] + [RELATIONSHIP ] + [FILETYPE ...] + [CHECKSUM ...] + [COPYRIGHT >] + [COMMENT ] + [NOTICE ] + [CONTRIBUTORS ...] + [ATTRIBUTION ...] +) +``` + +- `filename`: A path to the file to add, relative to `CMAKE_INSTALL_PREFIX`. + - Generator expressions are supported. + - See [SPDX clause 8.1](https://spdx.github.io/spdx-spec/v2.3/file-information/#81-file-name-field) for more information. +- `LICENSE`: License of the file. + - See [SPDX clause 8.5](https://spdx.github.io/spdx-spec/v2.3/file-information/#85-concluded-license-field) for more information. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - No SBOM entry when omitted. + - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. +- `SPDXID`: The ID to use for identifier generation. + - If omitted generates a new one. + - See [SPDX clause 8.2](https://spdx.github.io/spdx-spec/v2.3/file-information/#82-file-spdx-identifier-field) for more information. + - Whether or not this is specified, the variable `SBOM_LAST_SPDXID` is set to just generated/used SPDXID, which could be used for later relationship definitions. +- `RELATIONSHIP`: A relationship definition related to this file. + - If omitted a default relationship is added: `SPDXRef-${PACKAGE_NAME} CONTAINS @SBOM_LAST_SPDXID@` + - `${PACKAGE_NAME}` is the `PACKAGE_NAME` argument given to `sbom_generate()`. + - See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. + - The string `@SBOM_LAST_SPDXID@` will be replaced by the SPDXID that is used for this SBOM item. + - ***Limitation:*** + - This will ***replace*** the default relationship added. + - Only one relationship can be added. +- `FILETYPE`: One or more file types. + - If omitted, no SBOM entry is generated. + - See [SPDX clause 8.3](https://spdx.github.io/spdx-spec/v2.3/file-information/#83-file-type-field) for more information. + - One or many of the following keywords: + - `SOURCE`, `BINARY`, `ARCHIVE`, `APPLICATION`, `AUDIO`, `IMAGE`, `TEXT`, `VIDEO`, `DOCUMENTATION`, `SPDX`, `OTHER`. + - Usage: + - `sbom_add_file(... FILETYPE "SOURCE" "TEXT" ...)` + - `sbom_add_file(... FILETYPE "BINARY" ...)` + - `sbom_add_file(... FILETYPE "ARCHIVE" ...)` +- `CHECKSUM`: Checksums to be generated for the file. + - SPDX and TR-03183 require a SHA1 and SHA256 respectively to be generated. This is always done automatically. + - With this argument, additional checksums can be specified. + - See [SPDX clause 8.4](https://spdx.github.io/spdx-spec/v2.3/file-information/#84-file-checksum-field) for more information. + - One or many of the following keywords: + - `MD5`, `SHA224`, `SHA384`, `SHA512`, `SHA3_256`, `SHA3_384`, `SHA3_512`. + - These are the set of hash algorithms that CMake supports and are defined in the SPDX specification. + - Usage: + - `sbom_add_file(... CHECKSUM MD5 SHA3_512 ...)` This would in total generate SHA1, SHA256, MD5, and SHA3_512 checksums. +- `COPYRIGHT`: Copyright information. + - When omitted defaults to `NOASSERTION`. + - See [SPDX clause 8.8](https://spdx.github.io/spdx-spec/v2.3/file-information/#88-copyright-text-field) for more information. + - Either `NOASSERTION`, `NONE`, or a `` must follow `COPYRIGHT`. +- `COMMENT`: Additional comments about the file. + - No SBOM entry when omitted. + - See [SPDX clause 8.12](https://spdx.github.io/spdx-spec/v2.3/file-information/#812-file-comment-field) for more information. +- `NOTICE`: Notice text. + - No SBOM entry when omitted. + - See [SPDX clause 8.13](https://spdx.github.io/spdx-spec/v2.3/file-information/#813-file-notice-field) for more information. +- `CONTRIBUTORS`: Contributors to the file. + - No SBOM entry when omitted. + - See [SPDX clause 8.14](https://spdx.github.io/spdx-spec/v2.3/file-information/#814-file-contributor-field) for more information. +- `ATTRIBUTION`: Attribution text. + - No SBOM entry when omitted. + - See [SPDX clause 8.15](https://spdx.github.io/spdx-spec/v2.3/file-information/#815-file-attribution-text-field) for more information. + +## sbom_add_package + +```cmake +sbom_add_package( + + LICENSE + [DECLARED > ] + [COMMENT ] + VERSION + SUPPLIER [EMAIL ] + [SPDXID ] + [RELATIONSHIP ] + [FILENAME ] + [ORIGINATOR [EMAIL ]] + [DOWNLOAD >] + [CHECKSUM < >...] + [URL >] + [SOURCE_INFO ] + [COPYRIGHT >] + [NOTES [SUMMARY ] + [DESC ] + [COMMENT ] ] + [EXTREF < [COMMENT ]>...] + [ATTRIBUTION ...] + [PURPOSE ...] + [DATE [RELEASE ] + [BUILD ] + [VALID_UNTIL ] ] +) +``` + +- `name`: Name of the package to be added as a dependency to the SBOM. (spdx clause 7.1) + - Use the name that is given by the author or package manager. + - The package files are not analysed further. + - It is assumed that this package is a dependency of the project. +- `LICENSE`: License of the package described in the SBOM. + - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. + - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. + - This is the license that the creator of the SBOM concluded the package has, which may differ from the declared license of the package supplier. + - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) + - Add `DECLARED` to specify the declared license. + - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `DECLARED`. + - When omitted defaults to `NOASSERTION`. + - See [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. + - Add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - No SBOM entry when omitted. + - See [SPDX clause 7.16](https://spdx.github.io/spdx-spec/v2.3/package-information/#716-comments-on-license-field) for more information. + - SPDX recommends to use this field also when `NOASSERTION` is set. + - Usage: + - `sbom_add_package(... LICENSE "MIT" DECLARED "MIT" ...)` + - `sbom_add_package(... LICENSE "MIT" DECLARED NONE COMMENT "No package level license can be found. The files are licensed individually. All files are MIT licensed." ...)` +- `VERSION`: Package version field + - Required by the TR-03183. + - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. +- `SUPPLIER`: Supplier of the Package + - One of `` keywords must follow `SUPPLIER`. + - `EMAIL` is optional. + - Usage: + - `sbom_add_package(... SUPPLIER ORGANIZATION "Package Distributor" EMAIL "contact@email.com" ...)` + - `sbom_add_package(... SUPPLIER PERSON "Firstname Lastname" ...)` + - See [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. +- `SPDXID`: The ID to use for identifier generation. (spdx clause 7.2) + - By default, generate a new one. Whether or not this is specified, the variable `SBOM_LAST_SPDXID` is set to just generated/used SPDXID, which could be used for later relationship definitions. +- `RELATIONSHIP`: A relationship definition related to this package. + - If omitted a default relationship is added: `SPDXRef-${PACKAGE_NAME} DEPENDS_ON @SBOM_LAST_SPDXID@` + - `${PACKAGE_NAME}` is the `PACKAGE_NAME` argument given to `sbom_generate()`. + - See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. + - The string `@SBOM_LAST_SPDXID@` will be replaced by the SPDXID that is used for this SBOM item. + - Usage: + - `sbom_add_package( gtest ...)` + - `set(GTEST_SPDX_ID ${SBOM_LAST_SPDXID})` + - `sbom_add_package(... RELATIONSHIP "${GTEST_SPDX_ID} TEST_DEPENDENCY_OF @SBOM_LAST_SPDXID@" ...)` + - To get the spdx-id of another package, save `SBOM_LAST_SPDXID` in a different variable after calling `sbom_add_package(...)`. + - ***Limitation:*** + - This will ***replace*** the default relationship added, which is: `SPDXRef-${PACKAGE_NAME} DEPENDS_ON @SBOM_LAST_SPDXID@` + - Only one relationship can be added. + - The Relationship: `@SBOM_LAST_SPDXID@ CONTAINS NOASSERTION` is always added, which can cause confusion. +- `FILENAME`: Filename of the package. + - No SBOM entry when omitted. + - See [SPDX clause 7.4](https://spdx.github.io/spdx-spec/v2.3/package-information/#74-package-file-name-field) for more information. + - Filename of the package as it is distributed. + - Can include relative path from `CMAKE_INSTALL_PREFIX` if it part of your install artifacts. + - Usage: + - `sbom_add_package(... FILENAME "./lib/libmodbus.so" ...)` +- `ORIGINATOR`: Originator of the Package + - No SBOM entry when omitted. + - See [SPDX clause 7.6](https://spdx.github.io/spdx-spec/v2.3/package-information/#76-package-originator-field) for more information. + - Same options/keywords as `SUPPLIER`. + - The package may be acquired from a different source than the original creator of the package. + - Usage: + - `sbom_add_package(... ORIGINATOR ORGANIZATION "Package Creator" EMAIL "" ...)` + - `sbom_add_package(... ORIGINATOR NOASSERTION ...)` +- `DOWNLOAD`: Download location of the package. + - If omitted, defaults to `NOASSERTION`, as this field is required by SPDX. + - See [SPDX clause 7.7](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) for more information. + - One of `NOASSERTION`, `NONE`, or a `` must follow `DOWNLOAD`. + - ``: A URL or version control system location. +- `CHECKSUM`: Checksum of the package. + - No SBOM entry when omitted. + - See [SPDX clause 7.10](https://spdx.github.io/spdx-spec/v2.3/package-information/#710-package-checksum-field) for more information. + - For `` check CMakes supported [hash algorithms](https://cmake.org/cmake/help/latest/command/string.html#hash). + - We are bound to the hash algorithms that CMake supports, as we aren't doing anything with the checksums yet. In the future, we may add automatic checksum verification, etc. which would limit us to the algorithms CMake supports. + - Multiple checksums can be provided. + - Usage: + - `sbom_add_package(... CHECKSUM SHA256 "######" ...)` + - `sbom_add_package(... CHECKSUM SHA256 "######" SHA1 "######" ...)` +- `URL`: Package home page. + - No SBOM entry when omitted. + - See [SPDX clause 7.11](https://spdx.github.io/spdx-spec/v2.3/package-information/#711-package-home-page-field) for more information. + - Either `NOASSERTION`, `NONE`, or a `` must follow `URL`. +- `SOURCE_INFO`: Background information about the origin of the package. + - No SBOM entry when omitted. + - See [SPDX clause 7.12](https://spdx.github.io/spdx-spec/v2.3/package-information/#712-source-information-field) for more information. +- `COPYRIGHT`: Copyright information. + - When omitted defaults to `NOASSERTION`. + - This field is optional in the SPDX specification. + - If the field is not present in the SBOM, `NOASSERTION` is implied as per SPDX specification. + - See [SPDX clause 7.17](https://spdx.github.io/spdx-spec/v2.3/package-information/#717-copyright-text-field) for more information. + - Either `NOASSERTION`, `NONE`, or a `` must follow `COPYRIGHT`. +- `NOTES`: + - No SBOM entry when omitted. + - `SUMMARY`: A short description of the package. + - See [SPDX clause 7.18](https://spdx.github.io/spdx-spec/v2.3/package-information/#718-package-summary-description-field) for more information. + - `DESC`: A detailed description of the package. + - See [SPDX clause 7.19](https://spdx.github.io/spdx-spec/v2.3/package-information/#719-package-detailed-description-field) for more information. + - `COMMENT`: Additional comments about the package. + - See [SPDX clause 7.20](https://spdx.github.io/spdx-spec/v2.3/package-information/#720-package-comment-field) for more information. + - Usage: + - `sbom_generate(... NOTES SUMMARY "A canbus library" DESC "Provides function specified by $someStandard and is certified by ... ." COMMENT "This package came with it's own sbom. Which is appended to this sbom" ...)` +- `EXTREF`: External references, such as security or package manager information. + - No SBOM entry when omitted. + - Refer to [SPDX clause 7.21](https://spdx.github.io/spdx-spec/v2.3/package-information/#721-external-reference-field) for details. + - Add `COMMENT` to record any additional information about the external reference. + - No SBOM entry when omitted. + - Refer to [SPDX clause 7.22](https://spdx.github.io/spdx-spec/v2.3/package-information/#722-external-reference-comment-field) for details. +- `ATTRIBUTION`: Attribution text. + - No SBOM entry when omitted. + - See [SPDX clause 7.23](https://spdx.github.io/spdx-spec/v2.3/package-information/#723-package-attribution-text-field) for more information. + - Multiple strings can be provided and will be added as separate fields to the SBOM. + - Usage: + - `sbom_add_package(... ATTRIBUTION "text" "text2" ...)` +- `PURPOSE`: + - No SBOM entry when omitted. + - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. + - One or many of the following keywords: + - `APPLICATION`, `FRAMEWORK`, `LIBRARY`, `CONTAINER`, `OPERATING-SYSTEM`, `DEVICE`, `FIRMWARE`, `SOURCE`, `ARCHIVE`, `FILE`, `INSTALL`, `OTHER`. + - Usage: + - `sbom_generate(... PURPOSE "APPLICATION" "FIRMWARE" ...)` + - `sbom_generate(... PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` +- `DATE`: + - No SBOM entries when omitted. + - `RELEASE`: The date the package was released. + - See [SPDX clause 7.25](https://spdx.github.io/spdx-spec/v2.3/package-information/#725-release-date) for more information. + - `BUILD`: The date the package was built. + - See [SPDX clause 7.26](https://spdx.github.io/spdx-spec/v2.3/package-information/#726-built-date) for more information. + - `VALID_UNTIL`: End of support date. + - See [SPDX clause 7.27](https://spdx.github.io/spdx-spec/v2.3/package-information/#727-valid-until-date) for more information. + - ``: A date in the format `YYYY-MM-DDThh:mm:ssZ`. + - Usage: + - `sbom_add_package(... DATE RELEASE "2024-01-10T00:00:00Z" BUILD "2024-01-07T00:00:00Z" VALID_UNTIL "2029-01-10T00:00:00Z" ...)` diff --git a/readme.md b/readme.md index 46e5a82..a5f4f6b 100644 --- a/readme.md +++ b/readme.md @@ -41,9 +41,7 @@ Major Changes include: - [Build and install your project](#build-and-install-your-project) - [SBOM Generation](#sbom-generation) - [`sbom_generate`](#sbom_generate) - - [`sbom_add_file`](#sbom_add_file) - - [`sbom_add_directory`](#sbom_add_directory) - - [`sbom_add_target`](#sbom_add_target) + - [`sbom_add_[file|directory|target]`](#sbom_add_filedirectorytarget) - [`sbom_add_package`](#sbom_add_package) - [`sbom_add_external`](#sbom_add_external) - [`sbom_finalize`](#sbom_finalize) @@ -175,6 +173,9 @@ Per default the SBOM will be generated in `${CMAKE_INSTALL_PREFIX}/share/${PROJE `cmake/sbom.cmake` provides the following functions: +Here is a brief overview of the functions provided by the SBOM-Builder. Shown here is only a subset of the available arguments, which we consider the most important and most likely to be used. +For the entire function signature take a look [here](./doc/full_signature.md). + ### `sbom_generate` Generates the SBOM creator information and the package information of the package that the SBOM describes. @@ -185,187 +186,35 @@ sbom_generate( PACKAGE_LICENSE [PACKAGE_NAME ] [PACKAGE_VERSION ] - [PACKAGE_FILENAME ] - [PACKAGE_DOWNLOAD >] - [PACKAGE_URL >]xg [PACKAGE_COPYRIGHT >] - [PACKAGE_NOTES [SUMMARY ] - [DESCRIPTION ] ] - [PACKAGE_PURPOSE ...] - [OUTPUT ] - [NAMESPACE ] ) ``` - `CREATOR`: Supplier of the Package and Creator of the sbom - - See [SPDX clause 6.8](https://spdx.github.io/spdx-spec/v2.3/document-creation-information/#68-creator-field) & [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. - One of the `` keywords must be provided. - `EMAIL` is optional. - - Usage: - - `sbom_generate(... CREATOR ORGANIZATION "My Company" EMAIL "contact@company.com" ...)` - - `sbom_generate(... CREATOR PERSON "Firstname Lastname" ...)` - - ***Note:*** - - The SPDX specification differentiates between the creator of the SBOM and the supplier of the package it describes. However, this project treats them as the same entity. This is based on the assumption that whoever uses this project, uses it to generate a SBOM for a package they are building. In this case, the creator of the SBOM and the supplier of the package are the same entity. - - The SBOM-Builder is always added as an additional creator of the SBOM. - `PACKAGE_LICENSE`: License of the package described in the SBOM. - - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. - - ***Note:*** - - The SPDX specification differentiates between a declared and a concluded license. This argument sets both to the same value. - - We assume that the creator of the SBOM is the supplier of the package, there should be no difference between the declared and concluded license. - - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) & [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. - - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. - `PACKAGE_NAME`: Package name. - Defaults to `${PROJECT_NAME}`. - - See [SPDX clause 7.1](https://spdx.github.io/spdx-spec/v2.3/package-information/#71-package-name-field) for more information. - `PACKAGE_VERSION`: Package version field - Defaults to `${GIT_VERSION}`. (see [Version Extraction](#version-extraction)) - - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. -- `PACKAGE_FILENAME`: Filename of the distributed package. - - Defaults to `${PACKAGE_NAME}-${PACKAGE_VERSION}.zip`. - - See [SPDX clause 7.4](https://spdx.github.io/spdx-spec/v2.3/package-information/#74-package-file-name-field) for more information. -- `PACKAGE_DOWNLOAD`: Download location of the distributed package. - - Either `NOASSERTION`, `NONE`, or a ``. - - Defaults to `NOASSERTION`. - - See [SPDX clause 7.7](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) for more information. -- `PACKAGE_URL`: Package home page. - - `NONE` or `NOASSERTION` require that `NAMESPACE` is provided. - - otherwise `` is required. - - See [SPDX clause 7.11](https://spdx.github.io/spdx-spec/v2.3/package-information/#711-package-home-page-field) for more information. - `PACKAGE_COPYRIGHT`: Copyright information. - - Either `NOASSERTION`, `NONE`, or a ``. - Defaults to ` ` where `` is the `CREATOR` name. - - See [SPDX clause 7.17](https://spdx.github.io/spdx-spec/v2.3/package-information/#717-copyright-text-field) for more information. -- `PACKAGE_NOTES`: - - No SBOM entry when omitted. - - `SUMMARY`: A short description of the package. - - `DESC`: A detailed description of the package. - - Usage: - - `sbom_generate(... PACKAGE_NOTES SUMMARY "A short description" DESC "A detailed description" ...)` - - `sbom_generate(... PACKAGE_NOTES SUMMARY "A short description" ...)` - - `sbom_generate(... PACKAGE_NOTES DESC "A detailed description" ...)` - - See [SPDX clause 7.18](https://spdx.github.io/spdx-spec/v2.3/package-information/#718-package-summary-description-field) & [SPDX clause 7.19](https://spdx.github.io/spdx-spec/v2.3/package-information/#719-package-detailed-description-field) for more information. -- `PACKAGE_PURPOSE`: - - Optional. If omitted, no `PrimaryPackagePurpose` field is added to the SBOM. - - One or many of the following keywords: - - `APPLICATION`, `FRAMEWORK`, `LIBRARY`, `CONTAINER`, `OPERATING-SYSTEM`, `DEVICE`, `FIRMWARE`, `SOURCE`, `ARCHIVE`, `FILE`, `INSTALL`, `OTHER`. - - Usage: - - `sbom_generate(... PACKAGE_PURPOSE "APPLICATION" "FIRMWARE" ...)` - - `sbom_generate(... PACKAGE_PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` - - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. -- `OUTPUT`: Output filename + path. - - Can be absolute or relative to `CMAKE_INSTALL_PREFIX`. - - Default location is `${CMAKE_INSTALL_PREFIX}/share/${PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx`. - - `--prefix` option is honoured when added to the install command. - - `--prefix` and `${CMAKE_INSTALL_PREFIX}` have no effect when `OUTPUT` is an absolute path. -- `NAMESPACE`: Document namespace. - - If not specified, default to a URL based on `PACKAGE_URL`, `PACKAGE_NAME` and `PACKAGE_VERSION`. - -### `sbom_add_file` + +### `sbom_add_[file|directory|target]` ```cmake -sbom_add_file( - +sbom_add_[file|directory|target]( + LICENSE [COMMENT ] - [SPDXID ] - [RELATIONSHIP ] - [FILETYPE ...] - [CHECKSUM ...] - [COPYRIGHT >] - [COMMENT ] - [NOTICE ] - [CONTRIBUTORS ...] - [ATTRIBUTION ...] ) ``` -- `filename`: A path to the file to add, relative to `CMAKE_INSTALL_PREFIX`. +- `filename|path|target`: + - A path to a file/directory, relative to `CMAKE_INSTALL_PREFIX`, or a target name, to be added to the SBOM. Target have to be installed using `install(TARGETS ...)`. - Generator expressions are supported. - - See [SPDX clause 8.1](https://spdx.github.io/spdx-spec/v2.3/file-information/#81-file-name-field) for more information. - `LICENSE`: License of the file. - - See [SPDX clause 8.5](https://spdx.github.io/spdx-spec/v2.3/file-information/#85-concluded-license-field) for more information. - - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. - - No SBOM entry when omitted. - - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. -- `SPDXID`: The ID to use for identifier generation. - - If omitted generates a new one. - - See [SPDX clause 8.2](https://spdx.github.io/spdx-spec/v2.3/file-information/#82-file-spdx-identifier-field) for more information. - - Whether or not this is specified, the variable `SBOM_LAST_SPDXID` is set to just generated/used SPDXID, which could be used for later relationship definitions. -- `RELATIONSHIP`: A relationship definition related to this file. - - If omitted a default relationship is added: `SPDXRef-${PACKAGE_NAME} CONTAINS @SBOM_LAST_SPDXID@` - - `${PACKAGE_NAME}` is the `PACKAGE_NAME` argument given to `sbom_generate()`. - - See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. - - The string `@SBOM_LAST_SPDXID@` will be replaced by the SPDXID that is used for this SBOM item. - - ***Limitation:*** - - This will ***replace*** the default relationship added. - - Only one relationship can be added. -- `FILETYPE`: One or more file types. - - If omitted, no SBOM entry is generated. - - See [SPDX clause 8.3](https://spdx.github.io/spdx-spec/v2.3/file-information/#83-file-type-field) for more information. - - One or many of the following keywords: - - `SOURCE`, `BINARY`, `ARCHIVE`, `APPLICATION`, `AUDIO`, `IMAGE`, `TEXT`, `VIDEO`, `DOCUMENTATION`, `SPDX`, `OTHER`. - - Usage: - - `sbom_add_file(... FILETYPE "SOURCE" "TEXT" ...)` - - `sbom_add_file(... FILETYPE "BINARY" ...)` - - `sbom_add_file(... FILETYPE "ARCHIVE" ...)` -- `CHECKSUM`: Checksums to be generated for the file. - - SPDX and TR-03183 require a SHA1 and SHA256 respectively to be generated. This is always done automatically. - - With this argument, additional checksums can be specified. - - See [SPDX clause 8.4](https://spdx.github.io/spdx-spec/v2.3/file-information/#84-file-checksum-field) for more information. - - One or many of the following keywords: - - `MD5`, `SHA224`, `SHA384`, `SHA512`, `SHA3_256`, `SHA3_384`, `SHA3_512`. - - These are the set of hash algorithms that CMake supports and are defined in the SPDX specification. - - Usage: - - `sbom_add_file(... CHECKSUM MD5 SHA3_512 ...)` This would in total generate SHA1, SHA256, MD5, and SHA3_512 checksums. -- `COPYRIGHT`: Copyright information. - - When omitted defaults to `NOASSERTION`. - - See [SPDX clause 8.8](https://spdx.github.io/spdx-spec/v2.3/file-information/#88-copyright-text-field) for more information. - - Either `NOASSERTION`, `NONE`, or a `` must follow `COPYRIGHT`. -- `COMMENT`: Additional comments about the file. - - No SBOM entry when omitted. - - See [SPDX clause 8.12](https://spdx.github.io/spdx-spec/v2.3/file-information/#812-file-comment-field) for more information. -- `NOTICE`: Notice text. - - No SBOM entry when omitted. - - See [SPDX clause 8.13](https://spdx.github.io/spdx-spec/v2.3/file-information/#813-file-notice-field) for more information. -- `CONTRIBUTORS`: Contributors to the file. - - No SBOM entry when omitted. - - See [SPDX clause 8.14](https://spdx.github.io/spdx-spec/v2.3/file-information/#814-file-contributor-field) for more information. -- `ATTRIBUTION`: Attribution text. - - No SBOM entry when omitted. - - See [SPDX clause 8.15](https://spdx.github.io/spdx-spec/v2.3/file-information/#815-file-attribution-text-field) for more information. - -2 specializations of this function are provided. - -#### `sbom_add_directory` - -```cmake -sbom_add_directory( - - ... -) -``` - -- `path`: A path to the directory, relative to `CMAKE_INSTALL_PREFIX`, for which all files are to be added to the SBOM recursively. - - Generator expressions are supported. - -The supported options for `sbom_add_directory` are the same as those for [`sbom_add_file`](#sbom_add_file). - -#### `sbom_add_target` - -```cmake -sbom_add_target( - - ... -) -``` - -- `name`: Corresponds to the logical target name. - - It is required that the binaries are installed under `CMAKE_INSTALL_BINDIR`. - -The supported options for `sbom_add_target` are the same as those for [`sbom_add_file`](#sbom_add_file), with the exception of `FILETYPE`. The `FILETYPE` argument is set to BINARY. ### `sbom_add_package` @@ -373,164 +222,18 @@ The supported options for `sbom_add_target` are the same as those for [`sbom_add sbom_add_package( LICENSE - [DECLARED > ] - [COMMENT ] VERSION SUPPLIER [EMAIL ] - [SPDXID ] - [RELATIONSHIP ] - [FILENAME ] - [ORIGINATOR [EMAIL ]] - [DOWNLOAD >] - [CHECKSUM < >...] - [URL >] - [SOURCE_INFO ] - [COPYRIGHT >] - [NOTES [SUMMARY ] - [DESC ] - [COMMENT ] ] - [EXTREF < [COMMENT ]>...] - [ATTRIBUTION ...] - [PURPOSE ...] - [DATE [RELEASE ] - [BUILD ] - [VALID_UNTIL ] ] - + ... ) ``` -- `name`: Name of the package to be added as a dependency to the SBOM. (spdx clause 7.1) - - Use the name that is given by the author or package manager. - - The package files are not analysed further. - - It is assumed that this package is a dependency of the project. -- `LICENSE`: License of the package described in the SBOM. - - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. - - The federal guidelines mentioned above do not explicitly allow the use of `NOASSERTION` or `NONE`. We therefore do not provide these options. - - This is the license that the creator of the SBOM concluded the package has, which may differ from the declared license of the package supplier. - - See [SPDX clause 7.13](https://spdx.github.io/spdx-spec/v2.3/package-information/#713-concluded-license-field) - - Add `DECLARED` to specify the declared license. - - Either `NOASSERTION`, `NONE`, or a valid SPDX license expression must follow `DECLARED`. - - When omitted defaults to `NOASSERTION`. - - See [SPDX clause 7.15](https://spdx.github.io/spdx-spec/v2.3/package-information/#715-declared-license-field) for more information. - - Add `COMMENT` to record any additional information that went in to arriving at the concluded license. - - No SBOM entry when omitted. - - See [SPDX clause 7.16](https://spdx.github.io/spdx-spec/v2.3/package-information/#716-comments-on-license-field) for more information. - - SPDX recommends to use this field also when `NOASSERTION` is set. - - Usage: - - `sbom_add_package(... LICENSE "MIT" DECLARED "MIT" ...)` - - `sbom_add_package(... LICENSE "MIT" DECLARED NONE COMMENT "No package level license can be found. The files are licensed individually. All files are MIT licensed." ...)` -- `VERSION`: Package version field - - Required by the TR-03183. - - See [SPDX clause 7.3](https://spdx.github.io/spdx-spec/v2.3/package-information/#73-package-version-field) for more information. -- `SUPPLIER`: Supplier of the Package - - One of `` keywords must follow `SUPPLIER`. +- `name`: The name of the package. +- `LICENSE`: License of the package. +- `VERSION`: Version of the package. +- `SUPPLIER`: Supplier of the package. + - One of the `` keywords must be provided. - `EMAIL` is optional. - - Usage: - - `sbom_add_package(... SUPPLIER ORGANIZATION "Package Distributor" EMAIL "contact@email.com" ...)` - - `sbom_add_package(... SUPPLIER PERSON "Firstname Lastname" ...)` - - See [SPDX clause 7.5](https://spdx.github.io/spdx-spec/v2.3/package-information/#75-package-supplier-field) for more information. -- `SPDXID`: The ID to use for identifier generation. (spdx clause 7.2) - - By default, generate a new one. Whether or not this is specified, the variable `SBOM_LAST_SPDXID` is set to just generated/used SPDXID, which could be used for later relationship definitions. -- `RELATIONSHIP`: A relationship definition related to this package. - - If omitted a default relationship is added: `SPDXRef-${PACKAGE_NAME} DEPENDS_ON @SBOM_LAST_SPDXID@` - - `${PACKAGE_NAME}` is the `PACKAGE_NAME` argument given to `sbom_generate()`. - - See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. - - The string `@SBOM_LAST_SPDXID@` will be replaced by the SPDXID that is used for this SBOM item. - - Usage: - - `sbom_add_package( gtest ...)` - - `set(GTEST_SPDX_ID ${SBOM_LAST_SPDXID})` - - `sbom_add_package(... RELATIONSHIP "${GTEST_SPDX_ID} TEST_DEPENDENCY_OF @SBOM_LAST_SPDXID@" ...)` - - To get the spdx-id of another package, save `SBOM_LAST_SPDXID` in a different variable after calling `sbom_add_package(...)`. - - ***Limitation:*** - - This will ***replace*** the default relationship added, which is: `SPDXRef-${PACKAGE_NAME} DEPENDS_ON @SBOM_LAST_SPDXID@` - - Only one relationship can be added. - - The Relationship: `@SBOM_LAST_SPDXID@ CONTAINS NOASSERTION` is always added, which can cause confusion. -- `FILENAME`: Filename of the package. - - No SBOM entry when omitted. - - See [SPDX clause 7.4](https://spdx.github.io/spdx-spec/v2.3/package-information/#74-package-file-name-field) for more information. - - Filename of the package as it is distributed. - - Can include relative path from `CMAKE_INSTALL_PREFIX` if it part of your install artifacts. - - Usage: - - `sbom_add_package(... FILENAME "./lib/libmodbus.so" ...)` -- `ORIGINATOR`: Originator of the Package - - No SBOM entry when omitted. - - See [SPDX clause 7.6](https://spdx.github.io/spdx-spec/v2.3/package-information/#76-package-originator-field) for more information. - - Same options/keywords as `SUPPLIER`. - - The package may be acquired from a different source than the original creator of the package. - - Usage: - - `sbom_add_package(... ORIGINATOR ORGANIZATION "Package Creator" EMAIL "" ...)` - - `sbom_add_package(... ORIGINATOR NOASSERTION ...)` -- `DOWNLOAD`: Download location of the package. - - If omitted, defaults to `NOASSERTION`, as this field is required by SPDX. - - See [SPDX clause 7.7](https://spdx.github.io/spdx-spec/v2.3/package-information/#77-package-download-location-field) for more information. - - One of `NOASSERTION`, `NONE`, or a `` must follow `DOWNLOAD`. - - ``: A URL or version control system location. -- `CHECKSUM`: Checksum of the package. - - No SBOM entry when omitted. - - See [SPDX clause 7.10](https://spdx.github.io/spdx-spec/v2.3/package-information/#710-package-checksum-field) for more information. - - For `` check CMakes supported [hash algorithms](https://cmake.org/cmake/help/latest/command/string.html#hash). - - We are bound to the hash algorithms that CMake supports, as we aren't doing anything with the checksums yet. In the future, we may add automatic checksum verification, etc. which would limit us to the algorithms CMake supports. - - Multiple checksums can be provided. - - Usage: - - `sbom_add_package(... CHECKSUM SHA256 "######" ...)` - - `sbom_add_package(... CHECKSUM SHA256 "######" SHA1 "######" ...)` -- `URL`: Package home page. - - No SBOM entry when omitted. - - See [SPDX clause 7.11](https://spdx.github.io/spdx-spec/v2.3/package-information/#711-package-home-page-field) for more information. - - Either `NOASSERTION`, `NONE`, or a `` must follow `URL`. -- `SOURCE_INFO`: Background information about the origin of the package. - - No SBOM entry when omitted. - - See [SPDX clause 7.12](https://spdx.github.io/spdx-spec/v2.3/package-information/#712-source-information-field) for more information. -- `COPYRIGHT`: Copyright information. - - When omitted defaults to `NOASSERTION`. - - This field is optional in the SPDX specification. - - If the field is not present in the SBOM, `NOASSERTION` is implied as per SPDX specification. - - See [SPDX clause 7.17](https://spdx.github.io/spdx-spec/v2.3/package-information/#717-copyright-text-field) for more information. - - Either `NOASSERTION`, `NONE`, or a `` must follow `COPYRIGHT`. -- `NOTES`: - - No SBOM entry when omitted. - - `SUMMARY`: A short description of the package. - - See [SPDX clause 7.18](https://spdx.github.io/spdx-spec/v2.3/package-information/#718-package-summary-description-field) for more information. - - `DESC`: A detailed description of the package. - - See [SPDX clause 7.19](https://spdx.github.io/spdx-spec/v2.3/package-information/#719-package-detailed-description-field) for more information. - - `COMMENT`: Additional comments about the package. - - See [SPDX clause 7.20](https://spdx.github.io/spdx-spec/v2.3/package-information/#720-package-comment-field) for more information. - - Usage: - - `sbom_generate(... NOTES SUMMARY "A canbus library" DESC "Provides function specified by $someStandard and is certified by ... ." COMMENT "This package came with it's own sbom. Which is appended to this sbom" ...)` -- `EXTREF`: External references, such as security or package manager information. - - No SBOM entry when omitted. - - Refer to [SPDX clause 7.21](https://spdx.github.io/spdx-spec/v2.3/package-information/#721-external-reference-field) for details. - - Add `COMMENT` to record any additional information about the external reference. - - No SBOM entry when omitted. - - Refer to [SPDX clause 7.22](https://spdx.github.io/spdx-spec/v2.3/package-information/#722-external-reference-comment-field) for details. -- `ATTRIBUTION`: Attribution text. - - No SBOM entry when omitted. - - See [SPDX clause 7.23](https://spdx.github.io/spdx-spec/v2.3/package-information/#723-package-attribution-text-field) for more information. - - Multiple strings can be provided and will be added as separate fields to the SBOM. - - Usage: - - `sbom_add_package(... ATTRIBUTION "text" "text2" ...)` -- `PURPOSE`: - - No SBOM entry when omitted. - - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. - - One or many of the following keywords: - - `APPLICATION`, `FRAMEWORK`, `LIBRARY`, `CONTAINER`, `OPERATING-SYSTEM`, `DEVICE`, `FIRMWARE`, `SOURCE`, `ARCHIVE`, `FILE`, `INSTALL`, `OTHER`. - - Usage: - - `sbom_generate(... PURPOSE "APPLICATION" "FIRMWARE" ...)` - - `sbom_generate(... PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` -- `DATE`: - - No SBOM entries when omitted. - - `RELEASE`: The date the package was released. - - See [SPDX clause 7.25](https://spdx.github.io/spdx-spec/v2.3/package-information/#725-release-date) for more information. - - `BUILD`: The date the package was built. - - See [SPDX clause 7.26](https://spdx.github.io/spdx-spec/v2.3/package-information/#726-built-date) for more information. - - `VALID_UNTIL`: End of support date. - - See [SPDX clause 7.27](https://spdx.github.io/spdx-spec/v2.3/package-information/#727-valid-until-date) for more information. - - ``: A date in the format `YYYY-MM-DDThh:mm:ssZ`. - - Usage: - - `sbom_add_package(... DATE RELEASE "2024-01-10T00:00:00Z" BUILD "2024-01-07T00:00:00Z" VALID_UNTIL "2029-01-10T00:00:00Z" ...)` ### `sbom_add_external` From ad8e98c25e95640e03efe2ae52f0a123c1ccc097 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 16:08:03 +0200 Subject: [PATCH 04/19] docs: simpler how-to-use instructions and what the sbom contains --- readme.md | 124 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/readme.md b/readme.md index a5f4f6b..29e0df2 100644 --- a/readme.md +++ b/readme.md @@ -8,10 +8,8 @@ The CMake-SBOM-Builder aims to be compliant with: - The US [Executive Order 14028](https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-security-supply-chains-software-1) - [SPDX Specification 2.3](https://spdx.github.io/spdx-spec/v2.3/) -It automates two tasks: - -- extracting version information from Git, and passing it to CMake, shell scripts, and C/C++ -- generating a SBOM in SPDX format, based on install artifacts, and the package dependencies you specify +The SBOM-Builder is designed to seamlessly be integrated into your CMake project. It generates a single SBOM for your project, based on the files you install and the package dependencies you specify. +It also comes with a version extraction feature, to generate version information from your Git repository and make it available in your CMake files, your C/C++ code via a cmake target, and in your shell environment via a script. To get started, take a look at the [example](#example) and how to [add the SBOM-Builder to your project](#adding-sbom-builder-to-your-project). @@ -36,10 +34,11 @@ Major Changes include: **Contents** - [How to use](#how-to-use) - - [Example](#example) - [Adding SBOM-Builder to your project](#adding-sbom-builder-to-your-project) + - [Steps to generate an SBOM](#steps-to-generate-an-sbom) - [Build and install your project](#build-and-install-your-project) -- [SBOM Generation](#sbom-generation) + - [Example](#example) +- [Available Functions and Arguments](#available-functions-and-arguments) - [`sbom_generate`](#sbom_generate) - [`sbom_add_[file|directory|target]`](#sbom_add_filedirectorytarget) - [`sbom_add_package`](#sbom_add_package) @@ -57,55 +56,6 @@ Major Changes include: ## How to use -A SBOM is generated for one project, and describes the output of that project as a **single** package, which may contain files and other package dependencies. -All files shall be installed under `CMAKE_INSTALL_PREFIX`. The package dependencies are all black boxes; their files are not specified or analysed. - -### Example - -```cmake -cmake_minimum_required(VERSION 3.16) -project(Example) - -include(cmake/sbom.cmake) - -sbom_generate( - SUPPLIER ORGANIZATION "sodgeIT" - PACKAGE_LICENSE "MIT" -) - -sbom_add_package(Boost - VERSION 1.88 - SUPPLIER ORGANIZATION "Boost Foundation" - LICENSE "BSL-1.0" -) -sbom_add_package(cxxopts - VERSION 3.2.0 - SUPPLIER PERSON "Jarryd Beck" - LICENSE "MIT" -) - -add_library(example_lib SHARED) -target_sources(example_lib PRIVATE - source1.c - source2.cpp - header1.h -) -target_link_libraries(example_lib PUBLIC Boost::algorithm) - -add_executable(cli main.cpp) -target_link_libraries(cli PRIVATE example_lib cxxopts) - -install(TARGETS cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(TARGETS example_lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(FILE header1.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - -sbom_add_target(cli) -sbom_add_target(example_lib) -sbom_add_file(${CMAKE_INSTALL_INCLUDEDIR}/header1.h LICENSE "MIT") - -sbom_finalize() -``` - ### Adding SBOM-Builder to your project There are a variety of way's to do this. We recommend to use CMake directly to keep things simple. @@ -138,6 +88,16 @@ And then just include the file: include(${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake) ``` +### Steps to generate an SBOM + +1. Use `sbom_generate()` to define the SBOM creator and provide general information about the package you build. The assumption is that your CMake project produces a single package. + +2. With `sbom_add_file()`, `sbom_add_directory()`, or `sbom_add_target()` you can declare the contents of the package. These should cover all files, executables, libraries, etc. that are part of the distribution and are installed using CMake's `install()` command. + +3. `sbom_add_package()` is used to define dependencies for the package as a whole. For single-file dependencies, use the `RELATIONSHIP` argument to override the default behaviour. All dependencies are treated as black boxes, meaning their internal contents are not specified or analysed further. + +4. Finally, call `sbom_finalize()` to finish the SBOM definition. + ### Build and install your project Using single config generators (Makefiles, Ninja): @@ -167,19 +127,63 @@ Per default the SBOM will be generated in `${CMAKE_INSTALL_PREFIX}/share/${PROJE -- Finalizing: .../build/install/share/example-sbom-0.2.1.spdx ``` ---- +### Example -## SBOM Generation +```cmake +cmake_minimum_required(VERSION 3.16) +project(Example) + +include(cmake/sbom.cmake) + +sbom_generate( + SUPPLIER ORGANIZATION "sodgeIT" + PACKAGE_NAME "Example" + PACKAGE_VERSION "1.0.0" + PACKAGE_LICENSE "MIT" +) -`cmake/sbom.cmake` provides the following functions: +sbom_add_package(Boost + VERSION 1.88 + SUPPLIER ORGANIZATION "Boost Foundation" + LICENSE "BSL-1.0" +) +sbom_add_package(cxxopts + VERSION 3.2.0 + SUPPLIER PERSON "Jarryd Beck" + LICENSE "MIT" +) + +add_library(example_lib SHARED) +target_sources(example_lib PRIVATE + source1.c + source2.cpp + header1.h +) +target_link_libraries(example_lib PUBLIC Boost::algorithm) + +add_executable(cli main.cpp) +target_link_libraries(cli PRIVATE example_lib cxxopts) + +install(TARGETS cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS example_lib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILE header1.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +sbom_add_target(cli) +sbom_add_target(example_lib) +sbom_add_file(${CMAKE_INSTALL_INCLUDEDIR}/header1.h LICENSE "MIT") + +sbom_finalize() +``` + +--- + +## Available Functions and Arguments Here is a brief overview of the functions provided by the SBOM-Builder. Shown here is only a subset of the available arguments, which we consider the most important and most likely to be used. For the entire function signature take a look [here](./doc/full_signature.md). ### `sbom_generate` -Generates the SBOM creator information and the package information of the package that the SBOM describes. - ```cmake sbom_generate( CREATOR [EMAIL ] From d487bb00b1f2faebed815c55e21407b2c205febc Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 16:14:07 +0200 Subject: [PATCH 05/19] docs: fix typo --- doc/full_signature.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/full_signature.md b/doc/full_signature.md index cb4e5e3..90d3a7b 100644 --- a/doc/full_signature.md +++ b/doc/full_signature.md @@ -15,7 +15,7 @@ sbom_generate( [PACKAGE_VERSION ] [PACKAGE_FILENAME ] [PACKAGE_DOWNLOAD >] - [PACKAGE_URL >]xg + [PACKAGE_URL >] [PACKAGE_COPYRIGHT >] [PACKAGE_NOTES [SUMMARY ] [DESCRIPTION ] ] From 0c70b114ce04936ebda5de2a80f64f7743dc7055 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 16:43:54 +0200 Subject: [PATCH 06/19] docs: add Relationship argument to readme.md --- readme.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/readme.md b/readme.md index 29e0df2..4bb709a 100644 --- a/readme.md +++ b/readme.md @@ -211,6 +211,8 @@ sbom_generate( sbom_add_[file|directory|target]( LICENSE [COMMENT ] + [RELATIONSHIP ] + [COPYRIGHT >] ) ``` @@ -219,6 +221,11 @@ sbom_add_[file|directory|target]( - Generator expressions are supported. - `LICENSE`: License of the file. - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. +- `RELATIONSHIP`: + - Defaults to `${Project} CONTAINS ` + - Use this argument to override the default relationship. See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. +- `COPYRIGHT`: + - Defaults to NOASSERTION. ### `sbom_add_package` @@ -228,6 +235,7 @@ sbom_add_package( LICENSE VERSION SUPPLIER [EMAIL ] + [RELATIONSHIP ] ... ) ``` @@ -238,6 +246,8 @@ sbom_add_package( - `SUPPLIER`: Supplier of the package. - One of the `` keywords must be provided. - `EMAIL` is optional. +- `RELATIONSHIP`: Defaults to `${Project} DEPENDS_ON `. + - Use this argument to override the default relationship. See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. ### `sbom_add_external` @@ -255,6 +265,7 @@ sbom_add_external( - `path`: Reference to another SDPX file as External document reference. Then, depend on the package named in that document. The external SDPX file is copied next to the SBOM. Generator expressions are supported. - `RENAME`: Rename the external document to the given filename, without directories. - `SPDXID`: The identifier of the external document, which is used as prefix for the package identifier. Defaults to a unique identifier. The package identifier is added automatically. The variable `SBOM_LAST_SPDXID` is set to the used identifier. +- `RELATIONSHIP`: Defaults to `${Project} DEPENDS_ON ` ### `sbom_finalize` From 0014aa443edd0f44a163872fd1652b065865ba80 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 17:12:57 +0200 Subject: [PATCH 07/19] refactor: infer license and copyright from package definition only for sbom_add_file, sbom_add_directory and sbom_add_target functions --- cmake/sbom.cmake | 18 +++++++++++------- doc/full_signature.md | 14 ++++++++------ readme.md | 15 ++++++++++----- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index e6152f5..a91eaa4 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -687,7 +687,9 @@ function(sbom_generate) set_property(GLOBAL PROPERTY SBOM_FILENAME "${SBOM_GENERATE_OUTPUT}") set_property(GLOBAL PROPERTY SBOM_BINARY_DIR "${SBOM_BINARY_DIR}") set_property(GLOBAL PROPERTY SBOM_SNIPPET_DIR "${SBOM_SNIPPET_DIR}") - set_property(GLOBAL PROPERTY sbom_project "${SBOM_GENERATE_PACKAGE_NAME}") + set_property(GLOBAL PROPERTY sbom_package_spdxid "${SBOM_GENERATE_PACKAGE_NAME}") + set_property(GLOBAL PROPERTY sbom_package_license "${SBOM_GENERATE_PACKAGE_LICENSE}") + set_property(GLOBAL PROPERTY sbom_package_copyright "${SBOM_GENERATE_PACKAGE_COPYRIGHT}") set_property(GLOBAL PROPERTY sbom_spdxids 0) #REFAC(>=3.20): Use cmake_path() instead of get_filename_component(). @@ -743,7 +745,7 @@ function(sbom_finalize) get_property(_sbom GLOBAL PROPERTY SBOM_FILENAME) get_property(_sbom_binary_dir GLOBAL PROPERTY SBOM_BINARY_DIR) get_property(_sbom_snippet_dir GLOBAL PROPERTY SBOM_SNIPPET_DIR) - get_property(_sbom_project GLOBAL PROPERTY sbom_project) + get_property(_sbom_project GLOBAL PROPERTY sbom_package_spdxid) if("${_sbom_project}" STREQUAL "") message(FATAL_ERROR "Call sbom_generate() first") @@ -773,11 +775,11 @@ configure_file(\"\${SBOM_INTERMEDIATE_FILE}\" \"\${SBOM_EXPORT_FILENAME}\") # Mark finalized. set(SBOM_FILENAME "${_sbom}" PARENT_SCOPE) - set_property(GLOBAL PROPERTY sbom_project "") + set_property(GLOBAL PROPERTY sbom_package_spdxid "") endfunction() macro(_sbom_builder_is_setup) - get_property(_sbom_project GLOBAL PROPERTY sbom_project) + get_property(_sbom_project GLOBAL PROPERTY sbom_package_spdxid) if("${_sbom_project}" STREQUAL "") message(FATAL_ERROR "Call sbom_generate() first") @@ -814,8 +816,9 @@ function(_sbom_add_path PATH) set(_fields "") set(_arg_add_path_LICENSE_DECLARED "NOASSERTION") - if(NOT DEFINED _arg_add_path_LICENSE) #??? maybe use package license as default? - message(FATAL_ERROR "Missing LICENSE argument for ${PATH}.") + if(NOT DEFINED _arg_add_path_LICENSE) + get_property(_sbom_package_license GLOBAL PROPERTY sbom_package_license) + set(_arg_add_path_LICENSE "${_sbom_package_license}") endif() _sbom_parse_license("CONCLUDED;${_arg_add_path_LICENSE}" _arg_add_path_LICENSE_CONCLUDED _arg_add_path_LICENSE_DECLARED _arg_add_path_LICENSE_COMMENT) string(APPEND _fields "\nLicenseConcluded: ${_arg_add_path_LICENSE_CONCLUDED}") @@ -843,7 +846,8 @@ function(_sbom_add_path PATH) endif() if(NOT DEFINED _arg_add_path_COPYRIGHT) - set(_arg_add_path_COPYRIGHT "NOASSERTION") #??? maybe use package copyright as default? + get_property(_sbom_package_copyright GLOBAL PROPERTY sbom_package_copyright) + set(_arg_add_path_COPYRIGHT "${_sbom_package_copyright}") endif() string(APPEND _fields "\nFileCopyrightText: ${_arg_add_path_COPYRIGHT}") diff --git a/doc/full_signature.md b/doc/full_signature.md index 90d3a7b..88cec16 100644 --- a/doc/full_signature.md +++ b/doc/full_signature.md @@ -96,7 +96,7 @@ sbom_generate( ```cmake sbom_add_[file|directory|target]( - LICENSE [COMMENT ] + [LICENSE [COMMENT ]] [SPDXID ] [RELATIONSHIP ] [FILETYPE ...] @@ -113,11 +113,12 @@ sbom_add_[file|directory|target]( - Generator expressions are supported. - See [SPDX clause 8.1](https://spdx.github.io/spdx-spec/v2.3/file-information/#81-file-name-field) for more information. - `LICENSE`: License of the file. + - Defaults to the license of the package. (`PACKAGE_LICENSE` from `sbom_generate()`) - See [SPDX clause 8.5](https://spdx.github.io/spdx-spec/v2.3/file-information/#85-concluded-license-field) for more information. - Requires a valid SPDX license expression. See [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) for more information. - - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. - - No SBOM entry when omitted. - - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. + - If you are adding a target or file from one of your dependencies, specify their license. + - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - See [SPDX clause 8.7](https://spdx.github.io/spdx-spec/v2.3/file-information/#87-comments-on-license-field) for more information. - `SPDXID`: The ID to use for identifier generation. - If omitted generates a new one. - See [SPDX clause 8.2](https://spdx.github.io/spdx-spec/v2.3/file-information/#82-file-spdx-identifier-field) for more information. @@ -149,9 +150,10 @@ sbom_add_[file|directory|target]( - Usage: - `sbom_add_file(... CHECKSUM MD5 SHA3_512 ...)` This would in total generate SHA1, SHA256, MD5, and SHA3_512 checksums. - `COPYRIGHT`: Copyright information. - - When omitted defaults to `NOASSERTION`. + - Defaults to the copyright of the package. (`PACKAGE_COPYRIGHT` from `sbom_generate()`) - See [SPDX clause 8.8](https://spdx.github.io/spdx-spec/v2.3/file-information/#88-copyright-text-field) for more information. - - Either `NOASSERTION`, `NONE`, or a `` must follow `COPYRIGHT`. + - If you are adding a target or file from one of your dependencies, specify their copyright text. + - Use `NOASSERTION` or `NONE` if the information cannot be determined or is not specified. - `COMMENT`: Additional comments about the file. - No SBOM entry when omitted. - See [SPDX clause 8.12](https://spdx.github.io/spdx-spec/v2.3/file-information/#812-file-comment-field) for more information. diff --git a/readme.md b/readme.md index 4bb709a..e9372c7 100644 --- a/readme.md +++ b/readme.md @@ -210,9 +210,9 @@ sbom_generate( ```cmake sbom_add_[file|directory|target]( - LICENSE [COMMENT ] - [RELATIONSHIP ] + [LICENSE ] [COPYRIGHT >] + [RELATIONSHIP ] ) ``` @@ -220,12 +220,16 @@ sbom_add_[file|directory|target]( - A path to a file/directory, relative to `CMAKE_INSTALL_PREFIX`, or a target name, to be added to the SBOM. Target have to be installed using `install(TARGETS ...)`. - Generator expressions are supported. - `LICENSE`: License of the file. - - Optionally, add `COMMENT` to record any additional information that went in to arriving at the concluded license. + - Defaults to the license of the package. (`PACKAGE_LICENSE` from `sbom_generate()`) + - If you are adding a target or file from one of your dependencies, specify their license. + - Check the full signature for more information in such cases. +- `COPYRIGHT`: + - Defaults to the copyright of the package. (`PACKAGE_COPYRIGHT` from `sbom_generate()`) + - If you are adding a target or file from one of your dependencies, specify thier copyright text. + - Use `NOASSERTION` or `NONE` if the information cannot be determined or is not specified. - `RELATIONSHIP`: - Defaults to `${Project} CONTAINS ` - Use this argument to override the default relationship. See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. -- `COPYRIGHT`: - - Defaults to NOASSERTION. ### `sbom_add_package` @@ -242,6 +246,7 @@ sbom_add_package( - `name`: The name of the package. - `LICENSE`: License of the package. + - Check the full signature for more information, if the license is not specified, cannot be determined, or contains exceptions. - `VERSION`: Version of the package. - `SUPPLIER`: Supplier of the package. - One of the `` keywords must be provided. From ec9208e5d41a6e5d5473ce2411c1722091ba3bc1 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 17:35:01 +0200 Subject: [PATCH 08/19] style: rename internal function to better reflect its purpose in sbom generation --- cmake/sbom.cmake | 87 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index a91eaa4..5a70196 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -786,8 +786,7 @@ macro(_sbom_builder_is_setup) endif() endmacro() -# Append a file to the SBOM. Use this after calling sbom_generate(). -function(_sbom_add_path PATH) +function(_sbom_add_pkg_content PATH) set(options OPTIONAL FILE DIR) set(oneValueArgs SPDXID RELATIONSHIP @@ -798,45 +797,45 @@ function(_sbom_add_path PATH) ATTRIBUTION ) set(multiValueArgs FILETYPE CHECKSUM LICENSE) - cmake_parse_arguments(_arg_add_path "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments(_arg_add_pkg_content "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) _sbom_builder_is_setup() - if(_arg_add_path_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown arguments: ${_arg_add_path_UNPARSED_ARGUMENTS}") + if(_arg_add_pkg_content_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments: ${_arg_add_pkg_content_UNPARSED_ARGUMENTS}") endif() sbom_spdxid( - VARIABLE _arg_add_path_SPDXID - CHECK "${_arg_add_path_SPDXID}" + VARIABLE _arg_add_pkg_content_SPDXID + CHECK "${_arg_add_pkg_content_SPDXID}" HINTS "SPDXRef-${PATH}" ) - set(SBOM_LAST_SPDXID "${_arg_add_path_SPDXID}" PARENT_SCOPE) + set(SBOM_LAST_SPDXID "${_arg_add_pkg_content_SPDXID}" PARENT_SCOPE) set(_fields "") - set(_arg_add_path_LICENSE_DECLARED "NOASSERTION") - if(NOT DEFINED _arg_add_path_LICENSE) + set(_arg_add_pkg_content_LICENSE_DECLARED "NOASSERTION") + if(NOT DEFINED _arg_add_pkg_content_LICENSE) get_property(_sbom_package_license GLOBAL PROPERTY sbom_package_license) - set(_arg_add_path_LICENSE "${_sbom_package_license}") + set(_arg_add_pkg_content_LICENSE "${_sbom_package_license}") endif() - _sbom_parse_license("CONCLUDED;${_arg_add_path_LICENSE}" _arg_add_path_LICENSE_CONCLUDED _arg_add_path_LICENSE_DECLARED _arg_add_path_LICENSE_COMMENT) - string(APPEND _fields "\nLicenseConcluded: ${_arg_add_path_LICENSE_CONCLUDED}") - if(DEFINED _arg_add_path_LICENSE_COMMENT) - string(APPEND _fields "\nLicenseComments: ${_arg_add_path_LICENSE_COMMENT}") + _sbom_parse_license("CONCLUDED;${_arg_add_pkg_content_LICENSE}" _arg_add_pkg_content_LICENSE_CONCLUDED _arg_add_pkg_content_LICENSE_DECLARED _arg_add_pkg_content_LICENSE_COMMENT) + string(APPEND _fields "\nLicenseConcluded: ${_arg_add_pkg_content_LICENSE_CONCLUDED}") + if(DEFINED _arg_add_pkg_content_LICENSE_COMMENT) + string(APPEND _fields "\nLicenseComments: ${_arg_add_pkg_content_LICENSE_COMMENT}") endif() - if(DEFINED _arg_add_path_FILETYPE) - _sbom_parse_filetype("${_arg_add_path_FILETYPE}" _arg_add_path_FILETYPE) - foreach(_filetype ${_arg_add_path_FILETYPE}) + if(DEFINED _arg_add_pkg_content_FILETYPE) + _sbom_parse_filetype("${_arg_add_pkg_content_FILETYPE}" _arg_add_pkg_content_FILETYPE) + foreach(_filetype ${_arg_add_pkg_content_FILETYPE}) string(APPEND _fields "\nFileType: ${_filetype}") endforeach() endif() - if(DEFINED _arg_add_path_CHECKSUM) + if(DEFINED _arg_add_pkg_content_CHECKSUM) set(_hash_algo "SHA1;SHA256") # SHA1 is always required by SPDX, SHA256 required by TR-03183 set(_supported_algorithms "MD5;SHA224;SHA384;SHA512;SHA3-256;SHA3-384;SHA3-512") - foreach(_checksum ${_arg_add_path_CHECKSUM}) + foreach(_checksum ${_arg_add_pkg_content_CHECKSUM}) if("${_checksum}" IN_LIST _supported_algorithms) list(APPEND _hash_algo "${_checksum}") else() @@ -845,50 +844,50 @@ function(_sbom_add_path PATH) endforeach() endif() - if(NOT DEFINED _arg_add_path_COPYRIGHT) + if(NOT DEFINED _arg_add_pkg_content_COPYRIGHT) get_property(_sbom_package_copyright GLOBAL PROPERTY sbom_package_copyright) - set(_arg_add_path_COPYRIGHT "${_sbom_package_copyright}") + set(_arg_add_pkg_content_COPYRIGHT "${_sbom_package_copyright}") endif() - string(APPEND _fields "\nFileCopyrightText: ${_arg_add_path_COPYRIGHT}") + string(APPEND _fields "\nFileCopyrightText: ${_arg_add_pkg_content_COPYRIGHT}") - if(DEFINED _arg_add_path_COMMENT) - string(APPEND _fields "\nComment: ${_arg_add_path_COMMENT}") + if(DEFINED _arg_add_pkg_content_COMMENT) + string(APPEND _fields "\nComment: ${_arg_add_pkg_content_COMMENT}") endif() - if(DEFINED _arg_add_path_NOTICE) - string(APPEND _fields "\nFileNotice: ${_arg_add_path_NOTICE}") + if(DEFINED _arg_add_pkg_content_NOTICE) + string(APPEND _fields "\nFileNotice: ${_arg_add_pkg_content_NOTICE}") endif() - if(DEFINED _arg_add_path_CONTRIBUTORS) - foreach(_contributor ${_arg_add_path_CONTRIBUTORS}) + if(DEFINED _arg_add_pkg_content_CONTRIBUTORS) + foreach(_contributor ${_arg_add_pkg_content_CONTRIBUTORS}) string(APPEND _fields "\nFileContributor: ${_contributor}") endforeach() endif() - if(DEFINED _arg_add_path_ATTRIBUTION) - foreach(_attribution ${_arg_add_path_ATTRIBUTION}) + if(DEFINED _arg_add_pkg_content_ATTRIBUTION) + foreach(_attribution ${_arg_add_pkg_content_ATTRIBUTION}) string(APPEND _fields "\nFileAttributionText: ${_attribution}") endforeach() endif() - if(NOT DEFINED _arg_add_path_RELATIONSHIP) - set(_arg_add_path_RELATIONSHIP "SPDXRef-${_sbom_project} CONTAINS ${_arg_add_path_SPDXID}") + if(NOT DEFINED _arg_add_pkg_content_RELATIONSHIP) + set(_arg_add_pkg_content_RELATIONSHIP "SPDXRef-${_sbom_project} CONTAINS ${_arg_add_pkg_content_SPDXID}") else() - string(REPLACE "@SBOM_LAST_SPDXID@" "${_arg_add_path_SPDXID}" _arg_add_path_RELATIONSHIP "${_arg_add_path_RELATIONSHIP}") + string(REPLACE "@SBOM_LAST_SPDXID@" "${_arg_add_pkg_content_SPDXID}" _arg_add_pkg_content_RELATIONSHIP "${_arg_add_pkg_content_RELATIONSHIP}") endif() get_property(_sbom_snippet_dir GLOBAL PROPERTY SBOM_SNIPPET_DIR) - _sbom_append_sbom_snippet("${_arg_add_path_SPDXID}.cmake") + _sbom_append_sbom_snippet("${_arg_add_pkg_content_SPDXID}.cmake") file( GENERATE - OUTPUT ${_sbom_snippet_dir}/${_arg_add_path_SPDXID}.cmake + OUTPUT ${_sbom_snippet_dir}/${_arg_add_pkg_content_SPDXID}.cmake CONTENT " cmake_policy(SET CMP0011 NEW) cmake_policy(SET CMP0012 NEW) -set(ADDING_DIR ${_arg_add_path_DIR}) +set(ADDING_DIR ${_arg_add_pkg_content_DIR}) set(_files \"\") if(NOT ADDING_DIR) @@ -901,17 +900,17 @@ else() endif() if((NOT ADDING_DIR) AND (NOT EXISTS \${CMAKE_INSTALL_PREFIX}/${PATH})) - if(NOT ${_arg_add_path_OPTIONAL}) + if(NOT ${_arg_add_pkg_content_OPTIONAL}) message(FATAL_ERROR \"Cannot find ./${PATH}\") endif() else() set(_count 0) - set(_rel \"${_arg_add_path_RELATIONSHIP}\") - set(_id \"${_arg_add_path_SPDXID}\") + set(_rel \"${_arg_add_pkg_content_RELATIONSHIP}\") + set(_id \"${_arg_add_pkg_content_SPDXID}\") foreach(_f IN LISTS _files) if(ADDING_DIR) - set(_rel \"${_arg_add_path_RELATIONSHIP}-\${_count}\") - set(_id \"${_arg_add_path_SPDXID}-\${_count}\") + set(_rel \"${_arg_add_pkg_content_RELATIONSHIP}-\${_count}\") + set(_id \"${_arg_add_pkg_content_SPDXID}-\${_count}\") math(EXPR _count \"\${_count} + 1\") endif() set(_checksum_fields \"\") @@ -940,12 +939,12 @@ endif() endfunction() function(sbom_add_directory DIR_PATH) - _sbom_add_path("${DIR_PATH}" "DIR" "${ARGN}") + _sbom_add_pkg_content("${DIR_PATH}" "DIR" "${ARGN}") set(SBOM_LAST_SPDXID "${SBOM_LAST_SPDXID}" PARENT_SCOPE) endfunction() function(sbom_add_file FILENAME) - _sbom_add_path("${FILENAME}" "${ARGN}") + _sbom_add_pkg_content("${FILENAME}" "${ARGN}") set(SBOM_LAST_SPDXID "${SBOM_LAST_SPDXID}" PARENT_SCOPE) endfunction() From b272a4219daa9c89987c06e03e34056723d7d737 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Mon, 16 Sep 2024 17:36:26 +0200 Subject: [PATCH 09/19] docs: example showing usage of RELATIONSHIP argument --- readme.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index e9372c7..3d073fc 100644 --- a/readme.md +++ b/readme.md @@ -94,7 +94,7 @@ include(${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake) 2. With `sbom_add_file()`, `sbom_add_directory()`, or `sbom_add_target()` you can declare the contents of the package. These should cover all files, executables, libraries, etc. that are part of the distribution and are installed using CMake's `install()` command. -3. `sbom_add_package()` is used to define dependencies for the package as a whole. For single-file dependencies, use the `RELATIONSHIP` argument to override the default behaviour. All dependencies are treated as black boxes, meaning their internal contents are not specified or analysed further. +3. `sbom_add_package()` is used to define dependencies for your package as a whole. For single-file dependencies, use the `RELATIONSHIP` argument to override the default behaviour. All dependencies are treated as black boxes, meaning their internal contents are not specified or analysed further. 4. Finally, call `sbom_finalize()` to finish the SBOM definition. @@ -228,7 +228,8 @@ sbom_add_[file|directory|target]( - If you are adding a target or file from one of your dependencies, specify thier copyright text. - Use `NOASSERTION` or `NONE` if the information cannot be determined or is not specified. - `RELATIONSHIP`: - - Defaults to `${Project} CONTAINS ` + - Defaults to ` CONTAINS ` + - `` and ``are placeholders for the SPDX identifiers that are automatically generated. - Use this argument to override the default relationship. See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. ### `sbom_add_package` @@ -251,8 +252,18 @@ sbom_add_package( - `SUPPLIER`: Supplier of the package. - One of the `` keywords must be provided. - `EMAIL` is optional. -- `RELATIONSHIP`: Defaults to `${Project} DEPENDS_ON `. +- `RELATIONSHIP`: + - Defaults to ` DEPENDS_ON `. + - `` and ``are placeholders for the SPDX identifiers that are automatically generated. - Use this argument to override the default relationship. See [SPDX clause 11](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/) for more information. + - Eg: In the example above, the dependency `cxxopts` is only used by the `cli` and not the entire package. The relationship can be overridden as follows: + ```cmake + sbom_add_target(cli) + set(cli_spdxid ${SBOM_LAST_SPDXID}) + sbom_add_package(cxxopts ... RELATIONSHIP "${cli_spdxid} DEPENDS_ON @SBOM_LAST_SPDXID@" ) + ``` + - - `${SBOM_LAST_SPDXID}` is set to the SPDX identifier of the last added file/package/target. + - `@SBOM_LAST_SPDXID@` is a placeholder for the SPDX identifier that will be generated for `cxxopts`. ### `sbom_add_external` From 4f8931cd530c645516cb24de8aafb98fc9e55a71 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 10:23:28 +0200 Subject: [PATCH 10/19] refactor: change argument parsing to prevent name collisions --- cmake/sbom.cmake | 354 +++++++++++++++++++++++------------------------ 1 file changed, 177 insertions(+), 177 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 5a70196..323e79b 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -329,41 +329,41 @@ macro(_sbom_generate_document_template) set(_pkg_supplier_field "") set(_pkg_copyright_field "") - if(DEFINED SBOM_GENERATE_CREATOR_PERSON) - set(_pkg_creator_name "${SBOM_GENERATE_CREATOR_PERSON}") + if(DEFINED _arg_sbom_gen_CREATOR_PERSON) + set(_pkg_creator_name "${_arg_sbom_gen_CREATOR_PERSON}") set(_pkg_creator_field "Creator: Person: ${_pkg_creator_name}") set(_pkg_supplier_field "PackageSupplier: Person: ${_pkg_creator_name}") - elseif(DEFINED SBOM_GENERATE_CREATOR_ORGANIZATION) - set(_pkg_creator_name "${SBOM_GENERATE_CREATOR_ORGANIZATION}") + elseif(DEFINED _arg_sbom_gen_CREATOR_ORGANIZATION) + set(_pkg_creator_name "${_arg_sbom_gen_CREATOR_ORGANIZATION}") set(_pkg_creator_field "Creator: Organization: ${_pkg_creator_name}") set(_pkg_supplier_field "PackageSupplier: Organization: ${_pkg_creator_name}") endif() - if(DEFINED SBOM_GENERATE_CREATOR_EMAIL) - set(_pkg_creator_field "${_pkg_creator_field} (${SBOM_GENERATE_CREATOR_EMAIL})") - set(_pkg_supplier_field "${_pkg_supplier_field} (${SBOM_GENERATE_CREATOR_EMAIL})") + if(DEFINED _arg_sbom_gen_CREATOR_EMAIL) + set(_pkg_creator_field "${_pkg_creator_field} (${_arg_sbom_gen_CREATOR_EMAIL})") + set(_pkg_supplier_field "${_pkg_supplier_field} (${_arg_sbom_gen_CREATOR_EMAIL})") endif() - if(DEFINED SBOM_GENERATE_PACKAGE_COPYRIGHT) - set(_pkg_copyright_field "PackageCopyrightText: ${SBOM_GENERATE_PACKAGE_COPYRIGHT}") + if(DEFINED _arg_sbom_gen_PACKAGE_COPYRIGHT) + set(_pkg_copyright_field "PackageCopyrightText: ${_arg_sbom_gen_PACKAGE_COPYRIGHT}") endif() set(_pkg_summary_field FALSE) set(_pkg_desc_field FALSE) - if(DEFINED SBOM_GENERATE_PACKAGE_SUMMARY) + if(DEFINED _arg_sbom_gen_PACKAGE_SUMMARY) set(_pkg_summary_field TRUE) - set(_pkg_summary_field_txt "PackageSummary: ${SBOM_GENERATE_PACKAGE_SUMMARY}") + set(_pkg_summary_field_txt "PackageSummary: ${_arg_sbom_gen_PACKAGE_SUMMARY}") endif() - if(DEFINED SBOM_GENERATE_PACKAGE_DESC) + if(DEFINED _arg_sbom_gen_PACKAGE_DESC) set(_pkg_desc_field TRUE) - set(_pkg_desc_field_txt "PackageDescription: ${SBOM_GENERATE_PACKAGE_DESC}") + set(_pkg_desc_field_txt "PackageDescription: ${_arg_sbom_gen_PACKAGE_DESC}") endif() set(_pkg_purpose_fields FALSE) - if(DEFINED SBOM_GENERATE_PACKAGE_PURPOSE) + if(DEFINED _arg_sbom_gen_PACKAGE_PURPOSE) set(_pkg_purpose_fields TRUE) set(_pkg_purpose_field_txt "") - foreach(_purpose IN LISTS SBOM_GENERATE_PACKAGE_PURPOSE) + foreach(_purpose IN LISTS _arg_sbom_gen_PACKAGE_PURPOSE) set(_pkg_purpose_field_txt "${_pkg_purpose_field_txt}\nPrimaryPackagePurpose: ${_purpose}") endforeach() endif() @@ -376,7 +376,7 @@ macro(_sbom_generate_document_template) DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: ${doc_name} -DocumentNamespace: ${SBOM_GENERATE_NAMESPACE}\ +DocumentNamespace: ${_arg_sbom_gen_NAMESPACE}\ $<$:\n${_pkg_creator_field}> Creator: Tool: CMake-SBOM-Builder-${SBOM_BUILDER_VERSION} CreatorComment: This SPDX document was created from CMake ${CMAKE_VERSION}, using CMake-SBOM-Builder from https://github.com/sodgeit/CMake-SBOM-Builder @@ -394,21 +394,21 @@ FilesAnalyzed: false PackageSummary: The compiler as identified by CMake, running on ${CMAKE_HOST_SYSTEM_NAME} (${CMAKE_HOST_SYSTEM_PROCESSOR}) PrimaryPackagePurpose: APPLICATION Relationship: SPDXRef-compiler CONTAINS NOASSERTION -Relationship: SPDXRef-compiler BUILD_DEPENDENCY_OF SPDXRef-${SBOM_GENERATE_PACKAGE_NAME} -RelationshipComment: SPDXRef-${SBOM_GENERATE_PACKAGE_NAME} is built by compiler ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION} +Relationship: SPDXRef-compiler BUILD_DEPENDENCY_OF SPDXRef-${_arg_sbom_gen_PACKAGE_NAME} +RelationshipComment: SPDXRef-${_arg_sbom_gen_PACKAGE_NAME} is built by compiler ${CMAKE_CXX_COMPILER_ID} (${CMAKE_CXX_COMPILER}) version ${CMAKE_CXX_COMPILER_VERSION} -PackageName: ${SBOM_GENERATE_PACKAGE_NAME} -SPDXID: SPDXRef-${SBOM_GENERATE_PACKAGE_NAME} +PackageName: ${_arg_sbom_gen_PACKAGE_NAME} +SPDXID: SPDXRef-${_arg_sbom_gen_PACKAGE_NAME} ExternalRef: SECURITY cpe23Type ${SBOM_CPE} -ExternalRef: PACKAGE-MANAGER purl pkg:supplier/${_pkg_creator_name}/${SBOM_GENERATE_PACKAGE_NAME}@${SBOM_GENERATE_PACKAGE_VERSION} -PackageVersion: ${SBOM_GENERATE_PACKAGE_VERSION} -PackageFileName: ${SBOM_GENERATE_PACKAGE_FILENAME}\ +ExternalRef: PACKAGE-MANAGER purl pkg:supplier/${_pkg_creator_name}/${_arg_sbom_gen_PACKAGE_NAME}@${_arg_sbom_gen_PACKAGE_VERSION} +PackageVersion: ${_arg_sbom_gen_PACKAGE_VERSION} +PackageFileName: ${_arg_sbom_gen_PACKAGE_FILENAME}\ $<$:\n${_pkg_supplier_field}> -PackageDownloadLocation: ${SBOM_GENERATE_PACKAGE_DOWNLOAD} -PackageLicenseConcluded: ${SBOM_GENERATE_PACKAGE_LICENSE} -PackageLicenseDeclared: ${SBOM_GENERATE_PACKAGE_LICENSE}\ +PackageDownloadLocation: ${_arg_sbom_gen_PACKAGE_DOWNLOAD} +PackageLicenseConcluded: ${_arg_sbom_gen_PACKAGE_LICENSE} +PackageLicenseDeclared: ${_arg_sbom_gen_PACKAGE_LICENSE}\ $<$:\n${_pkg_copyright_field}> -PackageHomePage: ${SBOM_GENERATE_PACKAGE_URL}\ +PackageHomePage: ${_arg_sbom_gen_PACKAGE_URL}\ $<$:\n${_pkg_summary_field_txt}>\ $<$:\n${_pkg_desc_field_txt}> PackageComment: Built by CMake ${CMAKE_VERSION} with $ configuration for ${CMAKE_SYSTEM_NAME} (${CMAKE_SYSTEM_PROCESSOR})\ @@ -416,7 +416,7 @@ $<$:${_pkg_purpose_field_txt}> PackageVerificationCode: \${SBOM_VERIFICATION_CODE} BuiltDate: \${SBOM_CREATE_DATE} ReleaseDate: \${SBOM_CREATE_DATE} -Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-${SBOM_GENERATE_PACKAGE_NAME} +Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-${_arg_sbom_gen_PACKAGE_NAME} " ) endmacro() @@ -565,138 +565,138 @@ function(sbom_generate) ) set(multiValueArgs CREATOR PACKAGE_NOTES PACKAGE_PURPOSE) cmake_parse_arguments( - SBOM_GENERATE "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} + _arg_sbom_gen "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - if(SBOM_GENERATE_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown arguments: ${SBOM_GENERATE_UNPARSED_ARGUMENTS}") + if(_arg_sbom_gen_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments: ${_arg_sbom_gen_UNPARSED_ARGUMENTS}") endif() if(NOT DEFINED GIT_VERSION) version_extract() endif() - if(NOT DEFINED SBOM_GENERATE_CREATOR) + if(NOT DEFINED _arg_sbom_gen_CREATOR) message(FATAL_ERROR "Missing required argument CREATOR.") endif() - cmake_parse_arguments(SBOM_GENERATE_CREATOR "" "PERSON;ORGANIZATION;EMAIL" "" ${SBOM_GENERATE_CREATOR}) - if(SBOM_GENERATE_CREATOR_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown subarguments for CREATOR: ${SBOM_GENERATE_CREATOR_UNPARSED_ARGUMENTS}.") + cmake_parse_arguments(_arg_sbom_gen_CREATOR "" "PERSON;ORGANIZATION;EMAIL" "" ${_arg_sbom_gen_CREATOR}) + if(_arg_sbom_gen_CREATOR_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown subarguments for CREATOR: ${_arg_sbom_gen_CREATOR_UNPARSED_ARGUMENTS}.") endif() - if((NOT DEFINED SBOM_GENERATE_CREATOR_PERSON) AND (NOT DEFINED SBOM_GENERATE_CREATOR_ORGANIZATION)) + if((NOT DEFINED _arg_sbom_gen_CREATOR_PERSON) AND (NOT DEFINED _arg_sbom_gen_CREATOR_ORGANIZATION)) message(FATAL_ERROR "Missing for argument CREATOR.") - elseif(DEFINED SBOM_GENERATE_CREATOR_PERSON AND DEFINED SBOM_GENERATE_CREATOR_ORGANIZATION) + elseif(DEFINED _arg_sbom_gen_CREATOR_PERSON AND DEFINED _arg_sbom_gen_CREATOR_ORGANIZATION) message(FATAL_ERROR "Specify either PERSON or ORGANIZATION, not both.") endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_LICENSE) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_LICENSE) message(FATAL_ERROR "Missing required argument PACKAGE_LICENSE.") endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_NAME) - set(SBOM_GENERATE_PACKAGE_NAME ${PROJECT_NAME}) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_NAME) + set(_arg_sbom_gen_PACKAGE_NAME ${PROJECT_NAME}) endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_VERSION) - set(SBOM_GENERATE_PACKAGE_VERSION ${GIT_VERSION}) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_VERSION) + set(_arg_sbom_gen_PACKAGE_VERSION ${GIT_VERSION}) endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_FILENAME) - set(SBOM_GENERATE_PACKAGE_FILENAME "${SBOM_GENERATE_PACKAGE_NAME}-${SBOM_GENERATE_PACKAGE_VERSION}.zip") + if(NOT DEFINED _arg_sbom_gen_PACKAGE_FILENAME) + set(_arg_sbom_gen_PACKAGE_FILENAME "${_arg_sbom_gen_PACKAGE_NAME}-${_arg_sbom_gen_PACKAGE_VERSION}.zip") endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_DOWNLOAD) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_DOWNLOAD) # if not defined, the creator made no attempt to specify a download location - set(SBOM_GENERATE_PACKAGE_DOWNLOAD "NOASSERTION") + set(_arg_sbom_gen_PACKAGE_DOWNLOAD "NOASSERTION") else() - cmake_parse_arguments(SBOM_GENERATE_PACKAGE_DOWNLOAD "NONE;NOASSERTION" "" "" ${SBOM_GENERATE_PACKAGE_DOWNLOAD}) - if(SBOM_GENERATE_PACKAGE_DOWNLOAD_NONE) - set(SBOM_GENERATE_PACKAGE_DOWNLOAD "NONE") - elseif(SBOM_GENERATE_PACKAGE_DOWNLOAD_NOASSERTION) - set(SBOM_GENERATE_PACKAGE_DOWNLOAD "NOASSERTION") + cmake_parse_arguments(_arg_sbom_gen_PACKAGE_DOWNLOAD "NONE;NOASSERTION" "" "" ${_arg_sbom_gen_PACKAGE_DOWNLOAD}) + if(_arg_sbom_gen_PACKAGE_DOWNLOAD_NONE) + set(_arg_sbom_gen_PACKAGE_DOWNLOAD "NONE") + elseif(_arg_sbom_gen_PACKAGE_DOWNLOAD_NOASSERTION) + set(_arg_sbom_gen_PACKAGE_DOWNLOAD "NOASSERTION") endif() endif() - if(NOT DEFINED SBOM_GENERATE_PACKAGE_URL) - if(NOT DEFINED SBOM_GENERATE_NAMESPACE) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_URL) + if(NOT DEFINED _arg_sbom_gen_NAMESPACE) message(FATAL_ERROR "Specify NAMESPACE when PACKAGE_URL is omitted.") endif() endif() string(TIMESTAMP NOW_UTC UTC) - if(NOT DEFINED SBOM_GENERATE_PACKAGE_COPYRIGHT) + if(NOT DEFINED _arg_sbom_gen_PACKAGE_COPYRIGHT) string(TIMESTAMP NOW_YEAR "%Y" UTC) - if(DEFINED SBOM_GENERATE_CREATOR_PERSON) - set(SBOM_GENERATE_PACKAGE_COPYRIGHT "${NOW_YEAR} ${SBOM_GENERATE_CREATOR_PERSON}") - elseif(DEFINED SBOM_GENERATE_CREATOR_ORGANIZATION) - set(SBOM_GENERATE_PACKAGE_COPYRIGHT "${NOW_YEAR} ${SBOM_GENERATE_CREATOR_ORGANIZATION}") + if(DEFINED _arg_sbom_gen_CREATOR_PERSON) + set(_arg_sbom_gen_PACKAGE_COPYRIGHT "${NOW_YEAR} ${_arg_sbom_gen_CREATOR_PERSON}") + elseif(DEFINED _arg_sbom_gen_CREATOR_ORGANIZATION) + set(_arg_sbom_gen_PACKAGE_COPYRIGHT "${NOW_YEAR} ${_arg_sbom_gen_CREATOR_ORGANIZATION}") else() - set(SBOM_GENERATE_PACKAGE_COPYRIGHT "NOASSERTION") + set(_arg_sbom_gen_PACKAGE_COPYRIGHT "NOASSERTION") endif() else() - cmake_parse_arguments(SBOM_GENERATE_PACKAGE_COPYRIGHT "NONE;NOASSERTION" "" "" ${SBOM_GENERATE_PACKAGE_COPYRIGHT}) - if(SBOM_GENERATE_PACKAGE_COPYRIGHT_NONE) - set(SBOM_GENERATE_PACKAGE_COPYRIGHT "NONE") - elseif(SBOM_GENERATE_PACKAGE_COPYRIGHT_NOASSERTION) - set(SBOM_GENERATE_PACKAGE_COPYRIGHT "NOASSERTION") + cmake_parse_arguments(_arg_sbom_gen_PACKAGE_COPYRIGHT "NONE;NOASSERTION" "" "" ${_arg_sbom_gen_PACKAGE_COPYRIGHT}) + if(_arg_sbom_gen_PACKAGE_COPYRIGHT_NONE) + set(_arg_sbom_gen_PACKAGE_COPYRIGHT "NONE") + elseif(_arg_sbom_gen_PACKAGE_COPYRIGHT_NOASSERTION) + set(_arg_sbom_gen_PACKAGE_COPYRIGHT "NOASSERTION") endif() endif() - if(DEFINED SBOM_GENERATE_PACKAGE_NOTES) - _sbom_parse_package_notes("${SBOM_GENERATE_PACKAGE_NOTES}" SBOM_GENERATE_PACKAGE_SUMMARY - SBOM_GENERATE_PACKAGE_DESC + if(DEFINED _arg_sbom_gen_PACKAGE_NOTES) + _sbom_parse_package_notes("${_arg_sbom_gen_PACKAGE_NOTES}" _arg_sbom_gen_PACKAGE_SUMMARY + _arg_sbom_gen_PACKAGE_DESC __unused__) unset(__unused__) endif() - if(DEFINED SBOM_GENERATE_PACKAGE_PURPOSE) - _sbom_parse_package_purpose("${SBOM_GENERATE_PACKAGE_PURPOSE}" SBOM_GENERATE_PACKAGE_PURPOSE) + if(DEFINED _arg_sbom_gen_PACKAGE_PURPOSE) + _sbom_parse_package_purpose("${_arg_sbom_gen_PACKAGE_PURPOSE}" _arg_sbom_gen_PACKAGE_PURPOSE) endif() - if(NOT DEFINED SBOM_GENERATE_OUTPUT) - set(SBOM_GENERATE_OUTPUT "./${CMAKE_INSTALL_DATAROOTDIR}/${SBOM_GENERATE_PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx") + if(NOT DEFINED _arg_sbom_gen_OUTPUT) + set(_arg_sbom_gen_OUTPUT "./${CMAKE_INSTALL_DATAROOTDIR}/${_arg_sbom_gen_PACKAGE_NAME}-sbom-${GIT_VERSION_PATH}.spdx") endif() - if(NOT DEFINED SBOM_GENERATE_NAMESPACE) - if((NOT DEFINED SBOM_GENERATE_PACKAGE_URL) OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NONE") OR (SBOM_GENERATE_PACKAGE_URL STREQUAL "NOASSERTION")) + if(NOT DEFINED _arg_sbom_gen_NAMESPACE) + if((NOT DEFINED _arg_sbom_gen_PACKAGE_URL) OR (_arg_sbom_gen_PACKAGE_URL STREQUAL "NONE") OR (_arg_sbom_gen_PACKAGE_URL STREQUAL "NOASSERTION")) message(FATAL_ERROR "Specifiy PACKAGE_URL when NAMESPACE is omitted.") endif() - set(SBOM_GENERATE_NAMESPACE "${SBOM_GENERATE_PACKAGE_URL}/spdxdocs/${SBOM_GENERATE_PACKAGE_NAME}-${SBOM_GENERATE_PACKAGE_VERSION}") + set(_arg_sbom_gen_NAMESPACE "${_arg_sbom_gen_PACKAGE_URL}/spdxdocs/${_arg_sbom_gen_PACKAGE_NAME}-${_arg_sbom_gen_PACKAGE_VERSION}") endif() - if(${SBOM_GENERATE_ENABLE_CHECKS}) + if(${_arg_sbom_gen_ENABLE_CHECKS}) set(SBOM_CHECKS_ENABLED ON CACHE BOOL "Warn on important missing fields.") else() set(SBOM_CHECKS_ENABLED OFF CACHE BOOL "Warn on important missing fields.") endif() # remove special characters from package name and replace with - - string(REGEX REPLACE "[^A-Za-z0-9.]+" "-" SBOM_GENERATE_PACKAGE_NAME "${SBOM_GENERATE_PACKAGE_NAME}") + string(REGEX REPLACE "[^A-Za-z0-9.]+" "-" _arg_sbom_gen_PACKAGE_NAME "${_arg_sbom_gen_PACKAGE_NAME}") # strip - from end of string - string(REGEX REPLACE "-+$" "" SBOM_GENERATE_PACKAGE_NAME "${SBOM_GENERATE_PACKAGE_NAME}") + string(REGEX REPLACE "-+$" "" _arg_sbom_gen_PACKAGE_NAME "${_arg_sbom_gen_PACKAGE_NAME}") # Prevent collision with other generated SPDXID with -[0-9]+ suffix, by removing -. - string(REGEX REPLACE "-([0-9]+)$" "\\1" SBOM_GENERATE_PACKAGE_NAME "${SBOM_GENERATE_PACKAGE_NAME}") + string(REGEX REPLACE "-([0-9]+)$" "\\1" _arg_sbom_gen_PACKAGE_NAME "${_arg_sbom_gen_PACKAGE_NAME}") - set(SBOM_FILENAME "${SBOM_GENERATE_OUTPUT}" PARENT_SCOPE) + set(SBOM_FILENAME "${_arg_sbom_gen_OUTPUT}" PARENT_SCOPE) set(SBOM_BINARY_DIR "${PROJECT_BINARY_DIR}/sbom") set(SBOM_SNIPPET_DIR "${SBOM_BINARY_DIR}/sbom-src/$") - set_property(GLOBAL PROPERTY SBOM_FILENAME "${SBOM_GENERATE_OUTPUT}") + set_property(GLOBAL PROPERTY SBOM_FILENAME "${_arg_sbom_gen_OUTPUT}") set_property(GLOBAL PROPERTY SBOM_BINARY_DIR "${SBOM_BINARY_DIR}") set_property(GLOBAL PROPERTY SBOM_SNIPPET_DIR "${SBOM_SNIPPET_DIR}") - set_property(GLOBAL PROPERTY sbom_package_spdxid "${SBOM_GENERATE_PACKAGE_NAME}") - set_property(GLOBAL PROPERTY sbom_package_license "${SBOM_GENERATE_PACKAGE_LICENSE}") - set_property(GLOBAL PROPERTY sbom_package_copyright "${SBOM_GENERATE_PACKAGE_COPYRIGHT}") + set_property(GLOBAL PROPERTY sbom_package_spdxid "${_arg_sbom_gen_PACKAGE_NAME}") + set_property(GLOBAL PROPERTY sbom_package_license "${_arg_sbom_gen_PACKAGE_LICENSE}") + set_property(GLOBAL PROPERTY sbom_package_copyright "${_arg_sbom_gen_PACKAGE_COPYRIGHT}") set_property(GLOBAL PROPERTY sbom_spdxids 0) #REFAC(>=3.20): Use cmake_path() instead of get_filename_component(). if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20) - cmake_path(GET SBOM_GENERATE_OUTPUT FILENAME doc_name) + cmake_path(GET _arg_sbom_gen_OUTPUT FILENAME doc_name) else() - get_filename_component(doc_name "${SBOM_GENERATE_OUTPUT}" NAME_WLE) + get_filename_component(doc_name "${_arg_sbom_gen_OUTPUT}" NAME_WLE) endif() file(MAKE_DIRECTORY ${SBOM_BINARY_DIR}) @@ -708,14 +708,14 @@ function(sbom_generate) set(_sbom_intermediate_file "$/sbom.spdx.in") set(_sbom_document_template "SPDXRef-DOCUMENT.spdx.in") - set(_sbom_export_path "${SBOM_GENERATE_OUTPUT}") + set(_sbom_export_path "${_arg_sbom_gen_OUTPUT}") - if(NOT IS_ABSOLUTE "${SBOM_GENERATE_OUTPUT}") - set(_sbom_export_path "\${CMAKE_INSTALL_PREFIX}/${SBOM_GENERATE_OUTPUT}") + if(NOT IS_ABSOLUTE "${_arg_sbom_gen_OUTPUT}") + set(_sbom_export_path "\${CMAKE_INSTALL_PREFIX}/${_arg_sbom_gen_OUTPUT}") endif() _sbom_generate_document_template() - set(SBOM_LAST_SPDXID "SPDXRef-${SBOM_GENERATE_PACKAGE_NAME}" PARENT_SCOPE) + set(SBOM_LAST_SPDXID "SPDXRef-${_arg_sbom_gen_PACKAGE_NAME}" PARENT_SCOPE) _sbom_append_sbom_snippet("setup.cmake") file(GENERATE @@ -1009,82 +1009,82 @@ function(sbom_add_package NAME) DATE ) cmake_parse_arguments( - _args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} + _arg_add_pkg "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) _sbom_builder_is_setup() - if(_args_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown arguments: ${_args_UNPARSED_ARGUMENTS}") + if(_arg_add_pkg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments: ${_arg_add_pkg_UNPARSED_ARGUMENTS}") endif() sbom_spdxid( - VARIABLE _args_SPDXID - CHECK "${_args_SPDXID}" + VARIABLE _arg_add_pkg_SPDXID + CHECK "${_arg_add_pkg_SPDXID}" HINTS "SPDXRef-${NAME}" ) - set(SBOM_LAST_SPDXID ${_args_SPDXID} PARENT_SCOPE) + set(SBOM_LAST_SPDXID ${_arg_add_pkg_SPDXID} PARENT_SCOPE) - set(_fields "PackageName: ${NAME}\nSPDXID: ${_args_SPDXID}") + set(_fields "PackageName: ${NAME}\nSPDXID: ${_arg_add_pkg_SPDXID}") - set(_args_LICENSE_DECLARED "NOASSERTION") - if(NOT DEFINED _args_LICENSE) + set(_arg_add_pkg_LICENSE_DECLARED "NOASSERTION") + if(NOT DEFINED _arg_add_pkg_LICENSE) message(FATAL_ERROR "Missing LICENSE argument for package ${NAME}.") endif() - _sbom_parse_license("CONCLUDED;${_args_LICENSE}" _args_LICENSE_CONCLUDED _args_LICENSE_DECLARED _args_LICENSE_COMMENT) - string(APPEND _fields "\nPackageLicenseConcluded: ${_args_LICENSE_CONCLUDED}\nPackageLicenseDeclared: ${_args_LICENSE_DECLARED}") - if(DEFINED _args_LICENSE_COMMENT) - string(APPEND _fields "\nPackageLicenseComments: ${_args_LICENSE_COMMENT}") + _sbom_parse_license("CONCLUDED;${_arg_add_pkg_LICENSE}" _arg_add_pkg_LICENSE_CONCLUDED _arg_add_pkg_LICENSE_DECLARED _arg_add_pkg_LICENSE_COMMENT) + string(APPEND _fields "\nPackageLicenseConcluded: ${_arg_add_pkg_LICENSE_CONCLUDED}\nPackageLicenseDeclared: ${_arg_add_pkg_LICENSE_DECLARED}") + if(DEFINED _arg_add_pkg_LICENSE_COMMENT) + string(APPEND _fields "\nPackageLicenseComments: ${_arg_add_pkg_LICENSE_COMMENT}") endif() - if(NOT DEFINED _args_VERSION) + if(NOT DEFINED _arg_add_pkg_VERSION) message(FATAL_ERROR "Missing VERSION argument for package ${NAME}.") endif() - string(APPEND _fields "\nPackageVersion: ${_args_VERSION}") + string(APPEND _fields "\nPackageVersion: ${_arg_add_pkg_VERSION}") - if(NOT DEFINED _args_SUPPLIER) + if(NOT DEFINED _arg_add_pkg_SUPPLIER) message(FATAL_ERROR "Missing SUPPLIER argument for package ${NAME}.") endif() set(_supplier_field_txt "") - _sbom_parse_package_supplier("${_args_SUPPLIER}" _args_SUPPLIER_TYPE _args_SUPPLIER_NAME _args_SUPPLIER_EMAIL) - if("${_args_SUPPLIER_TYPE}" STREQUAL "NOASSERTION") + _sbom_parse_package_supplier("${_arg_add_pkg_SUPPLIER}" _arg_add_pkg_SUPPLIER_TYPE _arg_add_pkg_SUPPLIER_NAME _arg_add_pkg_SUPPLIER_EMAIL) + if("${_arg_add_pkg_SUPPLIER_TYPE}" STREQUAL "NOASSERTION") message(FATAL_ERROR "SUPPLIER must be a PERSON or ORGANIZATION.") else() - set(_supplier_field_txt "PackageSupplier: ${_args_SUPPLIER_TYPE} ${_args_SUPPLIER_NAME}") - if(DEFINED _args_SUPPLIER_EMAIL) - set(_supplier_field_txt "${_supplier_field_txt} (${_args_SUPPLIER_EMAIL})") + set(_supplier_field_txt "PackageSupplier: ${_arg_add_pkg_SUPPLIER_TYPE} ${_arg_add_pkg_SUPPLIER_NAME}") + if(DEFINED _arg_add_pkg_SUPPLIER_EMAIL) + set(_supplier_field_txt "${_supplier_field_txt} (${_arg_add_pkg_SUPPLIER_EMAIL})") endif() endif() string(APPEND _fields "\n${_supplier_field_txt}") - if(DEFINED _args_FILENAME) - string(APPEND _fields "\nPackageFileName: ${_args_FILENAME}") + if(DEFINED _arg_add_pkg_FILENAME) + string(APPEND _fields "\nPackageFileName: ${_arg_add_pkg_FILENAME}") endif() - if(DEFINED _args_ORIGINATOR) + if(DEFINED _arg_add_pkg_ORIGINATOR) set(_originator_field_txt "") - _sbom_parse_package_supplier("${_args_ORIGINATOR}" _args_ORIGINATOR_TYPE _args_ORIGINATOR_NAME _args_ORIGINATOR_EMAIL) - if("${_args_ORIGINATOR_TYPE}" STREQUAL "NOASSERTION") + _sbom_parse_package_supplier("${_arg_add_pkg_ORIGINATOR}" _arg_add_pkg_ORIGINATOR_TYPE _arg_add_pkg_ORIGINATOR_NAME _arg_add_pkg_ORIGINATOR_EMAIL) + if("${_arg_add_pkg_ORIGINATOR_TYPE}" STREQUAL "NOASSERTION") set(_originator_field_txt "PackageOriginator: NOASSERTION") else() - set(_originator_field_txt "PackageOriginator: ${_args_ORIGINATOR_TYPE} ${_args_ORIGINATOR_NAME}") - if(DEFINED _args_ORIGINATOR_EMAIL) - set(_originator_field_txt "${_originator_field_txt} (${_args_ORIGINATOR_EMAIL})") + set(_originator_field_txt "PackageOriginator: ${_arg_add_pkg_ORIGINATOR_TYPE} ${_arg_add_pkg_ORIGINATOR_NAME}") + if(DEFINED _arg_add_pkg_ORIGINATOR_EMAIL) + set(_originator_field_txt "${_originator_field_txt} (${_arg_add_pkg_ORIGINATOR_EMAIL})") endif() endif() string(APPEND _fields "\n${_originator_field_txt}") endif() - if(NOT DEFINED _args_DOWNLOAD) - set(_args_DOWNLOAD "NOASSERTION") + if(NOT DEFINED _arg_add_pkg_DOWNLOAD) + set(_arg_add_pkg_DOWNLOAD "NOASSERTION") endif() - string(APPEND _fields "\nPackageDownloadLocation: ${_args_DOWNLOAD}") + string(APPEND _fields "\nPackageDownloadLocation: ${_arg_add_pkg_DOWNLOAD}") - if(DEFINED _args_CHECKSUM) + if(DEFINED _arg_add_pkg_CHECKSUM) set(_algo TRUE) #first string is the algorithm, second is the checksum set(_checksum_field_txt "") - foreach(_checksum IN LISTS _args_CHECKSUM) + foreach(_checksum IN LISTS _arg_add_pkg_CHECKSUM) if(_algo) set(_algo FALSE) set(_checksum_field_txt "${_checksum_field_txt}\nPackageChecksum: ${_checksum}:") @@ -1096,75 +1096,75 @@ function(sbom_add_package NAME) string(APPEND _fields "${_checksum_field_txt}") endif() - if(DEFINED _args_URL) - string(APPEND _fields "\nPackageHomePage: ${_args_URL}") + if(DEFINED _arg_add_pkg_URL) + string(APPEND _fields "\nPackageHomePage: ${_arg_add_pkg_URL}") endif() - if(DEFINED _args_SOURCE_INFO) - string(APPEND _fields "\nPackageSourceInfo: ${_args_URL}") + if(DEFINED _arg_add_pkg_SOURCE_INFO) + string(APPEND _fields "\nPackageSourceInfo: ${_arg_add_pkg_URL}") endif() - if(NOT DEFINED _args_COPYRIGHT) - set(_args_COPYRIGHT "NOASSERTION") + if(NOT DEFINED _arg_add_pkg_COPYRIGHT) + set(_arg_add_pkg_COPYRIGHT "NOASSERTION") endif() - string(APPEND _fields "\nPackageCopyrightText: ${_args_COPYRIGHT}") + string(APPEND _fields "\nPackageCopyrightText: ${_arg_add_pkg_COPYRIGHT}") - if(DEFINED _args_NOTES) - _sbom_parse_package_notes("${_args_NOTES}" _args_SUMMARY _args_DESC _args_COMMENT) - if(DEFINED _args_SUMMARY) - string(APPEND _fields "\nPackageSummary: ${_args_SUMMARY}") + if(DEFINED _arg_add_pkg_NOTES) + _sbom_parse_package_notes("${_arg_add_pkg_NOTES}" _arg_add_pkg_SUMMARY _arg_add_pkg_DESC _arg_add_pkg_COMMENT) + if(DEFINED _arg_add_pkg_SUMMARY) + string(APPEND _fields "\nPackageSummary: ${_arg_add_pkg_SUMMARY}") endif() - if(DEFINED _args_DESC) - string(APPEND _fields "\nPackageDescription: ${_args_DESC}") + if(DEFINED _arg_add_pkg_DESC) + string(APPEND _fields "\nPackageDescription: ${_arg_add_pkg_DESC}") endif() - if(DEFINED _args_COMMENT) - string(APPEND _fields "\nPackageComment: ${_args_COMMENT}") + if(DEFINED _arg_add_pkg_COMMENT) + string(APPEND _fields "\nPackageComment: ${_arg_add_pkg_COMMENT}") endif() endif() - foreach(_ref IN LISTS _args_EXTREF) + foreach(_ref IN LISTS _arg_add_pkg_EXTREF) string(APPEND _fields "\nExternalRef: ${_ref}") endforeach() - if(DEFINED _args_ATTRIBUTION) - foreach(_attr IN LISTS _args_ATTRIBUTION) + if(DEFINED _arg_add_pkg_ATTRIBUTION) + foreach(_attr IN LISTS _arg_add_pkg_ATTRIBUTION) string(APPEND _fields "\nPackageAttributionText: ${_attr}") endforeach() endif() - if(DEFINED _args_PURPOSE) - _sbom_parse_package_purpose("${_args_PURPOSE}" _args_PURPOSE) - foreach(_purpose IN LISTS _args_PURPOSE) + if(DEFINED _arg_add_pkg_PURPOSE) + _sbom_parse_package_purpose("${_arg_add_pkg_PURPOSE}" _arg_add_pkg_PURPOSE) + foreach(_purpose IN LISTS _arg_add_pkg_PURPOSE) string(APPEND _fields "\nPrimaryPackagePurpose: ${_purpose}") endforeach() endif() - if(DEFINED _args_DATE) - _sbom_parse_dates("${_args_DATE}" _args_date_Build _args_date_Rel _args_date_VU) - if(DEFINED _args_date_Build) - string(APPEND _fields "\nBuildDate: ${_args_date_Build}") + if(DEFINED _arg_add_pkg_DATE) + _sbom_parse_dates("${_arg_add_pkg_DATE}" _arg_add_pkg_date_Build _arg_add_pkg_date_Rel _arg_add_pkg_date_VU) + if(DEFINED _arg_add_pkg_date_Build) + string(APPEND _fields "\nBuildDate: ${_arg_add_pkg_date_Build}") endif() - if(DEFINED _args_date_Rel) - string(APPEND _fields "\nReleaseDate: ${_args_date_Rel}") + if(DEFINED _arg_add_pkg_date_Rel) + string(APPEND _fields "\nReleaseDate: ${_arg_add_pkg_date_Rel}") endif() - if(DEFINED _args_date_VU) - string(APPEND _fields "\nValidUntilDate: ${_args_date_VU}") + if(DEFINED _arg_add_pkg_date_VU) + string(APPEND _fields "\nValidUntilDate: ${_arg_add_pkg_date_VU}") endif() endif() - if(NOT DEFINED _args_RELATIONSHIP) - set(_args_RELATIONSHIP "SPDXRef-${_sbom_project} DEPENDS_ON ${_args_SPDXID}") + if(NOT DEFINED _arg_add_pkg_RELATIONSHIP) + set(_arg_add_pkg_RELATIONSHIP "SPDXRef-${_sbom_project} DEPENDS_ON ${_arg_add_pkg_SPDXID}") else() - string(REPLACE "@SBOM_LAST_SPDXID@" "${_args_SPDXID}" _args_RELATIONSHIP "${_args_RELATIONSHIP}") + string(REPLACE "@SBOM_LAST_SPDXID@" "${_arg_add_pkg_SPDXID}" _arg_add_pkg_RELATIONSHIP "${_arg_add_pkg_RELATIONSHIP}") endif() - string(APPEND _fields "\nRelationship: ${_args_RELATIONSHIP}\nRelationship: ${_args_SPDXID} CONTAINS NOASSERTION") + string(APPEND _fields "\nRelationship: ${_arg_add_pkg_RELATIONSHIP}\nRelationship: ${_arg_add_pkg_SPDXID} CONTAINS NOASSERTION") get_property(_sbom_snippet_dir GLOBAL PROPERTY SBOM_SNIPPET_DIR) - _sbom_append_sbom_snippet("${_args_SPDXID}.cmake") + _sbom_append_sbom_snippet("${_arg_add_pkg_SPDXID}.cmake") file( GENERATE - OUTPUT ${_sbom_snippet_dir}/${_args_SPDXID}.cmake + OUTPUT ${_sbom_snippet_dir}/${_arg_add_pkg_SPDXID}.cmake CONTENT " file(APPEND \"\${SBOM_INTERMEDIATE_FILE}\" @@ -1182,54 +1182,54 @@ endfunction() function(sbom_add_external ID PATH) set(oneValueArgs RENAME SPDXID RELATIONSHIP) cmake_parse_arguments( - SBOM_EXTERNAL "" "${oneValueArgs}" "" ${ARGN} + _arg_add_extern "" "${oneValueArgs}" "" ${ARGN} ) _sbom_builder_is_setup() - if(SBOM_EXTERNAL_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown arguments: ${SBOM_EXTERNAL_UNPARSED_ARGUMENTS}") + if(_arg_add_extern_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments: ${_arg_add_extern_UNPARSED_ARGUMENTS}") endif() - if("${SBOM_EXTERNAL_SPDXID}" STREQUAL "") + if("${_arg_add_extern_SPDXID}" STREQUAL "") get_property(_spdxids GLOBAL PROPERTY sbom_spdxids) - set(SBOM_EXTERNAL_SPDXID "DocumentRef-${_spdxids}") + set(_arg_add_extern_SPDXID "DocumentRef-${_spdxids}") math(EXPR _spdxids "${_spdxids} + 1") set_property(GLOBAL PROPERTY sbom_spdxids "${_spdxids}") endif() - if(NOT "${SBOM_EXTERNAL_SPDXID}" MATCHES "^DocumentRef-[-a-zA-Z0-9]+$") - message(FATAL_ERROR "Invalid DocumentRef \"${SBOM_EXTERNAL_SPDXID}\"") + if(NOT "${_arg_add_extern_SPDXID}" MATCHES "^DocumentRef-[-a-zA-Z0-9]+$") + message(FATAL_ERROR "Invalid DocumentRef \"${_arg_add_extern_SPDXID}\"") endif() - set(SBOM_LAST_SPDXID "${SBOM_EXTERNAL_SPDXID}" PARENT_SCOPE) + set(SBOM_LAST_SPDXID "${_arg_add_extern_SPDXID}" PARENT_SCOPE) get_filename_component(sbom_dir "${_sbom}" DIRECTORY) - if("${SBOM_EXTERNAL_RELATIONSHIP}" STREQUAL "") - set(SBOM_EXTERNAL_RELATIONSHIP - "SPDXRef-${_sbom_project} DEPENDS_ON ${SBOM_EXTERNAL_SPDXID}:${ID}" + if("${_arg_add_extern_RELATIONSHIP}" STREQUAL "") + set(_arg_add_extern_RELATIONSHIP + "SPDXRef-${_sbom_project} DEPENDS_ON ${_arg_add_extern_SPDXID}:${ID}" ) else() - string(REPLACE "@SBOM_LAST_SPDXID@" "${SBOM_EXTERNAL_SPDXID}" - SBOM_EXTERNAL_RELATIONSHIP "${SBOM_EXTERNAL_RELATIONSHIP}" + string(REPLACE "@SBOM_LAST_SPDXID@" "${_arg_add_extern_SPDXID}" + _arg_add_extern_RELATIONSHIP "${_arg_add_extern_RELATIONSHIP}" ) endif() get_property(_sbom_snippet_dir GLOBAL PROPERTY SBOM_SNIPPET_DIR) - _sbom_append_sbom_snippet("${SBOM_EXTERNAL_SPDXID}.cmake") + _sbom_append_sbom_snippet("${_arg_add_extern_SPDXID}.cmake") file( GENERATE - OUTPUT ${_sbom_snippet_dir}/${SBOM_EXTERNAL_SPDXID}.cmake + OUTPUT ${_sbom_snippet_dir}/${_arg_add_extern_SPDXID}.cmake CONTENT "file(SHA1 \"${PATH}\" ext_sha1) file(READ \"${PATH}\" ext_content) -if(\"${SBOM_EXTERNAL_RENAME}\" STREQUAL \"\") +if(\"${_arg_add_extern_RENAME}\" STREQUAL \"\") get_filename_component(ext_name \"${PATH}\" NAME) file(WRITE \"${sbom_dir}/\${ext_name}\" \"\${ext_content}\") else() - file(WRITE \"${sbom_dir}/${SBOM_EXTERNAL_RENAME}\" \"\${ext_content}\") + file(WRITE \"${sbom_dir}/${_arg_add_extern_RENAME}\" \"\${ext_content}\") endif() if(NOT \"\${ext_content}\" MATCHES \"[\\r\\n]DocumentNamespace:\") @@ -1239,9 +1239,9 @@ endif() string(REGEX REPLACE \"^.*[\\r\\n]DocumentNamespace:[ \\t]*([^#\\r\\n]*).*$\" \"\\\\1\" ext_ns \"\${ext_content}\") -list(APPEND SBOM_EXT_DOCS \"ExternalDocumentRef: ${SBOM_EXTERNAL_SPDXID} \${ext_ns} SHA1: \${ext_sha1}\") +list(APPEND SBOM_EXT_DOCS \"ExternalDocumentRef: ${_arg_add_extern_SPDXID} \${ext_ns} SHA1: \${ext_sha1}\") -file(APPEND \"\${SBOM_INTERMEDIATE_FILE}\" \"Relationship: ${SBOM_EXTERNAL_RELATIONSHIP}\\n\") +file(APPEND \"\${SBOM_INTERMEDIATE_FILE}\" \"Relationship: ${_arg_add_extern_RELATIONSHIP}\\n\") " ) endfunction() From 606bbb29d8ff87c3113e631a2702bc65432fc24d Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 10:48:05 +0200 Subject: [PATCH 11/19] refactor: remove remnants of an old feature --- cmake/sbom.cmake | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 323e79b..4fa9e07 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -561,7 +561,6 @@ function(sbom_generate) PACKAGE_URL PACKAGE_LICENSE PACKAGE_COPYRIGHT - ENABLE_CHECKS ) set(multiValueArgs CREATOR PACKAGE_NOTES PACKAGE_PURPOSE) cmake_parse_arguments( @@ -667,12 +666,6 @@ function(sbom_generate) set(_arg_sbom_gen_NAMESPACE "${_arg_sbom_gen_PACKAGE_URL}/spdxdocs/${_arg_sbom_gen_PACKAGE_NAME}-${_arg_sbom_gen_PACKAGE_VERSION}") endif() - if(${_arg_sbom_gen_ENABLE_CHECKS}) - set(SBOM_CHECKS_ENABLED ON CACHE BOOL "Warn on important missing fields.") - else() - set(SBOM_CHECKS_ENABLED OFF CACHE BOOL "Warn on important missing fields.") - endif() - # remove special characters from package name and replace with - string(REGEX REPLACE "[^A-Za-z0-9.]+" "-" _arg_sbom_gen_PACKAGE_NAME "${_arg_sbom_gen_PACKAGE_NAME}") # strip - from end of string From d4220f390e9ac8f4bdab5715f80e4826820e29af Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 11:14:08 +0200 Subject: [PATCH 12/19] fix: tests after changing required arguments --- test/dir.cmake | 2 +- test/external.cmake | 4 ++-- test/file.cmake | 2 +- test/full_doc.cmake | 1 + test/minimal.cmake | 2 +- test/minimal2.cmake | 2 +- test/package.cmake | 6 +++--- test/target.cmake | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/test/dir.cmake b/test/dir.cmake index 94b2dff..de3db94 100644 --- a/test/dir.cmake +++ b/test/dir.cmake @@ -6,7 +6,7 @@ include(sbom) -sbom_generate(CREATOR ORGANIZATION DirectoryTest PACKAGE_URL https://www.directoryTest.com) +sbom_generate(CREATOR ORGANIZATION DirectoryTest PACKAGE_URL https://www.directoryTest.com PACKAGE_LICENSE MIT) install(FILES ${CMAKE_CURRENT_LIST_FILE} DESTINATION dir) install(FILES ${CMAKE_CURRENT_LIST_FILE} DESTINATION dir RENAME file.txt) diff --git a/test/external.cmake b/test/external.cmake index 04dff5c..cd278ae 100644 --- a/test/external.cmake +++ b/test/external.cmake @@ -11,7 +11,7 @@ file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/other/CMakeLists.txt " project(other) - sbom_generate(CREATOR PERSON \"Other\" OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/other-sbom.spdx PACKAGE_URL https://www.externalTest.com) + sbom_generate(CREATOR PERSON \"Other\" OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/other-sbom.spdx PACKAGE_URL https://www.externalTest.com PACKAGE_LICENSE MIT) sbom_finalize() " ) @@ -21,7 +21,7 @@ add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/other ${CMAKE_CURRENT_BINARY_DIR}/o # this is just used for testing purposes. Do not rely on this in production code. get_property(_sbom GLOBAL PROPERTY SBOM_FILENAME) -sbom_generate(CREATOR PERSON ExternalTest PACKAGE_URL https://www.externalTest.com) +sbom_generate(CREATOR PERSON ExternalTest PACKAGE_URL https://www.externalTest.com PACKAGE_LICENSE MIT) sbom_add_external(SPDXRef-other "${_sbom}") sbom_add_external(SPDXRef-other "${_sbom}" diff --git a/test/file.cmake b/test/file.cmake index 98705a6..d4d36b7 100644 --- a/test/file.cmake +++ b/test/file.cmake @@ -6,7 +6,7 @@ include(sbom) -sbom_generate(CREATOR ORGANIZATION FileTest PACKAGE_URL https://www.fileTest.com) +sbom_generate(CREATOR ORGANIZATION FileTest PACKAGE_URL https://www.fileTest.com PACKAGE_LICENSE MIT) install(FILES ${CMAKE_CURRENT_LIST_FILE} DESTINATION .) diff --git a/test/full_doc.cmake b/test/full_doc.cmake index 27ab8f9..f45ab17 100644 --- a/test/full_doc.cmake +++ b/test/full_doc.cmake @@ -13,6 +13,7 @@ sbom_generate( NAMESPACE "https://test.com/spdxdoc/me" CREATOR ORGANIZATION FullDocTest PACKAGE_URL https://www.fullDocTest.com + PACKAGE_LICENSE MIT ) sbom_finalize() diff --git a/test/minimal.cmake b/test/minimal.cmake index 8139d0c..1a578cc 100644 --- a/test/minimal.cmake +++ b/test/minimal.cmake @@ -6,7 +6,7 @@ include(sbom) -sbom_generate(CREATOR ORGANIZATION minimal_test PACKAGE_URL https://www.minimal_test.com) +sbom_generate(CREATOR ORGANIZATION minimal_test PACKAGE_URL https://www.minimal_test.com PACKAGE_LICENSE MIT) sbom_finalize() @TEST_VERIFY@ diff --git a/test/minimal2.cmake b/test/minimal2.cmake index 09a8d44..96eb2f2 100644 --- a/test/minimal2.cmake +++ b/test/minimal2.cmake @@ -6,7 +6,7 @@ include(sbom) -sbom_generate(CREATOR PERSON "Minimal2" PACKAGE_URL https://www.minimal_test.com) +sbom_generate(CREATOR PERSON "Minimal2" PACKAGE_URL https://www.minimal_test.com PACKAGE_LICENSE MIT) sbom_finalize() @TEST_VERIFY@ diff --git a/test/package.cmake b/test/package.cmake index 01b0477..4c38f9c 100644 --- a/test/package.cmake +++ b/test/package.cmake @@ -6,10 +6,10 @@ include(sbom) -sbom_generate(CREATOR PERSON package_test PACKAGE_URL https://www.package_test.com) +sbom_generate(CREATOR PERSON package_test PACKAGE_URL https://www.package_test.com PACKAGE_LICENSE MIT) -sbom_add_package(foo) -sbom_add_package(foo DOWNLOAD http://foo.bar/baz) +sbom_add_package(foo LICENSE GPL-3.0 VERSION 0.1 SUPPLIER PERSON "foo") +sbom_add_package(foo DOWNLOAD http://foo.bar/baz LICENSE GPL-3.0 VERSION 0.1 SUPPLIER PERSON "foo") sbom_add_package( bar DOWNLOAD http://somwhere.com/bar diff --git a/test/target.cmake b/test/target.cmake index 88b28ba..f12dd0a 100644 --- a/test/target.cmake +++ b/test/target.cmake @@ -6,7 +6,7 @@ include(sbom) -sbom_generate(CREATOR PERSON target_test PACKAGE_URL https://www.target_test.com) +sbom_generate(CREATOR PERSON target_test PACKAGE_URL https://www.target_test.com PACKAGE_LICENSE MIT) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/foo.c "int main() {}") From 8117df420b445af2f8bc689e77366b716c72d410 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 11:15:23 +0200 Subject: [PATCH 13/19] fix: valid purl for sbom --- cmake/sbom.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 4fa9e07..9e2d4cb 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -343,6 +343,9 @@ macro(_sbom_generate_document_template) set(_pkg_supplier_field "${_pkg_supplier_field} (${_arg_sbom_gen_CREATOR_EMAIL})") endif() + #make sure creator name can be used to create a uri + string(REGEX REPLACE "[ ]+" "-" _pkg_creator_name "${_pkg_creator_name}") + if(DEFINED _arg_sbom_gen_PACKAGE_COPYRIGHT) set(_pkg_copyright_field "PackageCopyrightText: ${_arg_sbom_gen_PACKAGE_COPYRIGHT}") endif() From 1db825c5bbaca9feeea9aed70ed5e82fc952877c Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 11:16:21 +0200 Subject: [PATCH 14/19] fix: default Checksums not generated when Checksum is not set --- cmake/sbom.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 9e2d4cb..5960cf0 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -828,8 +828,8 @@ function(_sbom_add_pkg_content PATH) endforeach() endif() + set(_hash_algo "SHA1;SHA256") # SHA1 is always required by SPDX, SHA256 required by TR-03183 if(DEFINED _arg_add_pkg_content_CHECKSUM) - set(_hash_algo "SHA1;SHA256") # SHA1 is always required by SPDX, SHA256 required by TR-03183 set(_supported_algorithms "MD5;SHA224;SHA384;SHA512;SHA3-256;SHA3-384;SHA3-512") foreach(_checksum ${_arg_add_pkg_content_CHECKSUM}) if("${_checksum}" IN_LIST _supported_algorithms) From 6c0b4f6ce6710443c026ee993ec4baee626123f2 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 11:29:38 +0200 Subject: [PATCH 15/19] fix: only one PackagePurpose allowed in SPDX SBOM At least according to their python validator. Specification says 0..* but the validator does not allow it. --- cmake/sbom.cmake | 19 +++++++------------ doc/full_signature.md | 7 ++----- example/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 5960cf0..837215a 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -365,10 +365,7 @@ macro(_sbom_generate_document_template) set(_pkg_purpose_fields FALSE) if(DEFINED _arg_sbom_gen_PACKAGE_PURPOSE) set(_pkg_purpose_fields TRUE) - set(_pkg_purpose_field_txt "") - foreach(_purpose IN LISTS _arg_sbom_gen_PACKAGE_PURPOSE) - set(_pkg_purpose_field_txt "${_pkg_purpose_field_txt}\nPrimaryPackagePurpose: ${_purpose}") - endforeach() + set(_pkg_purpose_field_txt "\nPrimaryPackagePurpose: ${_arg_sbom_gen_PACKAGE_PURPOSE}") endif() file( @@ -516,21 +513,21 @@ function(_sbom_parse_package_notes pkg_notes_arg out_pkg_SUMMARY out_pkg_DESC ou endforeach() endfunction() -function(_sbom_parse_package_purpose pkg_purpose_arg out_purpose_list) +function(_sbom_parse_package_purpose pkg_purpose_arg out_purpose) set(options "APPLICATION;FRAMEWORK;LIBRARY;CONTAINER;OPERATING-SYSTEM;DEVICE;FIRMWARE;SOURCE;ARCHIVE;FILE;INSTALL;OTHER") cmake_parse_arguments(_arg "${options}" "" "" ${pkg_purpose_arg}) if(_arg_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unknown keywords for PURPOSE: ${_arg_UNPARSED_ARGUMENTS}") endif() - set(${out_purpose_list} "") + # only one option is allowed + set(${out_purpose} "") foreach(opt ${options}) if(_arg_${opt}) - list(APPEND ${out_purpose_list} ${opt}) + set(${out_purpose} ${opt} PARENT_SCOPE) + return() endif() endforeach() - - set(${out_purpose_list} "${${out_purpose_list}}" PARENT_SCOPE) endfunction() function(_sbom_parse_filetype file_type_arg out_filetype_list) @@ -1130,9 +1127,7 @@ function(sbom_add_package NAME) if(DEFINED _arg_add_pkg_PURPOSE) _sbom_parse_package_purpose("${_arg_add_pkg_PURPOSE}" _arg_add_pkg_PURPOSE) - foreach(_purpose IN LISTS _arg_add_pkg_PURPOSE) - string(APPEND _fields "\nPrimaryPackagePurpose: ${_purpose}") - endforeach() + string(APPEND _fields "\nPrimaryPackagePurpose: ${_arg_add_pkg_PURPOSE}") endif() if(DEFINED _arg_add_pkg_DATE) diff --git a/doc/full_signature.md b/doc/full_signature.md index 88cec16..9b9ef29 100644 --- a/doc/full_signature.md +++ b/doc/full_signature.md @@ -194,7 +194,7 @@ sbom_add_package( [PURPOSE ...] + FILE|INSTALL|OTHER>] [DATE [RELEASE ] [BUILD ] [VALID_UNTIL ] ] @@ -314,11 +314,8 @@ sbom_add_package( - `PURPOSE`: - No SBOM entry when omitted. - See [SPDX clause 7.24](https://spdx.github.io/spdx-spec/v2.3/package-information/#724-primary-package-purpose-field) for more information. - - One or many of the following keywords: + - One of the following keywords: - `APPLICATION`, `FRAMEWORK`, `LIBRARY`, `CONTAINER`, `OPERATING-SYSTEM`, `DEVICE`, `FIRMWARE`, `SOURCE`, `ARCHIVE`, `FILE`, `INSTALL`, `OTHER`. - - Usage: - - `sbom_generate(... PURPOSE "APPLICATION" "FIRMWARE" ...)` - - `sbom_generate(... PURPOSE "FILE" "SOURCE" "LIBRARY" ...)` - `DATE`: - No SBOM entries when omitted. - `RELEASE`: The date the package was released. diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index f2c23ed..57ad51c 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -39,7 +39,7 @@ sbom_generate( PACKAGE_DOWNLOAD "http://example.org/download" PACKAGE_LICENSE "MIT" PACKAGE_NOTES SUMMARY "Just a simple example project, to demonstrate the SBOM-Builder" - PACKAGE_PURPOSE "APPLICATION" "OTHER" + PACKAGE_PURPOSE "APPLICATION" ) # mention the dependencies used in the SBOM From 4ecc76be1b65cf5514fb6846d620018a882858ec Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 11:48:37 +0200 Subject: [PATCH 16/19] fix: robustness of error detection in verify-step --- test/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f007c55..7ba4cb6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -23,12 +23,12 @@ project(${name})" set(TEST_VERIFY "install(CODE \" - message(STATUS \\\"Verifying SPDX document generated by test_${name}\\\") + message(STATUS \\\"Verifying: \${CMAKE_INSTALL_PREFIX}/\${SBOM_FILENAME}\\\") execute_process( - COMMAND \\\"pyspdxtools\\\" \\\"-i\\\" \\\"\${SBOM_FILENAME}\\\" + COMMAND \\\"pyspdxtools\\\" \\\"-i\\\" \\\"\${CMAKE_INSTALL_PREFIX}/\${SBOM_FILENAME}\\\" ERROR_VARIABLE _output ) - if(_output MATCHES \\\".*ERROR.*\\\") + if(NOT _output STREQUAL \\\"\\\") message(FATAL_ERROR \\\"SPDX verification failed: \\\${_output}\\\") endif()\" From af01d5bf7eb7e9d7ceadd7dccdca42b534014726 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Tue, 17 Sep 2024 17:29:46 +0200 Subject: [PATCH 17/19] refactor: simplify codeflow --- cmake/sbom.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/sbom.cmake b/cmake/sbom.cmake index 837215a..e35e4b4 100644 --- a/cmake/sbom.cmake +++ b/cmake/sbom.cmake @@ -883,13 +883,13 @@ cmake_policy(SET CMP0012 NEW) set(ADDING_DIR ${_arg_add_pkg_content_DIR}) set(_files \"\") -if(NOT ADDING_DIR) - set(_files \"./${PATH}\") -else() +if(ADDING_DIR) file(GLOB_RECURSE _files LIST_DIRECTORIES false RELATIVE \"\${CMAKE_INSTALL_PREFIX}\" \"\${CMAKE_INSTALL_PREFIX}/${PATH}/*\" -) + ) +else() + set(_files \"${PATH}\") endif() if((NOT ADDING_DIR) AND (NOT EXISTS \${CMAKE_INSTALL_PREFIX}/${PATH})) From bccb68ae9318214623bffc73d1e7ee1330574c91 Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Wed, 18 Sep 2024 13:18:09 +0200 Subject: [PATCH 18/19] fix: example sbom --- example/output/Example-sbom-0.3.0.spdx | 56 +++++++++++++------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/example/output/Example-sbom-0.3.0.spdx b/example/output/Example-sbom-0.3.0.spdx index cbef72b..4a0dde1 100644 --- a/example/output/Example-sbom-0.3.0.spdx +++ b/example/output/Example-sbom-0.3.0.spdx @@ -6,7 +6,7 @@ DocumentNamespace: https://github.com/sodgeit/CMake-SBOM-Builder/spdxdocs/Exampl Creator: Organization: Example Org (example@org.com) Creator: Tool: CMake-SBOM-Builder-v0.3.0 CreatorComment: This SPDX document was created from CMake 3.30.1, using CMake-SBOM-Builder from https://github.com/sodgeit/CMake-SBOM-Builder -Created: 2024-08-29T09:16:55Z +Created: 2024-09-17T15:30:54Z PackageName: Clang SPDXID: SPDXRef-compiler @@ -26,7 +26,7 @@ RelationshipComment: SPDXRef-Example is built by compiler Clang (C:/Progra PackageName: Example SPDXID: SPDXRef-Example ExternalRef: SECURITY cpe23Type cpe:2.3:o:microsoft:windows_10:-:*:*:*:*:*:x64:* -ExternalRef: PACKAGE-MANAGER purl pkg:supplier/Example/Example@v0.3.0 +ExternalRef: PACKAGE-MANAGER purl pkg:supplier/Example-Org/Example@v0.3.0 PackageVersion: v0.3.0 PackageFileName: Example-v0.3.0.zip PackageSupplier: Organization: Example Org (example@org.com) @@ -37,60 +37,58 @@ PackageCopyrightText: 2024 Example Org PackageHomePage: https://github.com/sodgeit/CMake-SBOM-Builder PackageSummary: Just a simple example project, to demonstrate the SBOM-Builder PackageComment: Built by CMake 3.30.1 with Release configuration for Windows (AMD64) -PackageVerificationCode: eab840722ebab9379e046b88ce0e6f6f616a2eb6 -BuiltDate: 2024-08-29T09:16:55Z +PrimaryPackagePurpose: APPLICATION +PackageVerificationCode: ae2f5127406146b9ab607f1ede155bca519ba872 +BuiltDate: 2024-09-17T15:30:54Z +ReleaseDate: 2024-09-17T15:30:54Z Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Example PackageName: cxxopts SPDXID: SPDXRef-cxxopts-0 -ExternalRef: SECURITY cpe23Type cpe:2.3:o:microsoft:windows_10:-:*:*:*:*:*:x64:* -PackageDownloadLocation: NOASSERTION +PackageLicenseConcluded: MIT PackageLicenseDeclared: NOASSERTION -PackageCopyrightText: NOASSERTION PackageVersion: 3.2.0 -PackageSupplier: Jarryd Beck (https://github.com/jarro2783/cxxopts) -FilesAnalyzed: false -PackageLicenseConcluded: MIT +PackageSupplier: Person: Jarryd Beck +PackageDownloadLocation: NOASSERTION +PackageCopyrightText: NOASSERTION Relationship: SPDXRef-Example DEPENDS_ON SPDXRef-cxxopts-0 Relationship: SPDXRef-cxxopts-0 CONTAINS NOASSERTION PackageName: Boost SPDXID: SPDXRef-Boost-1 -ExternalRef: SECURITY cpe23Type cpe:2.3:o:microsoft:windows_10:-:*:*:*:*:*:x64:* -PackageDownloadLocation: NOASSERTION +PackageLicenseConcluded: BSL-1.0 PackageLicenseDeclared: NOASSERTION -PackageCopyrightText: NOASSERTION PackageVersion: 1.85.0 -PackageSupplier: https://www.boost.org -FilesAnalyzed: false -PackageLicenseConcluded: BSL-1.0 +PackageSupplier: Organization: Boost Foundation +PackageDownloadLocation: NOASSERTION +PackageCopyrightText: NOASSERTION Relationship: SPDXRef-Example DEPENDS_ON SPDXRef-Boost-1 Relationship: SPDXRef-Boost-1 CONTAINS NOASSERTION FileName: ./include/Example_version.h SPDXID: SPDXRef-include-Example-version-h-2 +LicenseConcluded: MIT FileType: SOURCE -FileChecksum: SHA1: d8531f8bb2896353ae13c24ec84324ebbc11a1e4 -LicenseConcluded: NOASSERTION -LicenseInfoInFile: NOASSERTION -FileCopyrightText: NOASSERTION +FileCopyrightText: 2024 Example Org +FileChecksum: SHA1: 431efda6e36ca14a3a71892fb5e94582f713b95f +FileChecksum: SHA256: 81e62d1f1c32a1b055aca45f75f8e167cc53c14beb70cae6b5bc92949f1cba20 Relationship: SPDXRef-Example CONTAINS SPDXRef-include-Example-version-h-2 FileName: ./share/example/version.txt SPDXID: SPDXRef-share-example-version-txt-3 -FileType: DOCUMENTATION +LicenseConcluded: MIT FileType: TEXT -FileChecksum: SHA1: ad9f5f85711c66b6fce6975f6b7c489863e60974 -LicenseConcluded: NOASSERTION -LicenseInfoInFile: NOASSERTION -FileCopyrightText: NOASSERTION +FileType: DOCUMENTATION +FileCopyrightText: 2024 Example Org +FileChecksum: SHA1: ef8ae947da2dd7b37cc1e186c42975c702ec6fbe +FileChecksum: SHA256: 7836146189efb5232dc27bb99a67f9b9eec407463cf022d55cd9f9fb111d6ebb Relationship: SPDXRef-Example CONTAINS SPDXRef-share-example-version-txt-3 FileName: ./bin/example.exe SPDXID: SPDXRef-bin-TARGET-FILE-NAME-example-4 +LicenseConcluded: MIT FileType: BINARY -FileChecksum: SHA1: eaf3cf61d5fdccd5fc90dbfe6ec3aa4da3641754 -LicenseConcluded: NOASSERTION -LicenseInfoInFile: NOASSERTION -FileCopyrightText: NOASSERTION +FileCopyrightText: 2024 Example Org +FileChecksum: SHA1: a91168ee725c567ecdcb20b1e2dfafb7cb8c8f89 +FileChecksum: SHA256: af9c28ab48f7f5a3c26d100da127ea77f594447c0f30a8231e348d37f8ded424 Relationship: SPDXRef-Example CONTAINS SPDXRef-bin-TARGET-FILE-NAME-example-4 From 9a219f3d898a4641dcd0cb287102a4b51172e8dc Mon Sep 17 00:00:00 2001 From: Andreas Lay Date: Wed, 18 Sep 2024 13:21:12 +0200 Subject: [PATCH 19/19] ci: also verify the example sbom --- .github/workflows/cmake-multi-platform.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index c7afcbc..8b3ce40 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -6,7 +6,6 @@ on: push: branches: [ "main" ] pull_request: - branches: [ "main" ] jobs: build: @@ -52,13 +51,17 @@ jobs: - name: setup python uses: actions/setup-python@v3 with: - python-version: "3.10" + python-version: "3.12" - name: Install spdx-tools run: | python -m pip install --upgrade pip pip install spdx-tools + - name: Validate example sbom + run: | + pyspdxtools -i ${{ github.workspace }}/example/output/*.spdx + - name: Configure CMake run: > cmake -B ${{ steps.strings.outputs.build-output-dir }}