public inbox for linux-kbuild@vger.kernel.org
 help / color / mirror / Atom feed
From: Luis Augenstein <luis.augenstein@tngtech.com>
To: nathan@kernel.org, nsc@kernel.org
Cc: linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
	akpm@linux-foundation.org, gregkh@linuxfoundation.org,
	maximilian.huber@tngtech.com,
	Luis Augenstein <luis.augenstein@tngtech.com>
Subject: [PATCH v2 11/14] tools/sbom: add SPDX source graph
Date: Tue, 20 Jan 2026 12:53:49 +0100	[thread overview]
Message-ID: <20260120115352.10910-12-luis.augenstein@tngtech.com> (raw)
In-Reply-To: <20260120115352.10910-1-luis.augenstein@tngtech.com>

Implement the SPDX source graph which contains all source files
involved during the build, along with the licensing information
for each file.

Co-developed-by: Maximilian Huber <maximilian.huber@tngtech.com>
Signed-off-by: Maximilian Huber <maximilian.huber@tngtech.com>
Signed-off-by: Luis Augenstein <luis.augenstein@tngtech.com>
---
 .../sbom/sbom/spdx_graph/build_spdx_graphs.py |   8 ++
 .../sbom/sbom/spdx_graph/spdx_source_graph.py | 126 ++++++++++++++++++
 2 files changed, 134 insertions(+)
 create mode 100644 tools/sbom/sbom/spdx_graph/spdx_source_graph.py

diff --git a/tools/sbom/sbom/spdx_graph/build_spdx_graphs.py b/tools/sbom/sbom/spdx_graph/build_spdx_graphs.py
index 2af0fbe6cdbe..a61257a905f3 100644
--- a/tools/sbom/sbom/spdx_graph/build_spdx_graphs.py
+++ b/tools/sbom/sbom/spdx_graph/build_spdx_graphs.py
@@ -10,6 +10,7 @@ from sbom.path_utils import PathStr
 from sbom.spdx_graph.kernel_file import KernelFileCollection
 from sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
 from sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
+from sbom.spdx_graph.spdx_source_graph import SpdxSourceGraph
 from sbom.spdx_graph.spdx_output_graph import SpdxOutputGraph
 
 
@@ -54,4 +55,11 @@ def build_spdx_graphs(
         KernelSpdxDocumentKind.OUTPUT: output_graph,
     }
 
+    if len(kernel_files.source) > 0:
+        spdx_graphs[KernelSpdxDocumentKind.SOURCE] = SpdxSourceGraph.create(
+            source_files=list(kernel_files.source.values()),
+            shared_elements=shared_elements,
+            spdx_id_generators=spdx_id_generators,
+        )
+
     return spdx_graphs
