From patchwork Mon Sep 14 11:44:21 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Wagenknecht X-Patchwork-Id: 98180 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E258C88E64 for ; Mon, 14 Sep 2026 11:46:14 +0000 (UTC) Received: from mx1.emlix.com (mx1.emlix.com [178.63.209.131]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.18099.1789386373603965570 for ; Mon, 14 Sep 2026 04:46:13 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@emlix.com header.s=20250930 header.b=lZ8zPKnR; dkim=fail reason="dkim: body hash did not verify" header.i=@emlix.com header.s=20250930 header.b=lZ8zPKnR; spf=pass (domain: emlix.com, ip: 178.63.209.131, mailfrom: dwagenknecht@emlix.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=emlix.com; s=20250930; t=1789386360; bh=550Jp7j7zKs9B35ZX4dePN6CYN/5n1/YudgSuwtwEIQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lZ8zPKnRDFJ/D+S/oob12CdPAq8y/9Zggx2H0g377QZ+LqwTOZ1D0eigruqsMuJzO UOdWMTPxeNgt3YVYZRwq8/Cpsppj0K7Kt1JF8yeMP5h1WBGza/M3BqOJRYX2pPoZpo BhNvbYA1VRBtfkcMzF+geYu2aYyv3HHurh4IHspY97NU8LMw3tz7RtqbeTNdf7dQvL 8fAaa3F/69jiPfS1r4kRiOLwUbOPrKyfyx62SpVHwWOZLFz7kAEpurQt3ev9G64f/M 6xI3YDMJgDKAcJsmaMYaUf9WEYcww6LAl1wdCJiS0qzdoVbrXqPo6E/jRkvNslKpDg 7Dd6f5tjFcQ4Q== Received: from mx1.emlix.com (localhost [127.0.0.1]) by mx1.emlix.com (Postfix) with ESMTP id 4B2035FA92 for ; Mon, 14 Sep 2026 13:46:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=emlix.com; s=20250930; t=1789386360; bh=550Jp7j7zKs9B35ZX4dePN6CYN/5n1/YudgSuwtwEIQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lZ8zPKnRDFJ/D+S/oob12CdPAq8y/9Zggx2H0g377QZ+LqwTOZ1D0eigruqsMuJzO UOdWMTPxeNgt3YVYZRwq8/Cpsppj0K7Kt1JF8yeMP5h1WBGza/M3BqOJRYX2pPoZpo BhNvbYA1VRBtfkcMzF+geYu2aYyv3HHurh4IHspY97NU8LMw3tz7RtqbeTNdf7dQvL 8fAaa3F/69jiPfS1r4kRiOLwUbOPrKyfyx62SpVHwWOZLFz7kAEpurQt3ev9G64f/M 6xI3YDMJgDKAcJsmaMYaUf9WEYcww6LAl1wdCJiS0qzdoVbrXqPo6E/jRkvNslKpDg 7Dd6f5tjFcQ4Q== Received: from mailer.emlix.com (p5098be52.dip0.t-ipconnect.de [80.152.190.82]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.emlix.com (Postfix) with ESMTPS id 3A8725F82B for ; Mon, 14 Sep 2026 13:46:00 +0200 (CEST) From: Daniel Wagenknecht To: openembedded-core@lists.openembedded.org Cc: Daniel Wagenknecht Subject: [PATCH 2/2] spdx: link files to the meta-layer providing them Date: Mon, 14 Sep 2026 13:44:21 +0200 Message-ID: <20260914114526.2646773-3-dwagenknecht@emlix.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260914114526.2646773-1-dwagenknecht@emlix.com> References: <20260914114526.2646773-1-dwagenknecht@emlix.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 14 Sep 2026 11:46:14 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245765 Many recipes ship files that originate from a meta-layer. Link each file added via the `file` protocol to the spdx entry of the meta-layer containing that file. Some files might not originate from a meta-layer (`file` protocol supports absolute paths), fail the build if SPDX_REQUIRE_LAYER_ASSERTION is set to true. Signed-off-by: Daniel Wagenknecht --- meta/lib/oe/spdx30_tasks.py | 44 +++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 0a8f4b0e1a0..f782ea1cadf 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -497,6 +497,7 @@ def add_download_files(d, objset): primary_purpose = oe.spdx30.software_SoftwarePurpose.source if fd.type == "file": + (layer_path, layer_objset) = get_layer_info(d, fd.localpath) if os.path.isdir(fd.localpath): walk_idx = 1 for root, dirs, files in os.walk(fd.localpath, onerror=walk_error): @@ -512,23 +513,36 @@ def add_download_files(d, objset): objset.new_spdxid( "source", str(download_idx + 1), str(walk_idx) ), - os.path.join( - file_name, os.path.relpath(f_path, fd.localpath) - ), + os.path.relpath(f_path, layer_path), f_path, purposes=[primary_purpose], ) + if layer_objset is not None: + objset.new_scoped_relationship( + [oe.sbom30.get_element_link_id(layer_objset)], + oe.spdx30.RelationshipType.contains, + oe.spdx30.LifecycleScopeType.build, + [file], + ) + inputs.add(file) walk_idx += 1 else: file = objset.new_file( objset.new_spdxid("source", str(download_idx + 1)), - file_name, + os.path.relpath(fd.localpath, layer_path), fd.localpath, purposes=[primary_purpose], ) + if layer_objset is not None: + objset.new_scoped_relationship( + [oe.sbom30.get_element_link_id(layer_objset)], + oe.spdx30.RelationshipType.contains, + oe.spdx30.LifecycleScopeType.build, + [file], + ) inputs.add(file) else: @@ -803,6 +817,28 @@ def load_recipe_spdx(d): oe.spdx30.software_Package, ) +def get_layer_info(d, path): + layer = None + path = Path(path) + + layers = oe.buildcfg.get_layer_revisions(d) + for (l_path, l_name, l_branch, l_rev, l_ismodified) in layers: + l_path = Path(l_path) + if l_path in path.parents: + layer = l_name + break + + if not l_path: + if oe.utils.vartrue("SPDX_REQUIRE_LAYER_ASSERTION", True, False, d): + bb.fatal(f"Path {path} does not originate from a meta-layer!") + return ("/", None) + + deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX")) + objset = oe.sbom30.load_jsonld(d, deploy_dir_spdx / "layers.spdx.json", required=True) + spdx_obj = objset.find_root(oe.spdx30.software_Package, name=l_name) + + return (l_path, spdx_obj) + def create_spdx(d): def set_var_field(var, obj, name, package=None):