sodgeit/CMake-SBOM-Builder

GitHub: sodgeit/CMake-SBOM-Builder

一个基于 CMake 的 SBOM 生成工具,帮助项目自动生成符合 SPDX 和 BSI 规范的软件物料清单。

Stars: 9 | Forks: 7

# CMake SBOM 生成器 为任意 CMake 项目生成 SPDX 软件物料清单(SBOM)。 CMake-SBOM-Builder 旨在遵循以下规范: - [BSI 技术指南 TR-03183](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2.pdf?__blob=publicationFile&v=5)(德国联邦信息安全办公室) - 美国 [行政命令 14028](https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-security-supply-chains-software-1) - [SPDX 规范 2.3](https://spdx.github.io/spdx-spec/v2.3/) 该 SBOM 生成器设计为能够无缝集成到您的 CMake 项目中。它会根据您安装的文件和指定的包依赖关系,为项目生成一个 SBOM。 它还提供了版本提取功能,可以从 Git 仓库生成版本信息,并在 CMake 文件、C/C++ 代码(通过 cmake 目标)以及 Shell 环境(通过脚本)中可用。 要开始使用,请查看 [示例](#example) 以及如何 [将 SBOM-Builder 添加到您的项目](#adding-sbom-builder-to-your-project)。 **注意:** 该项目最初从 [cmake-sbom](https://github.com/DEMCON/cmake-sbom) 分支而来。 虽然原始项目提供了坚实的基础,但我们发现一些需要修改和改进的地方,以更好地符合我们的需求并在工作流程中有效使用。 主要变更包括: - **单文件集成**:我们将所有内容合并为一个文件,以简化与 CMake `file` 命令的集成,使用起来更简单高效。 - **多配置生成器增强**:SBOM 生成更好地与 Visual Studio 和 Ninja Multi-Config 等多配置生成器集成。为每种配置生成不同的 SBOM。 - **现代化 CMake**:提高最低要求版本(>=3.16),确保更好的兼容性并利用更新的功能。 - **更广泛的 SPDX 2.3 支持**:支持更多 SPDX 字段,以更好符合 SPDX 2.3 规范。 - **符合 BSI 指南** - **改进的文档** ## 目录 - [如何使用](#how-to-use) - [将 SBOM-Builder 添加到您的项目](#adding-sbom-builder-to-your-project) - [生成 SBOM 的步骤](#steps-to-generate-an-sbom) - [构建并安装您的项目](#build-and-install-your-project) - [示例](#example) - [可用的函数和参数](#available-functions-and-arguments) - [`sbom_generate`](#sbom_generate) - [`sbom_add_[file|directory|target]`](#sbom_add_filedirectorytarget) - [`sbom_add_package`](#sbom_add_package) - [`sbom_add_external`](#sbom_add_external) - [`sbom_finalize`](#sbom_finalize) - [`sbom_spdxid`](#sbom_spdxid) - [版本提取](#version-extraction) - [`version_extract()`](#version_extract) - [`version_generate()`](#version_generate) - [兼容性策略](#compatibility-strategy) - [许可证](#license) - [致谢](#acknowledgements) ## 如何使用 ### 将 SBOM-Builder 添加到您的项目 有多种方法可以实现这一点。我们推荐直接使用 CMake 以保持简单。 要下载特定版本: ``` file( DOWNLOAD https://github.com/sodgeit/CMake-SBOM-Builder/releases/download/v0.2.1/sbom.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake EXPECTED_HASH SHA256=f87f040c470f86e119e36f1043818a380ad6f81150df7fec60d4504bb38ae2e2 ) ``` 或始终下载最新版本。 然后只需包含该文件: ``` include(${CMAKE_CURRENT_BINARY_DIR}/cmake/sbom.cmake) ``` ### 生成 SBOM 的步骤 1. 使用 `sbom_generate()` 定义 SBOM 创建者并提供所构建包的一般信息。假设您的 CMake 项目生成一个包。 2. 使用 `sbom_add_file()`、`sbom_add_directory()` 或 `sbom_add_target()` 声明包的内容。这些应涵盖通过 CMake 的 `install()` 命令安装的所有文件、可执行文件、库等。 3. 使用 `sbom_add_package()` 定义包的依赖关系。对于单个文件依赖项,使用 `RELATIONSHIP` 参数覆盖默认行为。所有依赖项都被视为黑盒,不会进一步指定或分析其内部内容。 4. 最后调用 `sbom_finalize()` 完成 SBOM 定义。 ### 构建并安装您的项目 使用单配置生成器(Makefiles、Ninja): ``` cmake -S . -B build -DCMAKE_INSTALL_PREFIX=build/install -DCMAKE_BUILD_TYPE={Debug,Release,...} cmake --build build --target all cmake --install build ``` 使用多配置生成器(Visual Studio、Ninja Multi-Config): ``` cmake -S . -B build -G "Ninja Multi-Config" cmake --build build --target all --config {Debug,Release,...} #--target ALL_BUILD for Visual Studio cmake --install build --config {Debug,Release,...} --prefix build/install/{Debug,Release,...} ``` 我们建议在使用多配置生成器时使用 `--prefix` 选项覆盖安装前缀。这允许为每个配置在独立位置生成 SBOM。 如果不使用 `--prefix` 选项,SBOM 将在所有配置中生成到同一位置并相互覆盖。 默认情况下,SBOM 将生成在 `${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}-sbom-${GIT_VERSION_PATH}.spdx`(请参见 CMake 输出)。 ``` -- Installing: .../build/install/share/example-sbom-0.2.1.spdx ... -- Finalizing: .../build/install/share/example-sbom-0.2.1.spdx ``` ### 示例 ``` 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" ) 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() ``` ## 可用的函数和参数 以下是 SBOM-Builder 提供的函数概述。这里仅列出最重要且最可能使用的参数。 完整的函数签名请参考 [此处](./doc/full_signature.md)。 ### sbom_generate ``` sbom_generate( CREATOR [EMAIL ] PACKAGE_LICENSE [PACKAGE_NAME ] [PACKAGE_VERSION ] [PACKAGE_COPYRIGHT >] ) ``` - `CREATOR`:包和 SBOM 的提供者。 - 必须提供 `` 之一。 - `EMAIL` 可选。 - `PACKAGE_LICENSE`:SBOM 中描述的包的许可证。 - `PACKAGE_NAME`:包名称。 - 默认值为 `${PROJECT_NAME}`。 - `PACKAGE_VERSION`:包版本字段。 - 默认值为 `${GIT_VERSION}`。(参见[版本提取](#version-extraction)) - `PACKAGE_COPYRIGHT`:版权信息。 - 默认值为 ` `,其中 `` 是 `CREATOR` 的名称。 ### sbom_add_[file|directory|target] ``` sbom_add_[file|directory|target]( [LICENSE ] [COPYRIGHT >] [RELATIONSHIP ...] ) ``` - `filename|path|target`: - 相对于 `CMAKE_INSTALL_PREFIX` 的文件/目录路径,或要添加的目标名称(目标必须使用 `install(TARGETS ...)` 安装)。 - 支持生成器表达式。 - `LICENSE`:文件的许可证。 - 默认值为包的许可证(来自 `sbom_generate()` 的 `PACKAGE_LICENSE`)。 - 如果添加的是依赖项中的目标或文件,请指定其许可证。 - 有关此类情况的完整签名,请参见完整签名。 - `COPYRIGHT`: - 默认值为包的版权(来自 `sbom_generate()` 的 `PACKAGE_COPYRIGHT`)。 - 如果添加的是依赖项中的目标或文件,请指定其版权信息。 - 使用 `NOASSERTION` 或 `NONE` 表示无法确定或未指定该信息。 - `RELATIONSHIP`: - 描述 SBOM 组件之间关系的一个或多个字符串。 - 默认值为 ` CONTAINS `。 - `` 和 `` 是自动生成的 SPDX 标识符占位符。 - 使用此参数覆盖默认行为。请参见[SPDX 第 11 条款](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/)了解更多信息。 ### sbom_add_package ``` sbom_add_package( LICENSE VERSION SUPPLIER [EMAIL ] [RELATIONSHIP ...] ... ) ``` - `name`:包的名称。 - `LICENSE`:包的许可证。 - 如许可证未指定、无法确定或包含例外,请参见完整签名。 - `VERSION`:包的版本。 - `SUPPLIER`:包的提供者。 - 必须提供 `` 之一。 - `EMAIL` 可选。 - `RELATIONSHIP`: - 描述 SBOM 组件之间关系的一个或多个字符串。 - 默认值为: - ` DEPENDS_ON ` - ` CONTAINS NOASSERTION`。 - `` 和 `` 是自动生成的 SPDX 标识符占位符。 - 使用此参数覆盖默认行为。请参见[SPDX 第 11 条款](https://spdx.github.io/spdx-spec/v2.3/relationships-between-SPDX-elements/)了解更多信息。 - 示例:在下面的示例中,依赖项 `cxxopts` 仅被 `cli` 使用,而非整个包。关系可以按如下方式覆盖: ``` 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}` 设置为最后一个添加的文件/包/目标的 SPDX 标识符。 - `@SBOM_LAST_SPDXID@` 是 `cxxopts` 生成的 SPDX 标识符的占位符。 ### sbom_add_external ``` sbom_add_external( [RENAME ] [RELATIONSHIP ...] [SPDXID ] ) ``` - `id`:外部文件中包的 SPDX 标识符。 - `path`:引用另一个 SPDX 文件作为外部文档引用。然后依赖该文档中指定的包。外部 SPDX 文件将复制到 SBOM 旁边。支持生成器表达式。 - `RENAME`:将外部文档重命名为给定文件名(不含目录)。 - `SPDXID`:外部文档的标识符,用作包标识符的前缀。默认为唯一标识符。包标识符会自动添加。变量 `SBOM_LAST_SPDXID` 会被设置为使用的标识符。 - `RELATIONSHIP`: - 描述 SBOM 组件之间关系的一个或多个字符串。 - 默认为 ` DEPENDS_ON `。 - `` 是生成描述整个包的 SPDXID 的占位符。 ### sbom_finalize 完成 SBOM 定义。 ``` sbom_finalize() ``` ### sbom_spdxid ***这通常不应直接使用。*** 所有 `sbom_add_*` 函数都会自动调用此函数来生成唯一的 SPDX 标识符。 生成唯一的 SPDX 标识符。 ``` sbom_spdxid( VARIABLE [CHECK | HINTS ...] ) ``` - `VARIABLE`:用于生成唯一 SDPX 标识符的输出变量。 - `CHECK`:验证并返回给定的标识符。 - `HINTS`:一个或多个提示,转换为有效的标识符。第一个非空提示将被使用。如果未指定提示,则返回一个格式未指定的唯一标识符。 ## 版本提取 版本提取包含在 `sbom.cmake` 中,并由 `sbom_generate()` 函数用于在 SPDX 文档中填充版本信息。它也可在项目中使用。 ### version_extract() 此函数在当前范围内为当前项目设置以下变量: - `GIT_HASH`:完整的 Git 哈希值。 - `GIT_HASH_SHORT`:短 Git 哈希值。 - `GIT_VERSION`: - 如果当前提交有标签,标签名称:`v1.2.3` - 如果没有标签,`git-describe` + 分支:`v1.2.3-4-g1234567+feature/xyz` - 如果有修改,`+dirty` 后缀会添加到两种情况中:`v1.2.3-4-g1234567+feature/xyz+dirty` 或 `v1.2.3+dirty` - 我们对“脏”的判定非常严格,即使未跟踪的文件也会被视为脏。 - `GIT_VERSION_PATH`: - `GIT_VERSION` 的值,但可用于文件名。 - 例如,`v1.2.3-4-g1234567+feature/xyz+dirty` 会变成 `v1.2.3-4-g1234567+feature_xyz+dirty` - `VERSION_TIMESTAMP`:当前构建时间。 此外,如果 `GIT_VERSION` 以符合[语义化版本 2.0.0](https://semver.org/)(可选带 `v` 前缀)的标签开头,则会设置以下变量: - `GIT_VERSION_TRIPLET`:从 `GIT_VERSION` 提取的 major.minor.patch 三元组。 - 例如,`v1.2.3-4-g1234567+feature/xyz+dirty` -> `1.2.3` - `GIT_VERSION_MAJOR`:`GIT_VERSION_TRIPLET` 的主版本号。 - `GIT_VERSION_MINOR`:`GIT_VERSION_TRIPLET` 的次版本号。 - `GIT_VERSION_PATCH`:`GIT_VERSION_TRIPLET` 的修订号。 - `GIT_VERSION_SUFFIX`:三元组之后的所有内容。 - 例如,`v1.2.3-4-g1234567+feature/xyz+dirty` -> `-4-g1234567+feature/xyz+dirty` ### version_generate() 此函数生成以下文件,其中包含上述变量: - `version.[sh|ps1]`:设置环境变量的脚本文件。 - `version.txt`:用于文档的文本文件。 - 仅包含 `GIT_VERSION` 变量。 - `${PROJECT_NAME}-version`:一个接口库目标,提供单个头文件 `${PROJECT_NAME}-version.h`。 - **注意**:变量以 `${PROJECT_NAME}_` 为前缀,而不是 `GIT_`。 - 链接目标 `${PROJECT_NAME}-version` 并包含 `${PROJECT_NAME}-version.h` 以在 C/C++ 中访问版本信息([示例](example/CMakeLists.txt))。 所有文件生成在 `${PROJECT_BINARY_DIR}/version/[scripts|include|doc]` 中。CMake 变量 `VERSION_SCRIPT_DIR`、`VERSION_INC_DIR` 和 `VERSION_DOC_DIR` 指向这些目录。 ## 兼容性策略 CMake 频繁发布新功能和改进,有时会弃用或取代旧功能。为了确保脚本保持功能并利用这些更新,我们将根据所支持的最旧的 Ubuntu LTS 版本同步更新最低要求的 CMake 版本。 截至撰写本文时,所支持的最旧 Ubuntu LTS 版本是 Ubuntu 20.04,其包含 CMake 3.16。当对 Ubuntu 20.04 的支持在 2025 年 5 月结束后,我们将更新最低要求版本以与下一个最旧的受支持 Ubuntu LTS 版本对齐。(Ubuntu 22.04,包含 CMake 3.22) 我们的测试策略也将与此方法保持一致。 我们相信这种方法在确保稳定和长期平台用户的广泛兼容性与利用 CMake 的更新功能和改进之间取得了平衡。 ## 许可证 本仓库中的大部分代码采用 MIT 许可证。 ## 致谢 我们感谢该项目的原始作者和贡献者的辛勤工作。他们的努力为此分支提供了坚实的基础。
标签:Bash脚本, C/C++, CMake, Cutter, Git版本信息, Ninja, NIST, SBOM, SEO, SPDX, TR-03183, Visual Studio, 事务性I/O, 单文件集成, 合规指南, 多配置生成器, 开源合规, 构建系统, 版本提取, 硬件无关, 网络安全, 跌倒检测, 软件物料清单, 隐私保护