@@ -124,6 +124,16 @@ SPDX_ON_BEHALF_OF[doc] = "The base variable name to describe the Agent on who's
SPDX_PACKAGE_SUPPLIER[doc] = "The base variable name to describe the Agent who \
is supplying artifacts produced by the build"
+SPDX_IMAGE_SUPPLIER[doc] = "The base variable name to describe the Agent who \
+ is supplying the image SBOM. The supplier will be set on all root elements \
+ of the image SBOM using the suppliedBy property. If not set, no supplier \
+ information will be added to the image SBOM."
+
+SPDX_SDK_SUPPLIER[doc] = "The base variable name to describe the Agent who \
+ is supplying the SDK SBOM. The supplier will be set on all root elements \
+ of the SDK SBOM using the suppliedBy property. If not set, no supplier \
+ information will be added to the SDK SBOM."
+
SPDX_PACKAGE_VERSION ??= "${PV}"
SPDX_PACKAGE_VERSION[doc] = "The version of a package, software_packageVersion \
in software_Package"
@@ -162,7 +162,7 @@ def add_package_files(
bb.debug(1, f"Total compiled files: {len(compiled_sources)}")
# File filtering configuration
- spdx_file_filter = (d.getVar("SPDX_FILE_FILTER") or "all").lower()
+ spdx_file_filter = (d.getVar("SPDX_FILES_INCLUDED") or "all").lower()
essential_patterns = (d.getVar("SPDX_FILE_ESSENTIAL_PATTERNS") or "").split()
exclude_patterns = (d.getVar("SPDX_FILE_EXCLUDE_PATTERNS") or "").split()
@@ -244,7 +244,7 @@ def add_package_files(
def get_package_sources_from_debug(
d, package, package_files, sources, source_hash_cache
):
- spdx_file_filter = (d.getVar("SPDX_FILE_FILTER") or "all").lower()
+ spdx_file_filter = (d.getVar("SPDX_FILES_INCLUDED") or "all").lower()
def file_path_match(file_path, pkg_file):
if file_path.lstrip("/") == pkg_file.name.lstrip("/"):
@@ -283,7 +283,7 @@ def get_package_sources_from_debug(
if spdx_file_filter in ("none", "essential"):
bb.debug(
1,
- f"Skipping debug source lookup for {file_path} in {package} (filtered by SPDX_FILE_FILTER={spdx_file_filter})",
+ f"Skipping debug source lookup for {file_path} in {package} (filtered by SPDX_FILES_INCLUDED={spdx_file_filter})",
)
continue
else:
@@ -663,7 +663,13 @@ def create_spdx(d):
force_purposes=["install"],
)
- supplier = build_objset.new_agent("SPDX_PACKAGE_SUPPLIER")
+ # Follow the same pattern as SPDX_AUTHORS: get identifier, build varname, then call new_agent
+ supplier_id_val = d.getVar("SPDX_PACKAGE_SUPPLIER")
+ if supplier_id_val:
+ supplier_varname = f"SPDX_PACKAGE_SUPPLIER_{supplier_id_val}"
+ supplier = build_objset.new_agent(supplier_varname)
+ else:
+ supplier = None
if supplier is not None:
spdx_package.suppliedBy = (
supplier if isinstance(supplier, str) else supplier._id
@@ -1006,8 +1012,17 @@ def write_bitbake_spdx(d):
objset = oe.sbom30.ObjectSet.new_objset(d, "bitbake", False)
host_import_key = d.getVar("SPDX_BUILD_HOST")
- invoked_by = objset.new_agent("SPDX_INVOKED_BY", add=False)
- on_behalf_of = objset.new_agent("SPDX_ON_BEHALF_OF", add=False)
+ invoked_by = None
+ invoked_by_id_val = d.getVar("SPDX_INVOKED_BY")
+ if invoked_by_id_val:
+ invoked_by_varname = f"SPDX_INVOKED_BY_{invoked_by_id_val}"
+ invoked_by = objset.new_agent(invoked_by_varname, add=False)
+
+ on_behalf_of = None
+ on_behalf_of_id_val = d.getVar("SPDX_ON_BEHALF_OF")
+ if on_behalf_of_id_val:
+ on_behalf_of_varname = f"SPDX_ON_BEHALF_OF_{on_behalf_of_id_val}"
+ on_behalf_of = objset.new_agent(on_behalf_of_varname, add=False)
if d.getVar("SPDX_INCLUDE_BITBAKE_PARENT_BUILD") == "1":
# Since the Build objects are unique, we may as well set the creation
@@ -1330,6 +1345,22 @@ def create_image_sbom_spdx(d):
objset, sbom = oe.sbom30.create_sbom(d, image_name, root_elements)
+ # Set supplier on root elements if SPDX_IMAGE_SUPPLIER is defined
+ # Follow the same pattern as SPDX_AUTHORS: get identifier, build varname, then call new_agent
+ supplier_id_val = d.getVar("SPDX_IMAGE_SUPPLIER")
+ if supplier_id_val:
+ supplier_varname = f"SPDX_IMAGE_SUPPLIER_{supplier_id_val}"
+ supplier = objset.new_agent(supplier_varname, add=False)
+ if supplier is not None:
+ supplier_id = supplier if isinstance(supplier, str) else supplier._id
+ # Add supplier to objset if it's not already there
+ if not isinstance(supplier, str):
+ objset.add(supplier)
+ # Set suppliedBy on all root elements
+ for elem in sbom.rootElement:
+ if hasattr(elem, "suppliedBy"):
+ elem.suppliedBy = supplier_id
+
oe.sbom30.write_jsonld_doc(d, objset, spdx_path)
def make_image_link(target_path, suffix):
@@ -1441,6 +1472,22 @@ def create_sdk_sbom(d, sdk_deploydir, spdx_work_dir, toolchain_outputname):
d, toolchain_outputname, sorted(list(files)), [rootfs_objset]
)
+ # Set supplier on root elements if SPDX_SDK_SUPPLIER is defined
+ # Follow the same pattern as SPDX_AUTHORS: get identifier, build varname, then call new_agent
+ supplier_id_val = d.getVar("SPDX_SDK_SUPPLIER")
+ if supplier_id_val:
+ supplier_varname = f"SPDX_SDK_SUPPLIER_{supplier_id_val}"
+ supplier = objset.new_agent(supplier_varname, add=False)
+ if supplier is not None:
+ supplier_id = supplier if isinstance(supplier, str) else supplier._id
+ # Add supplier to objset if it's not already there
+ if not isinstance(supplier, str):
+ objset.add(supplier)
+ # Set suppliedBy on all root elements
+ for elem in sbom.rootElement:
+ if hasattr(elem, "suppliedBy"):
+ elem.suppliedBy = supplier_id
+
oe.sbom30.write_jsonld_doc(
d, objset, sdk_deploydir / (toolchain_outputname + ".spdx.json")
)