€•>ŒŒsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ#/translations/zh_CN/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/zh_TW/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/it_IT/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/ja_JP/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/ko_KR/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/pt_BR/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ#/translations/sp_SP/tools/sbom/sbom”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ,SPDX-License-Identifier: GPL-2.0-only OR MIT”h]”hŒ,SPDX-License-Identifier: GPL-2.0-only OR MIT”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³Œ=/var/lib/git/docbuild/linux/Documentation/tools/sbom/sbom.rst”h´Kubh¶)”}”(hŒ1Copyright (C) 2025 TNG Technology Consulting GmbH”h]”hŒ1Copyright (C) 2025 TNG Technology Consulting GmbH”…””}”hhÈsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hµhhh²hh³hÇh´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ KernelSbom”h]”hŒ KernelSbom”…””}”(hhÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hhîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhëh²hh³hÇh´KubhŒ paragraph”“”)”}”(hX$KernelSbom is a Python script ``scripts/sbom/sbom.py`` that can be executed after a successful kernel build. When invoked, KernelSbom analyzes all files involved in the build and generates Software Bill of Materials (SBOM) documents in SPDX 3.0.1 format. The generated SBOM documents capture:”h]”(hŒKernelSbom is a Python script ”…””}”(hhþh²hh³Nh´NubhŒliteral”“”)”}”(hŒ``scripts/sbom/sbom.py``”h]”hŒscripts/sbom/sbom.py”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhhþubhŒî that can be executed after a successful kernel build. When invoked, KernelSbom analyzes all files involved in the build and generates Software Bill of Materials (SBOM) documents in SPDX 3.0.1 format. The generated SBOM documents capture:”…””}”(hhþh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K hhëh²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒB**Final output artifacts**, typically the kernel image and modules”h]”hý)”}”(hj)h]”(hŒstrong”“”)”}”(hŒ**Final output artifacts**”h]”hŒFinal output artifacts”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hj+ubhŒ(, typically the kernel image and modules”…””}”(hj+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khj'ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"h²hh³hÇh´Nubj&)”}”(hŒZ**All source files** that contributed to the build with metadata and licensing information”h]”hý)”}”(hŒZ**All source files** that contributed to the build with metadata and licensing information”h]”(j/)”}”(hŒ**All source files**”h]”hŒAll source files”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hjRubhŒF that contributed to the build with metadata and licensing information”…””}”(hjRh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KhjNubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"h²hh³hÇh´Nubj&)”}”(hŒ**Details of the build process**, including intermediate artifacts and the build commands linking source files to the final output artifacts ”h]”hý)”}”(hŒŒ**Details of the build process**, including intermediate artifacts and the build commands linking source files to the final output artifacts”h]”(j/)”}”(hŒ **Details of the build process**”h]”hŒDetails of the build process”…””}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hjxubhŒl, including intermediate artifacts and the build commands linking source files to the final output artifacts”…””}”(hjxh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khjtubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j h³hÇh´Khhëh²hubhý)”}”(hŒgKernelSbom is originally developed in the `KernelSbom repository `_.”h]”(hŒ*KernelSbom is originally developed in the ”…””}”(hj¢h²hh³Nh´NubhŒ reference”“”)”}”(hŒ<`KernelSbom repository `_”h]”hŒKernelSbom repository”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒKernelSbom repository”Œrefuri”Œ!https://github.com/TNG/KernelSbom”uh1jªhj¢ubhŒtarget”“”)”}”(hŒ$ ”h]”h}”(h]”Œkernelsbom-repository”ah ]”h"]”Œkernelsbom repository”ah$]”h&]”Œrefuri”j½uh1j¾Œ referenced”Khj¢ubhŒ.”…””}”(hj¢h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khhëh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ Requirements”h]”hŒ Requirements”…””}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjàh²hh³hÇh´Kubhý)”}”(hŒFPython 3.10 or later. No libraries or other dependencies are required.”h]”hŒFPython 3.10 or later. No libraries or other dependencies are required.”…””}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khjàh²hubeh}”(h]”Œ requirements”ah ]”h"]”Œ requirements”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ Basic Usage”h]”hŒ Basic Usage”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjh²hh³hÇh´K ubhý)”}”(hŒ+Run the ``make sbom`` target. For example::”h]”(hŒRun the ”…””}”(hjh²hh³Nh´Nubj)”}”(hŒ ``make sbom``”h]”hŒ make sbom”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ target. For example:”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K"hjh²hubhŒ literal_block”“”)”}”(hŒE$ make defconfig O=kernel_build $ make sbom O=kernel_build -j$(nproc)”h]”hŒE$ make defconfig O=kernel_build $ make sbom O=kernel_build -j$(nproc)”…””}”hj:sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j8h³hÇh´K%hjh²hubhý)”}”(hŒ¡This will trigger a kernel build. After all build outputs have been generated, KernelSbom produces three SPDX documents in the root directory of the object tree:”h]”hŒ¡This will trigger a kernel build. After all build outputs have been generated, KernelSbom produces three SPDX documents in the root directory of the object tree:”…””}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K(hjh²hubj!)”}”(hhh]”(j&)”}”(hŒ``sbom-source.spdx.json`` Describes all source files involved in the build and associates each file with its corresponding license expression. ”h]”hý)”}”(hŒŽ``sbom-source.spdx.json`` Describes all source files involved in the build and associates each file with its corresponding license expression.”h]”(j)”}”(hŒ``sbom-source.spdx.json``”h]”hŒsbom-source.spdx.json”…””}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj]ubhŒu Describes all source files involved in the build and associates each file with its corresponding license expression.”…””}”(hj]h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K,hjYubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjVh²hh³hÇh´Nubj&)”}”(hŒÔ``sbom-output.spdx.json`` Captures all final build outputs (kernel image and ``.ko`` module files) and includes build metadata such as environment variables and a hash of the ``.config`` file used for the build. ”h]”hý)”}”(hŒÓ``sbom-output.spdx.json`` Captures all final build outputs (kernel image and ``.ko`` module files) and includes build metadata such as environment variables and a hash of the ``.config`` file used for the build.”h]”(j)”}”(hŒ``sbom-output.spdx.json``”h]”hŒsbom-output.spdx.json”…””}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjƒubhŒ4 Captures all final build outputs (kernel image and ”…””}”(hjƒh²hh³Nh´Nubj)”}”(hŒ``.ko``”h]”hŒ.ko”…””}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjƒubhŒ[ module files) and includes build metadata such as environment variables and a hash of the ”…””}”(hjƒh²hh³Nh´Nubj)”}”(hŒ ``.config``”h]”hŒ.config”…””}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjƒubhŒ file used for the build.”…””}”(hjƒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K0hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjVh²hh³hÇh´Nubj&)”}”(hX``sbom-build.spdx.json`` Imports files from the source and output documents and describes every intermediate build artifact. For each artifact, it records the exact build command used and establishes the relationship between input files and generated outputs. ”h]”hý)”}”(hX``sbom-build.spdx.json`` Imports files from the source and output documents and describes every intermediate build artifact. For each artifact, it records the exact build command used and establishes the relationship between input files and generated outputs.”h]”(j)”}”(hŒ``sbom-build.spdx.json``”h]”hŒsbom-build.spdx.json”…””}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÍubhŒë Imports files from the source and output documents and describes every intermediate build artifact. For each artifact, it records the exact build command used and establishes the relationship between input files and generated outputs.”…””}”(hjÍh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K5hjÉubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjVh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j j¡uh1j h³hÇh´K,hjh²hubhý)”}”(hXÏWhen invoking the sbom target, it is recommended to perform out-of-tree builds using ``O=``. KernelSbom classifies files as source files when they are located in the source tree and not in the object tree. For in-tree builds, where the source and object trees are the same directory, this distinction can no longer be made reliably. In that case, KernelSbom does not generate a dedicated source SBOM. Instead, source files are included in the build SBOM.”h]”(hŒUWhen invoking the sbom target, it is recommended to perform out-of-tree builds using ”…””}”(hjõh²hh³Nh´Nubj)”}”(hŒ``O=``”h]”hŒ O=”…””}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjõubhXk. KernelSbom classifies files as source files when they are located in the source tree and not in the object tree. For in-tree builds, where the source and object trees are the same directory, this distinction can no longer be made reliably. In that case, KernelSbom does not generate a dedicated source SBOM. Instead, source files are included in the build SBOM.”…””}”(hjõh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K;hjh²hubeh}”(h]”Œ basic-usage”ah ]”h"]”Œ basic usage”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K ubh×)”}”(hhh]”(hÜ)”}”(hŒStandalone Usage”h]”hŒStandalone Usage”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjh²hh³hÇh´KDubhý)”}”(hŒåKernelSbom can also be used as a standalone script to generate SPDX documents for specific build outputs. For example, after a successful x86 kernel build, KernelSbom can generate SPDX documents for the ``bzImage`` kernel image::”h]”(hŒËKernelSbom can also be used as a standalone script to generate SPDX documents for specific build outputs. For example, after a successful x86 kernel build, KernelSbom can generate SPDX documents for the ”…””}”(hj.h²hh³Nh´Nubj)”}”(hŒ ``bzImage``”h]”hŒbzImage”…””}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj.ubhŒ kernel image:”…””}”(hj.h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KFhjh²hubj9)”}”(hŒ×$ SRCARCH=x86 python3 scripts/sbom/sbom.py \ --src-tree . \ --obj-tree ./kernel_build \ --roots arch/x86/boot/bzImage \ --generate-spdx \ --generate-used-files \ --prettify-json \ --debug”h]”hŒ×$ SRCARCH=x86 python3 scripts/sbom/sbom.py \ --src-tree . \ --obj-tree ./kernel_build \ --roots arch/x86/boot/bzImage \ --generate-spdx \ --generate-used-files \ --prettify-json \ --debug”…””}”hjNsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j8h³hÇh´KKhjh²hubhý)”}”(hXINote that when KernelSbom is invoked outside of the ``make`` process, the environment variables used during compilation are not available and therefore cannot be included in the generated SPDX documents. It is recommended to set at least the ``SRCARCH`` environment variable to the architecture for which the build was performed.”h]”(hŒ4Note that when KernelSbom is invoked outside of the ”…””}”(hj\h²hh³Nh´Nubj)”}”(hŒ``make``”h]”hŒmake”…””}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj\ubhŒ¶ process, the environment variables used during compilation are not available and therefore cannot be included in the generated SPDX documents. It is recommended to set at least the ”…””}”(hj\h²hh³Nh´Nubj)”}”(hŒ ``SRCARCH``”h]”hŒSRCARCH”…””}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj\ubhŒL environment variable to the architecture for which the build was performed.”…””}”(hj\h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KThjh²hubhý)”}”(hŒ.For a full list of command-line options, run::”h]”hŒ-For a full list of command-line options, run:”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KZhjh²hubj9)”}”(hŒ%$ python3 scripts/sbom/sbom.py --help”h]”hŒ%$ python3 scripts/sbom/sbom.py --help”…””}”hjœsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j8h³hÇh´K\hjh²hubeh}”(h]”Œstandalone-usage”ah ]”h"]”Œstandalone usage”ah$]”h&]”uh1hÖhhØh²hh³hÇh´KDubh×)”}”(hhh]”(hÜ)”}”(hŒ Output Format”h]”hŒ Output Format”…””}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj²h²hh³hÇh´K_ubhý)”}”(hŒŽKernelSbom generates documents conforming to the `SPDX 3.0.1 specification `_ serialized as JSON-LD.”h]”(hŒ1KernelSbom generates documents conforming to the ”…””}”(hjÃh²hh³Nh´Nubj«)”}”(hŒF`SPDX 3.0.1 specification `_”h]”hŒSPDX 3.0.1 specification”…””}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒSPDX 3.0.1 specification”j¼Œ(https://spdx.github.io/spdx-spec/v3.0.1/”uh1jªhjÃubj¿)”}”(hŒ+ ”h]”h}”(h]”Œspdx-3-0-1-specification”ah ]”h"]”Œspdx 3.0.1 specification”ah$]”h&]”Œrefuri”jÛuh1j¾jÍKhjÃubhŒ serialized as JSON-LD.”…””}”(hjÃh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kahj²h²hubhý)”}”(hXÐTo reduce file size, the output documents use the JSON-LD ``@context`` to define custom prefixes for ``spdxId`` values. While this is compliant with the SPDX specification, only a limited number of tools in the current SPDX ecosystem support custom JSON-LD contexts. To use such tools with the generated documents, the custom JSON-LD context must be expanded before providing the documents. See https://lists.spdx.org/g/Spdx-tech/message/6064 for more information.”h]”(hŒ:To reduce file size, the output documents use the JSON-LD ”…””}”(hjóh²hh³Nh´Nubj)”}”(hŒ ``@context``”h]”hŒ@context”…””}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjóubhŒ to define custom prefixes for ”…””}”(hjóh²hh³Nh´Nubj)”}”(hŒ ``spdxId``”h]”hŒspdxId”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjóubhX values. While this is compliant with the SPDX specification, only a limited number of tools in the current SPDX ecosystem support custom JSON-LD contexts. To use such tools with the generated documents, the custom JSON-LD context must be expanded before providing the documents. See ”…””}”(hjóh²hh³Nh´Nubj«)”}”(hŒ/https://lists.spdx.org/g/Spdx-tech/message/6064”h]”hŒ/https://lists.spdx.org/g/Spdx-tech/message/6064”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j!uh1jªhjóubhŒ for more information.”…””}”(hjóh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kehj²h²hubeh}”(h]”Œ output-format”ah ]”h"]”Œ output format”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K_ubh×)”}”(hhh]”(hÜ)”}”(hŒ How it Works”h]”hŒ How it Works”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj@h²hh³hÇh´Knubhý)”}”(hŒ(KernelSbom operates in two major phases:”h]”hŒ(KernelSbom operates in two major phases:”…””}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kphj@h²hubhŒenumerated_list”“”)”}”(hhh]”(j&)”}”(hŒA**Generate the cmd graph**, an acyclic directed dependency graph.”h]”hý)”}”(hjfh]”(j/)”}”(hŒ**Generate the cmd graph**”h]”hŒGenerate the cmd graph”…””}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hjhubhŒ', an acyclic directed dependency graph.”…””}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Krhjdubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjah²hh³hÇh´Nubj&)”}”(hŒ4**Generate SPDX documents** based on the cmd graph. ”h]”hý)”}”(hŒ3**Generate SPDX documents** based on the cmd graph.”h]”(j/)”}”(hŒ**Generate SPDX documents**”h]”hŒGenerate SPDX documents”…””}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hjubhŒ based on the cmd graph.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kshj‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjah²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1j_hj@h²hh³hÇh´Krubhý)”}”(hŒäKernelSbom begins from the root artifacts specified by the user, e.g., ``arch/x86/boot/bzImage``. For each root artifact, it collects all dependencies required to build that artifact. The dependencies come from multiple sources:”h]”(hŒGKernelSbom begins from the root artifacts specified by the user, e.g., ”…””}”(hjºh²hh³Nh´Nubj)”}”(hŒ``arch/x86/boot/bzImage``”h]”hŒarch/x86/boot/bzImage”…””}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjºubhŒ„. For each root artifact, it collects all dependencies required to build that artifact. The dependencies come from multiple sources:”…””}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kuhj@h²hubj!)”}”(hhh]”(j&)”}”(hXA**.cmd files**: The primary source is the ``.cmd`` file of the generated artifact, e.g., ``arch/x86/boot/.bzImage.cmd``. These files contain the exact command used to build the artifact and often include an explicit list of input dependencies. By parsing the ``.cmd`` file, the full list of dependencies can be obtained. ”h]”hý)”}”(hX@**.cmd files**: The primary source is the ``.cmd`` file of the generated artifact, e.g., ``arch/x86/boot/.bzImage.cmd``. These files contain the exact command used to build the artifact and often include an explicit list of input dependencies. By parsing the ``.cmd`` file, the full list of dependencies can be obtained.”h]”(j/)”}”(hŒ**.cmd files**”h]”hŒ .cmd files”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hjáubhŒ: The primary source is the ”…””}”(hjáh²hh³Nh´Nubj)”}”(hŒ``.cmd``”h]”hŒ.cmd”…””}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjáubhŒ' file of the generated artifact, e.g., ”…””}”(hjáh²hh³Nh´Nubj)”}”(hŒ``arch/x86/boot/.bzImage.cmd``”h]”hŒarch/x86/boot/.bzImage.cmd”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjáubhŒŒ. These files contain the exact command used to build the artifact and often include an explicit list of input dependencies. By parsing the ”…””}”(hjáh²hh³Nh´Nubj)”}”(hŒ``.cmd``”h]”hŒ.cmd”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjáubhŒ5 file, the full list of dependencies can be obtained.”…””}”(hjáh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KzhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjÚh²hh³hÇh´Nubj&)”}”(hŒn**.incbin statements**: The second source are include binary ``.incbin`` statements in ``.S`` assembly files. ”h]”hý)”}”(hŒm**.incbin statements**: The second source are include binary ``.incbin`` statements in ``.S`` assembly files.”h]”(j/)”}”(hŒ**.incbin statements**”h]”hŒ.incbin statements”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hj=ubhŒ': The second source are include binary ”…””}”(hj=h²hh³Nh´Nubj)”}”(hŒ ``.incbin``”h]”hŒ.incbin”…””}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj=ubhŒ statements in ”…””}”(hj=h²hh³Nh´Nubj)”}”(hŒ``.S``”h]”hŒ.S”…””}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj=ubhŒ assembly files.”…””}”(hj=h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K€hj9ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjÚh²hh³hÇh´Nubj&)”}”(hXž**Hardcoded dependencies**: Unfortunately, not all build dependencies can be found via ``.cmd`` files and ``.incbin`` statements. Some build dependencies are directly defined in Makefiles or Kbuild files. Parsing these files is considered too complex for the scope of this project. Instead, the remaining gaps of the graph are filled using a list of manually defined dependencies, see ``scripts/sbom/sbom/cmd_graph/hardcoded_dependencies.py``. This list is known to be incomplete. However, analysis of the cmd graph indicates a ~99% completeness. For more information about the completeness analysis, see `KernelSbom #95 `_. ”h]”hý)”}”(hX**Hardcoded dependencies**: Unfortunately, not all build dependencies can be found via ``.cmd`` files and ``.incbin`` statements. Some build dependencies are directly defined in Makefiles or Kbuild files. Parsing these files is considered too complex for the scope of this project. Instead, the remaining gaps of the graph are filled using a list of manually defined dependencies, see ``scripts/sbom/sbom/cmd_graph/hardcoded_dependencies.py``. This list is known to be incomplete. However, analysis of the cmd graph indicates a ~99% completeness. For more information about the completeness analysis, see `KernelSbom #95 `_.”h]”(j/)”}”(hŒ**Hardcoded dependencies**”h]”hŒHardcoded dependencies”…””}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j.hj‡ubhŒ=: Unfortunately, not all build dependencies can be found via ”…””}”(hj‡h²hh³Nh´Nubj)”}”(hŒ``.cmd``”h]”hŒ.cmd”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‡ubhŒ files and ”…””}”(hj‡h²hh³Nh´Nubj)”}”(hŒ ``.incbin``”h]”hŒ.incbin”…””}”(hj¯h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‡ubhX  statements. Some build dependencies are directly defined in Makefiles or Kbuild files. Parsing these files is considered too complex for the scope of this project. Instead, the remaining gaps of the graph are filled using a list of manually defined dependencies, see ”…””}”(hj‡h²hh³Nh´Nubj)”}”(hŒ9``scripts/sbom/sbom/cmd_graph/hardcoded_dependencies.py``”h]”hŒ5scripts/sbom/sbom/cmd_graph/hardcoded_dependencies.py”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‡ubhŒ£. This list is known to be incomplete. However, analysis of the cmd graph indicates a ~99% completeness. For more information about the completeness analysis, see ”…””}”(hj‡h²hh³Nh´Nubj«)”}”(hŒ?`KernelSbom #95 `_”h]”hŒKernelSbom #95”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒKernelSbom #95”j¼Œ+https://github.com/TNG/KernelSbom/issues/95”uh1jªhj‡ubj¿)”}”(hŒ. ”h]”h}”(h]”Œ kernelsbom-95”ah ]”h"]”Œkernelsbom #95”ah$]”h&]”Œrefuri”jãuh1j¾jÍKhj‡ubhŒ.”…””}”(hj‡h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kƒhjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjÚh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j j¡uh1j h³hÇh´Kzhj@h²hubhý)”}”(hX.Given the list of dependency files, KernelSbom recursively processes each file, expanding the dependency chain all the way to the version controlled source files. The result is a complete dependency graph where nodes represent files, and edges represent "file A was used to build file B" relationships.”h]”hX2Given the list of dependency files, KernelSbom recursively processes each file, expanding the dependency chain all the way to the version controlled source files. The result is a complete dependency graph where nodes represent files, and edges represent “file A was used to build file B†relationships.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KŽhj@h²hubhý)”}”(hŒgUsing the cmd graph, KernelSbom produces three SPDX documents. For every file in the graph, KernelSbom:”h]”hŒgUsing the cmd graph, KernelSbom produces three SPDX documents. For every file in the graph, KernelSbom:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K”hj@h²hubj!)”}”(hhh]”(j&)”}”(hŒ+Parses ``SPDX-License-Identifier`` headers,”h]”hý)”}”(hj(h]”(hŒParses ”…””}”(hj*h²hh³Nh´Nubj)”}”(hŒ``SPDX-License-Identifier``”h]”hŒSPDX-License-Identifier”…””}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj*ubhŒ headers,”…””}”(hj*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K—hj&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj#h²hh³hÇh´Nubj&)”}”(hŒComputes file hashes,”h]”hý)”}”(hjQh]”hŒComputes file hashes,”…””}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K˜hjOubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj#h²hh³hÇh´Nubj&)”}”(hŒ4Estimates the file type based on extension and path,”h]”hý)”}”(hjhh]”hŒ4Estimates the file type based on extension and path,”…””}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K™hjfubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj#h²hh³hÇh´Nubj&)”}”(hŒ+Records build relationships between files. ”h]”hý)”}”(hŒ*Records build relationships between files.”h]”hŒ*Records build relationships between files.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kšhj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj#h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j j¡uh1j h³hÇh´K—hj@h²hubhý)”}”(hŒEach root output file is additionally associated with an SPDX Package element that captures version information, license data, and copyright.”h]”hŒEach root output file is additionally associated with an SPDX Package element that captures version information, license data, and copyright.”…””}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kœhj@h²hubeh}”(h]”Œ how-it-works”ah ]”h"]”Œ how it works”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Knubh×)”}”(hhh]”(hÜ)”}”(hŒAdvanced Usage”h]”hŒAdvanced Usage”…””}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj±h²hh³hÇh´K ubh×)”}”(hhh]”(hÜ)”}”(hŒIncluding Kernel Modules”h]”hŒIncluding Kernel Modules”…””}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjÂh²hh³hÇh´K£ubhý)”}”(hŒ•The list of all ``.ko`` kernel modules produced during a build can be extracted from the ``modules.order`` file within the object tree. For example::”h]”(hŒThe list of all ”…””}”(hjÓh²hh³Nh´Nubj)”}”(hŒ``.ko``”h]”hŒ.ko”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÓubhŒB kernel modules produced during a build can be extracted from the ”…””}”(hjÓh²hh³Nh´Nubj)”}”(hŒ``modules.order``”h]”hŒ modules.order”…””}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÓubhŒ* file within the object tree. For example:”…””}”(hjÓh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K¥hjÂh²hubj9)”}”(hŒr$ echo "arch/x86/boot/bzImage" > sbom-roots.txt $ sed 's/\.o$/.ko/' ./kernel_build/modules.order >> sbom-roots.txt”h]”hŒr$ echo "arch/x86/boot/bzImage" > sbom-roots.txt $ sed 's/\.o$/.ko/' ./kernel_build/modules.order >> sbom-roots.txt”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j8h³hÇh´K©hjÂh²hubhý)”}”(hŒ#Then use the generated roots file::”h]”hŒ"Then use the generated roots file:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K¬hjÂh²hubj9)”}”(hŒ•$ SRCARCH=x86 python3 scripts/sbom/sbom.py \ --src-tree . \ --obj-tree ./kernel_build \ --roots-file sbom-roots.txt \ --generate-spdx”h]”hŒ•$ SRCARCH=x86 python3 scripts/sbom/sbom.py \ --src-tree . \ --obj-tree ./kernel_build \ --roots-file sbom-roots.txt \ --generate-spdx”…””}”hj!sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j8h³hÇh´K®hjÂh²hubeh}”(h]”Œincluding-kernel-modules”ah ]”h"]”Œincluding kernel modules”ah$]”h&]”uh1hÖhj±h²hh³hÇh´K£ubh×)”}”(hhh]”(hÜ)”}”(hŒEqual Source and Object Trees”h]”hŒEqual Source and Object Trees”…””}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj7h²hh³hÇh´Kµubhý)”}”(hX±When the source tree and object tree are identical (for example, when building in-tree), source files can no longer be reliably distinguished from generated files. In this scenario, KernelSbom does not produce a dedicated ``sbom-source.spdx.json`` document. Instead, both source files and build artifacts are included together in ``sbom-build.spdx.json``, and ``sbom.used-files.txt`` lists all files referenced in the build document.”h]”(hŒÞWhen the source tree and object tree are identical (for example, when building in-tree), source files can no longer be reliably distinguished from generated files. In this scenario, KernelSbom does not produce a dedicated ”…””}”(hjHh²hh³Nh´Nubj)”}”(hŒ``sbom-source.spdx.json``”h]”hŒsbom-source.spdx.json”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjHubhŒS document. Instead, both source files and build artifacts are included together in ”…””}”(hjHh²hh³Nh´Nubj)”}”(hŒ``sbom-build.spdx.json``”h]”hŒsbom-build.spdx.json”…””}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjHubhŒ, and ”…””}”(hjHh²hh³Nh´Nubj)”}”(hŒ``sbom.used-files.txt``”h]”hŒsbom.used-files.txt”…””}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjHubhŒ2 lists all files referenced in the build document.”…””}”(hjHh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K·hj7h²hubeh}”(h]”Œequal-source-and-object-trees”ah ]”h"]”Œequal source and object trees”ah$]”h&]”uh1hÖhj±h²hh³hÇh´Kµubh×)”}”(hhh]”(hÜ)”}”(hŒUnknown Build Commands”h]”hŒUnknown Build Commands”…””}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj”h²hh³hÇh´KÀubhý)”}”(hŒíBecause the kernel supports a wide range of configurations and versions, KernelSbom may encounter build commands in ``.cmd`` files that it does not yet support. By default, KernelSbom will fail if an unknown build command is encountered.”h]”(hŒtBecause the kernel supports a wide range of configurations and versions, KernelSbom may encounter build commands in ”…””}”(hj¥h²hh³Nh´Nubj)”}”(hŒ``.cmd``”h]”hŒ.cmd”…””}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¥ubhŒq files that it does not yet support. By default, KernelSbom will fail if an unknown build command is encountered.”…””}”(hj¥h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÂhj”h²hubhý)”}”(hŒñIf you still wish to generate SPDX documents despite unsupported commands, you can use the ``--do-not-fail-on-unknown-build-command`` option. KernelSbom will continue and produce the documents, although the resulting SBOM will be incomplete.”h]”(hŒ[If you still wish to generate SPDX documents despite unsupported commands, you can use the ”…””}”(hjÅh²hh³Nh´Nubj)”}”(hŒ*``--do-not-fail-on-unknown-build-command``”h]”hŒ&--do-not-fail-on-unknown-build-command”…””}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÅubhŒl option. KernelSbom will continue and produce the documents, although the resulting SBOM will be incomplete.”…””}”(hjÅh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÇhj”h²hubhý)”}”(hŒ‘This option should only be used when the missing portion of the dependency graph is small and an incomplete SBOM is acceptable for your use case.”h]”hŒ‘This option should only be used when the missing portion of the dependency graph is small and an incomplete SBOM is acceptable for your use case.”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÌhj”h²hubeh}”(h]”Œunknown-build-commands”ah ]”h"]”Œunknown build commands”ah$]”h&]”uh1hÖhj±h²hh³hÇh´KÀubeh}”(h]”Œadvanced-usage”ah ]”h"]”Œadvanced usage”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K ubeh}”(h]”Œ kernelsbom”ah ]”h"]”Œ kernelsbom”ah$]”h&]”uh1hÖhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÛNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j.Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jjjÝjÚjÉjÆjjjjj¯j¬j=j:jåjâj®j«jíjêjjýj4j1j‘jŽjøjõuŒ nametypes”}”(j‰j݉jɈj‰j‰j¯‰j=‰jåˆj®‰jíˆj‰j4‰j‘‰jø‰uh}”(jhØjÚhëjÆjÀjjàjjj¬jj:j²jâjÜj«j@jêjäjýj±j1jÂjŽj7jõj”uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.