diff --git a/tools/sbom/sbom/spdx_graph/spdx_source_graph.py b/tools/sbom/sbom/spdx_graph/spdx_source_graph.py
new file mode 100644
index 000000000000..16176c4ea5ee
--- /dev/null
+++ b/tools/sbom/sbom/spdx_graph/spdx_source_graph.py
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: GPL-2.0-only OR MIT
+# Copyright (C) 2025 TNG Technology Consulting GmbH
+
+from dataclasses import dataclass
+from sbom.spdx import SpdxIdGenerator
+from sbom.spdx.core import Element, NamespaceMap, Relationship, SpdxDocument
+from sbom.spdx.simplelicensing import LicenseExpression
+from sbom.spdx.software import File, Sbom
+from sbom.spdx_graph.kernel_file import KernelFile
+from sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
+from sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
+
+
+@dataclass
+class SpdxSourceGraph(SpdxGraph):
+    """SPDX graph representing source files"""
+
+    @classmethod
+    def create(
+        cls,
+        source_files: list[KernelFile],
+        shared_elements: SharedSpdxElements,
+        spdx_id_generators: SpdxIdGeneratorCollection,
+    ) -> "SpdxSourceGraph":
+        """
+        Args:
+            source_files: List of files within the kernel source tree.
+            shared_elements: Shared SPDX elements used across multiple documents.
+            spdx_id_generators: Collection of SPDX ID generators.
+
+        Returns:
+            SpdxSourceGraph: The SPDX source graph.
+        """
+        # SpdxDocument
+        source_spdx_document = SpdxDocument(
+            spdxId=spdx_id_generators.source.generate(),
+            profileConformance=["core", "software", "simpleLicensing"],
+            namespaceMap=[
+                NamespaceMap(prefix=generator.prefix, namespace=generator.namespace)
+                for generator in [spdx_id_generators.source, spdx_id_generators.base]
+                if generator.prefix is not None
+            ],
+        )
+
+        # Sbom
+        source_sbom = Sbom(
+            spdxId=spdx_id_generators.source.generate(),
+            software_sbomType=["source"],
+        )
+
+        # Src Tree Elements
+        src_tree_element = File(
+            spdxId=spdx_id_generators.source.generate(),
+            name="$(src_tree)",
+            software_fileKind="directory",
+        )
+        src_tree_contains_relationship = Relationship(
+            spdxId=spdx_id_generators.source.generate(),
+            relationshipType="contains",
+            from_=src_tree_element,
+            to=[],
+        )
+
+        # Source file elements
+        source_file_elements: list[Element] = [file.spdx_file_element for file in source_files]
+
+        # Source file license elements
+        source_file_license_identifiers, source_file_license_relationships = source_file_license_elements(
+            source_files, spdx_id_generators.source
+        )
+
+        # Update relationships
+        source_spdx_document.rootElement = [source_sbom]
+        source_sbom.rootElement = [src_tree_element]
+        source_sbom.element = [
+            src_tree_element,
+            src_tree_contains_relationship,
+            *source_file_elements,
+            *source_file_license_identifiers,
+            *source_file_license_relationships,
+        ]
+        src_tree_contains_relationship.to = source_file_elements
+
+        source_graph = SpdxSourceGraph(
+            source_spdx_document,
+            shared_elements.agent,
+            shared_elements.creation_info,
+            source_sbom,
+        )
+        return source_graph
+
+
+def source_file_license_elements(
+    source_files: list[KernelFile], spdx_id_generator: SpdxIdGenerator
+) -> tuple[list[LicenseExpression], list[Relationship]]:
+    """
+    Creates SPDX license expressions and links them to the given source files
+    via hasDeclaredLicense relationships.
+
+    Args:
+        source_files: List of files within the kernel source tree.
+        spdx_id_generator: Generator for unique SPDX IDs.
+
+    Returns:
+        Tuple of (license expressions, hasDeclaredLicense relationships).
+    """
+    license_expressions: dict[str, LicenseExpression] = {}
+    for file in source_files:
+        if file.license_identifier is None or file.license_identifier in license_expressions:
+            continue
+        license_expressions[file.license_identifier] = LicenseExpression(
+            spdxId=spdx_id_generator.generate(),
+            simplelicensing_licenseExpression=file.license_identifier,
+        )
+
+    source_file_license_relationships = [
+        Relationship(
+            spdxId=spdx_id_generator.generate(),
+            relationshipType="hasDeclaredLicense",
+            from_=file.spdx_file_element,
+            to=[license_expressions[file.license_identifier]],
+        )
+        for file in source_files
+        if file.license_identifier is not None
+    ]
+    return ([*license_expressions.values()], source_file_license_relationships)
-- 
2.34.1


  parent reply	other threads:[~2026-01-20 11:55 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-20 11:53 [PATCH v2 00/14] Add SPDX SBOM generation tool Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 01/14] tools/sbom: integrate tool in make process Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 02/14] tools/sbom: setup sbom logging Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 03/14] tools/sbom: add command parsers Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 04/14] tools/sbom: add cmd graph generation Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 05/14] tools/sbom: add additional dependency sources for cmd graph Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 06/14] tools/sbom: add SPDX classes Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 07/14] tools/sbom: add JSON-LD serialization Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 08/14] tools/sbom: add shared SPDX elements Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 09/14] tools/sbom: collect file metadata Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 10/14] tools/sbom: add SPDX output graph Luis Augenstein
2026-01-20 11:53 ` Luis Augenstein [this message]
2026-01-20 11:53 ` [PATCH v2 12/14] tools/sbom: add SPDX build graph Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 13/14] tools/sbom: add unit tests for command parsers Luis Augenstein
2026-01-22  6:00   ` Miguel Ojeda
2026-01-22 20:01     ` Luis Augenstein
2026-01-20 11:53 ` [PATCH v2 14/14] tools/sbom: add unit tests for SPDX-License-Identifier parsing Luis Augenstein
2026-01-20 15:40 ` [PATCH v2 00/14] Add SPDX SBOM generation tool Greg KH
2026-01-20 16:14   ` Luis Augenstein
2026-01-22  6:18 ` Miguel Ojeda
2026-01-22  6:35   ` Greg KH
2026-01-25 15:20     ` Miguel Ojeda
2026-01-25 15:33       ` Miguel Ojeda
2026-01-25 15:40         ` Greg KH
2026-01-25 15:34       ` Greg KH
2026-01-25 17:24         ` Miguel Ojeda
2026-01-27  8:03           ` Luis Augenstein
2026-01-27 23:10             ` Nathan Chancellor
2026-02-02 16:28               ` Luis Augenstein
2026-02-03  0:40                 ` Nathan Chancellor
2026-02-03 14:41                   ` Luis Augenstein
2026-02-03 20:51                     ` Nathan Chancellor
2026-01-22 20:32   ` Luis Augenstein
2026-01-25 15:30     ` Miguel Ojeda
2026-01-26  6:46       ` Luis Augenstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260120115352.10910-12-luis.augenstein@tngtech.com \
    --to=luis.augenstein@tngtech.com \
    --cc=akpm@linux-foundation.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maximilian.huber@tngtech.com \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox