From patchwork Wed Nov 4 15:33:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102922 Received: from mail-oi1-f172.google.com (mail-oi1-f172.google.com [209.85.167.172]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.11931.1793806541095826404 for ; Wed, 04 Nov 2026 07:35:41 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=g0GO5L18; spf=pass (domain: gmail.com, ip: 209.85.167.172, mailfrom: jpewhacker@gmail.com) Received: by mail-oi1-f172.google.com with SMTP id 5614622812f47-4e4a4d77e5bso1287413b6e.0 for ; Wed, 04 Nov 2026 07:35:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806540; x=1794411340; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=k6HhJL9qpsmK5T5siTyfRkDD4MIqxFfeTZ9MsiurJnE=; b=g0GO5L186HFZZQCAQy+QPGoKHjd+05UXHpgCKre2w+dfK14PJ0unTqnmt3XHPihZQq AMIK7ZGrP8p4ZYLuQmfkBf1mdQwcFtxh3UxB1FK68JVvzo4HeyHR80Vi4J+XOFE9tPAb cJxGAdcu4UzH/kWZUV0Kksa8ZNuKX4VG19vVhOMfUoEcZAH00nHvlY6Z/IPHSQkI6I1Q jiQavSvPL/g13Jma4AQyY7yR5W6cCdg5Ne7BZLEias2R//DJHeBZaiQpcmwpPHNSHS8O jJzAfKKmGuWV0n77O8aF997S+ZqqT5JiPi1Y65/9KUpvHlhcKbMAzF0vWf8aFZYUATO+ jdPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806540; x=1794411340; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=k6HhJL9qpsmK5T5siTyfRkDD4MIqxFfeTZ9MsiurJnE=; b=uLB/gfqZTOZWa+RMEMl/4jBAFQ1ctkCyAOosk2Toqsgo52OjmJCcxZnZZCSfCSxRj6 YfxO9TMhIdmclFB+y2PlYYrLrLiQFXIIDLX050Q6GL3PLpOj9zVhCjFQjkQynxmY1Otg t/910oFTJOYE8Qwi6yxJJSr2cHbNNE/JUjoJD2iZpjck8IDFXtpLs7dckKdUJsHFF7Cr IDovbZtFi+cB301GpYszeYeoB9Iy1HPXTItwSQuwIA/K5U11EENEbIdMLFl08Kp/fe59 CDNuBamfSjcaI/5a/L9Ynn2BxPU8zcyR/84qGp6317/JvaTPlcPnPGIledX/ABlkUSad 4OuQ== X-Gm-Message-State: APuU4Z/jy2fRq5lWO6blpVp8P+zzGlZ7cQsfxXt9Y1gZFouHIrcHMBCj OkbJJVHOwG4+oR8FQxyY4uD5701YIrvclSF2iYwaVczS8IE4bU3bxMfYk9pp8g== X-Gm-Gg: AYBFou2BP1XnNFh41zxX8maxKye8+xY+QNfTeK9HAP7KbJbXN65veX56RIGs1cjjbEM 3hSfuu14RqXF6fla6BSo66C9gzWP+/LClG46/4drvW9dYwfCMNSyvZfI/1WVVf6/OGoxS2L1XtH ilP1lYa6uXw4aK6j4Yf9SNYVVkX3Td10iAsAiRowVgJno5qIs9HOy4zdKmztcByECSx6/KaJvmR du90OqnGlPGjT7Cihrp3SIQ8+ygIcfngBqHAQCq16vW4fOdryyGi3fWvvO4eq4by9XSIfrzsc57 RqdxzupddiMbSltm+hmoNX83SUCPYTcgBZy+a0mI7XsgSadyyNqpgXyzlyY5H529pl2RKqinzEb G6XTqclNzQA30evFChkuuZoukT0Tn7WA4QPtV5HTzYcOEQ0x7BlX81OJlRhNctC+FiHOEmsMLMX XAhLI8ZvlmCuUfDf30H6e8mfDE2EpDh1YtSf5espYVHwZDcZ+A2/+xCl2hDzepvF+x4z8ioYpC7 fnYmzhlCsqjd9kWqOGWpqgy4yjVw3tbNE3FwJqia1HYebSXy3YKZot9eVlc/UAHfyW/RMrRLz7s 1G+Urz/GYEceU9zeQ84d92SJb9o= X-Received: by 2002:a05:6808:250d:b0:546:306d:45eb with SMTP id 5614622812f47-563efb56084mr9466264b6e.35.1793806539588; Wed, 04 Nov 2026 07:35:39 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:39 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 1/9] spdx: Skip dependencies that are not in the taskhash Date: Wed, 4 Nov 2026 08:33:54 -0700 Message-ID: <20261104153535.3184146-2-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:44 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249395 If a dependency is not in the taskhash, it cannot be included in the SPDX data because the dependency may not trigger the recipe to rebuild if it changes (although aliases help with this), but more importantly bitbake may not restore the sstate object associated with the dependency which causes errors when constructing the final SBoM Signed-off-by: Joshua Watt --- meta/lib/oe/spdx30_tasks.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 646ec7d074..3c3ba15e74 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -306,13 +306,14 @@ def collect_dep_objsets(d, direct_deps, subdir, fn_prefix, obj_type, **attr_filt dep_obj, dep_objset = oe.sbom30.find_root_obj_in_jsonld( d, subdir, fn_prefix + dep.pn, obj_type, **attr_filter ) - # If the dependency is part of the taskhash, return it to be linked - # against. Otherwise, it cannot be linked against because this recipe - # will not rebuilt if dependency changes - if dep.in_taskhash: - dep_objsets.append(dep_objset) + # If the dependency is not part of the task hash, do not include it + # since the dependency may not be present in subsequent runs, and may + # not rebuild if it changes + if not dep.in_taskhash: + bb.debug(1, f"Skipping dependency {dep.pn} (not in taskhash)") + continue - # The object _can_ be linked against (by alias) + dep_objsets.append(dep_objset) dep_objs.add(dep_obj) return dep_objsets, dep_objs From patchwork Wed Nov 4 15:33:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102923 Received: from mail-oi1-f171.google.com (mail-oi1-f171.google.com [209.85.167.171]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.11932.1793806543307514254 for ; Wed, 04 Nov 2026 07:35:43 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=Bbq4Ac99; spf=pass (domain: gmail.com, ip: 209.85.167.171, mailfrom: jpewhacker@gmail.com) Received: by mail-oi1-f171.google.com with SMTP id 5614622812f47-56431524c22so316449b6e.0 for ; Wed, 04 Nov 2026 07:35:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806542; x=1794411342; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=UytyvyRONmp5d0bwaTp/b814IGGDC2jbzr3kbbxx+kQ=; b=Bbq4Ac99QPYXcJNCacGyR+Nz6IrWXWm3vBFPns9KZNMuj7m8Fgmq3jhMwhvcFkNaoI DLoH4HF0FcHGd9eIlUxmQaQARnwvTiGyZnQeOeAEc9CCxHa1P/ZdcP7jeOR+7IDF3eNH be4KtYnTrqJQSEILcZplOFrKQxb5hzosW9EAPYU0cVWQZUZ43Jp5irJaerAb0kPHR/QO BlGMf9H+oHaNtuiUcWZ1/tbeuN/tqpdAq5qiMR4EkQcUxPyoDQXPYtXVS3P9neX0POnB +q/ssHjNlhrhTs2Tg6yUvgQTXNP8RqRu97Srvb09NuVKecfemRQ23XsfPwBwgI/fLgZG M01w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806542; x=1794411342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=UytyvyRONmp5d0bwaTp/b814IGGDC2jbzr3kbbxx+kQ=; b=0BIq06UWlw6+vaQhrHkfIVPnVeUt7zRwEKpEaAniiU4rgIZoEtAEtFIZOIoUPVA1fh YJ3mgyAQzPjX4AeofGKe+GnvWbr3xanQ670ZyvKALgYtk5eioIHuiQ/YjzV0p+HQFBnN SQQdPIE3yVeaTDv9aSL5OhHWrwPfa/WuOVV7IZ5gKD2OYbmUzMY1us3FT0c+zpiw2Gmn 6tKMZj7Jj2GsjeA8OGALBlV43rHcP4vdkH0QjcUxVxLhZ9DrETRwAcZzmoYRgYW2imtR DHpU1GFykptd6YWUtZA5tgD6Fb931H2fwPutl1pOoMOJ2jksBs2Jy2dOjcdpmhh/rEsD +Zig== X-Gm-Message-State: APuU4Z/cA5Ie3WcZiq80ikX+XlpToiN2IAasmuiQT6FJass9AWg4/Vx7 nUObNjCEqUqBrJH/eg9LFeZL8tbWewxJKhnqG6Xd28TP6QhVJM9gW3aMsgM3pQ== X-Gm-Gg: AYBFou1fPxwB08iNJfLdzW+HP8iEixyxOdxbb3Z4G+IBJOp7wStn4PIKqQB+husqr6c lIsMTrx1beYeIP2aVxtAFaoc9qbQDrd2AE1PMLkWDUgHq8oGD99wFe3seHkkYoHE+JRJMuOlX5c Jxv1m2h58tIqZhuDTdxMXSMgPlnTWmkSCm3CYx846FEdFDElRRjgUSYuj1ipKGSvyr7J64s/Pqw QL03MWeTVj8ymC29b46604q7zIo7tDydyxXZ30qNjBUYxyAwHEb9XCtqI0B83RWDVwm+X2IvWIC GTzEJUrQsBNhCqNClVt607wk/ExqJREjT0bsf3dNd8sy3/31U9IYY5WYVP6XOEX8rb4mDKwcfuT nrM45Ie0je4KvTWlRWPBvtUxbufy9CBMUkIadV50gsEf4p/2XNx1IwerYTpRBzs+MAJhZjZHHne dMQz2VPmHV+f1JJHh/A5ylyXjYR5uvjTIsFB4tzTd+KQKhYw6N0MpA9Ji9m06Xndm6zUczd3fEN j2BWYls3gKJoALCPipqNZ46hRngVJyUvkS0KmLfDBCFumNYw7DG7amxRF9YuNJ/S5gkPyR5VYeB wt9mTP02Zpdcd5KHTQmz3xvX0JWt X-Received: by 2002:a05:6808:c1d3:b0:552:950f:3ce9 with SMTP id 5614622812f47-5640de0fcc0mr10937250b6e.44.1793806540735; Wed, 04 Nov 2026 07:35:40 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:40 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 2/9] spdx: Add ability for deploy tasks to create SPDX Date: Wed, 4 Nov 2026 08:33:55 -0700 Message-ID: <20261104153535.3184146-3-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:44 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249398 Adds support for "deploy" tasks (like do_deploy) to write out SPDX documents that describe what has been deployed. Deploy tasks will automatically detect many dependencies on other recipes; specifically they will correctly detect dependencies on any do_create_spdx task, and also other deploy tasks that generate SPDX output. The only known notable exception are transitive (e.g. originating from other upstream tasks) dependencies on do_image_complete, and do_populate_sysroot. However, these are detected if a direct dependency of the deploy task (via translation of the task dependencies). This same dependency finding algorithm is now applied to the image generation SBoM; this means that if an image creation task depends on a task that generates a deploy SBoM, it will show up in the dependency graph of the image. A typical example is a wic file that consumes the kernel, u-boot, etc. will now correctly list those as a dependency, as long as their do_deploy step is added to SPDX_DEPLOY_TASKS. Signed-off-by: Joshua Watt --- .../create-spdx-image-3.0.bbclass | 4 +- meta/classes-recipe/deploy.bbclass | 1 + meta/classes-recipe/nospdx.bbclass | 1 + meta/classes/create-spdx-3.0.bbclass | 188 ++++++++++++ meta/classes/spdx-common.bbclass | 1 + meta/lib/oe/sbom30.py | 46 +-- meta/lib/oe/spdx30_tasks.py | 289 +++++++++++++++--- meta/lib/oe/spdx_common.py | 2 +- 8 files changed, 466 insertions(+), 66 deletions(-) diff --git a/meta/classes-recipe/create-spdx-image-3.0.bbclass b/meta/classes-recipe/create-spdx-image-3.0.bbclass index cf79ef5b01..b60cdd826f 100644 --- a/meta/classes-recipe/create-spdx-image-3.0.bbclass +++ b/meta/classes-recipe/create-spdx-image-3.0.bbclass @@ -30,7 +30,7 @@ python do_create_rootfs_spdx() { import oe.spdx30_tasks oe.spdx30_tasks.create_rootfs_spdx(d) } -addtask do_create_rootfs_spdx after do_rootfs before do_image +addtask do_create_rootfs_spdx after do_rootfs do_create_recipe_spdx before do_image SSTATETASKS += "do_create_rootfs_spdx" do_create_rootfs_spdx[sstate-inputdirs] = "${SPDXROOTFSDEPLOY}" do_create_rootfs_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}" @@ -47,7 +47,7 @@ python do_create_image_spdx() { import oe.spdx30_tasks oe.spdx30_tasks.create_image_spdx(d) } -addtask do_create_image_spdx after do_image_complete do_create_rootfs_spdx before do_build +addtask do_create_image_spdx after do_image_complete do_create_rootfs_spdx do_create_recipe_spdx before do_build SSTATETASKS += "do_create_image_spdx" SSTATE_SKIP_CREATION:task-create-image-spdx = "1" do_create_image_spdx[sstate-inputdirs] = "${SPDXIMAGEWORK}" diff --git a/meta/classes-recipe/deploy.bbclass b/meta/classes-recipe/deploy.bbclass index f56fe98d6d..f222a8560f 100644 --- a/meta/classes-recipe/deploy.bbclass +++ b/meta/classes-recipe/deploy.bbclass @@ -6,6 +6,7 @@ DEPLOYDIR = "${WORKDIR}/deploy-${PN}" SSTATETASKS += "do_deploy" +SPDX_DEPLOY_ARTIFACTS_DIR:task-deploy = "${DEPLOYDIR}" do_deploy[sstate-inputdirs] = "${DEPLOYDIR}" do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" diff --git a/meta/classes-recipe/nospdx.bbclass b/meta/classes-recipe/nospdx.bbclass index 6ccb93ba01..723194da2d 100644 --- a/meta/classes-recipe/nospdx.bbclass +++ b/meta/classes-recipe/nospdx.bbclass @@ -12,3 +12,4 @@ deltask do_create_package_spdx deltask do_create_rootfs_spdx deltask do_create_image_spdx deltask do_create_image_sbom_spdx +deltask do_create_deploy_sbom diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index 6d47aa1301..fb6a4f249e 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -163,6 +163,55 @@ SPDX_GIT_PURL_MAPPINGS[doc] = "A space separated list of domain:purl_type \ on gitlab.example.com to the pkg:gitlab PURL type. \ github.com is always mapped to pkg:github by default." +SPDX_DEPLOY_TASKS ?= "" +SPDX_DEPLOY_TASKS[doc] = "A space separated list of sstate tasks that produce \ + deployed output (usually written to DEPLOY_DIR_IMAGE). Tasks in this list \ + will produce SPDX documents that describe the deployed output. Items in \ + list have the format 'TASK(:FUNCTION)' where 'TASK' is the sstate task \ + (which must start with 'do_deploy'), and 'FUNCTION' is the optional \ + function to call to produce the deploy SPDX. If 'FUNCTION' is omitted \ + a default function is provided that uses SPDX_DEPLOY_ARTIFACTS and \ + SPDX_DEPLOY_ARTIFACTS_DIR to configure what deploy artifacts it describes \ + in the SPDX output.\ + \ + Dependencies of deploy tasks that produce SPDX data will be automatically \ + linked in as a build time dependency of the deploy task's SBoM. (for \ + example, if one do_deploy depends on another recipes do_deploy, this will \ + be reflected in the SPDX data)." + +SPDX_DEPLOY_SBOM ??= "1" +SPDX_DEPLOY_SBOM[doc] = "If '1' (the default) a task named \ + do_create_deploy_sbom will be created to automatically collect all deploy \ + SPDX documents (from SPDX_DEPLOY_TASKS) and combine them into a SBoM \ + which will be placed in DEPLOY_DIR_IMAGE. This task is added as a \ + dependency of do_build, so it will run whenever the recipe is built \ + directly. The name of the document can be set with SPDX_DEPLOY_SBOM_NAME. \ + If the recipe already has another task to create an SBoM, this should be \ + set to '0' to prevent multiple SBoMs from being created." + +SPDX_DEPLOY_SBOM_NAME ?= "${PN}-deploy-sbom" +SPDX_DEPLOY_SBOM_NAME[doc] = "The name of the output deploy SBoM when using \ + create_deploy_sbom" + +SPDX_DEPLOY_ARTIFACTS = "AUTO" +SPDX_DEPLOY_ARITFACTS[doc] = "A space separated list of deployed artifacts, \ + relative to SPDX_DEPLOY_ARTIFACTS_DIR that should be included in the SBoM. \ + If 'AUTO' (the default), all files in SPDX_DEPLOY_ARITFACTS_DIR will be \ + added. A :task- override *must* be used to set this value so that it is \ + scoped to a specific task" + +SPDX_DEPLOY_ARTIFACTS_DIR = "" +SPDX_DEPLOY_ARTIFACTS_DIR[doc] = "The directory recipe specific directory \ + where artifacts are deployed for staging to sstate (e.g. for do_deploy, \ + this is DEPLOY_DIR). A :task- override *must* be used to set this value so \ + that it is scoped to a specific task." + +SPDX_DEPLOY_ALLOW_EMPTY = "0" +SPDX_DEPLOY_ALLOW_EMPTY[doc] = "If set to '1', SPDX deploy task is allowed to \ + have no output artifacts. A SPDX document will still be produced, but it \ + will have no output files. This must always be set with a task override, \ + e.g.: SPDX_DEPLOY_ALLOW_EMPTY:task-deploy = '1'" + IMAGE_CLASSES:append = " create-spdx-image-3.0" SDK_CLASSES += "create-spdx-sdk-3.0" @@ -293,3 +342,142 @@ python spdx30_build_started_handler () { addhandler spdx30_build_started_handler spdx30_build_started_handler[eventmask] = "bb.event.BuildStarted" +python create_deploy_spdx() { + import oe.spdx30_tasks + from pathlib import Path + current_task = "do_" + d.getVar("BB_CURRENTTASK") + + spdxdeploydir = Path(d.getVar("SPDXDIR") + "/deploy-" + current_task) + + artifactsdir = d.getVar("SPDX_DEPLOY_ARTIFACTS_DIR") + if not artifactsdir: + bb.fatal(f"{pn}: spdx-artifactsdir must be set for task {current_task}") + return + + artifacts = d.getVar("SPDX_DEPLOY_ARTIFACTS") + + oe.spdx30_tasks.create_deploy_spdx(d, spdxdeploydir, artifactsdir, artifacts) +} +oe.spdx30_tasks.find_build_dep_objsets[vardepsexclude] += "BB_TASKDEPDATA" + +python () { + # Most recipes generate SPDX output in a distinct task from the task that + # actually is the relevant dependency. As such, we need to map the task + # that we care about to the task that generates the corresponding SPDX + # output so that we can rely on the SPDX output being present when the time + # comes to use it downstream. + # + # The down side of this is that only the first level of dependencies (e.g + # tasks listed in SPDX_DEPLOY_TASKS) will have the mapping done and thus + # find the dependencies. Transitive dependencies will not be mapped and + # thus the SPDX data will not be linked in. + # + # Ideally, this will be able to go away once more tasks directly generate + # SPDX files for their output instead of combining it into monolithic + # functions; tasks listed in this map are the best candidates to have this + # done first. + TASK_MAP = { + # If a task requires the RSS be extended, depend on the SPDX build task + # for the recipe, at least until it's possible for do_populate_sysroot + # to describe it's own output. + "do_populate_sysroot": "do_create_spdx", + # If an image is needed, also depend on the task to create the SBoM for + # the image + "do_image_complete": "do_create_image_spdx", + } + + def map_task_deps(task, flag): + task_flags= (d.getVarFlag(task, flag) or "").split() + for t in task_flags: + if t in TASK_MAP and TASK_MAP[t] not in task_flags: + d.appendVarFlag(task, flag, f" {TASK_MAP[t]}") + + def before_postfunc(f): + return f == "sstate_task_postfunc" or "buildhistory" in f + + if bb.data.inherits_class("nospdx", d): + return + + sstate_tasks = set((d.getVar("SSTATETASKS") or "").split()) + deploy_sbom_tasks = [] + for task in (d.getVar("SPDX_DEPLOY_TASKS") or "").split(): + if ":" in task: + task, func = task.split(":") + else: + func = "create_deploy_spdx" + + if not task.startswith("do_deploy") and not task == "do_image_complete": + bb.fatal(f"Task {task} is not allowed to deploy SPDX data. Must start with 'do_deploy'") + + deploy_sbom_tasks.append(task) + + if task not in sstate_tasks: + bb.fatal(f"{task} is not an sstate task") + + spdx_deploy = "${SPDXDIR}/deploy-" + task + + # Ensure function is sorted properly. It should be right before + # sstate_task_postfunc + postfuncs = (d.getVarFlag(task, "postfuncs") or "").split() + + new_postfuncs = [] + while True: + if not postfuncs or before_postfunc(postfuncs[0]): + break + new_postfuncs.append(postfuncs.pop(0)) + new_postfuncs.append(func) + new_postfuncs.extend(postfuncs) + + d.setVarFlag(task, "postfuncs", " ".join(new_postfuncs)) + d.prependVarFlag(task, "sstate-inputdirs", f"{spdx_deploy} ") + d.prependVarFlag(task, "sstate-outputdirs", "${DEPLOY_DIR_SPDX} ") + d.prependVarFlag(task, "file-checksums", "${SPDX3_DEP_FILES} ") + d.prependVarFlag(task, "dirs", f"{spdx_deploy} ") + d.prependVarFlag(task, "cleandirs", f"{spdx_deploy} ") + d.prependVarFlag(task, "vardeps", "SPDX_DEPLOY_ALLOW_EMPTY") + + deps = (d.getVarFlag(task, "depends") or "").split() + extra_deps = ["${PN}:do_create_recipe_spdx", "${PN}:do_create_spdx"] + for dep in deps: + _, fn, taskname = bb.runqueue.split_tid(dep) + if taskname in TASK_MAP: + extra_deps.append(f"{fn}:{TASK_MAP[taskname]}") + + d.prependVarFlag(task, "depends", " ".join(extra_deps) + " ") + + map_task_deps(task, "deptask") + map_task_deps(task, "rdeptask") + map_task_deps(task, "recrdeptask") + + # For now, if a recipe is directly built, deploy all of it's deploy tasks + # into a single SBoM. We may need an option in the future to have tasks + # that don't do this (e.g. because they do not deploy to a location that is + # intended to be consumed by the user) + if deploy_sbom_tasks and (d.getVar("SPDX_DEPLOY_SBOM") or "") == "1": + bb.build.addtask("do_create_deploy_sbom", "do_build", " ".join(deploy_sbom_tasks), d) +} + +python do_create_deploy_sbom() { + import oe.spdx30_tasks + from pathlib import Path + deploydir = Path(d.getVar("SPDXDEPLOYSBOMDEPLOY")) + deploy_tasks = [] + for task in (d.getVar("SPDX_DEPLOY_TASKS") or "").split(): + if ":" in task: + task, _ = task.split(":") + deploy_tasks.append(task) + + oe.spdx30_tasks.create_deploy_sbom(d, deploydir, deploy_tasks) +} +do_create_deploy_sbom[sstate-inputdirs] = "${SPDXDEPLOYSBOMDEPLOY}" +do_create_deploy_sbom[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" +do_create_deploy_sbom[recrdeptask] += "do_create_recipe_spdx do_create_spdx" +do_create_deploy_sbom[cleandirs] += "${SPDXDEPLOYSBOMDEPLOY}" +do_create_deploy_sbom[file-checksums] += "${SPDX3_DEP_FILES}" + +SSTATETASKS += "do_create_deploy_sbom" +python do_create_deploy_sbom_setscene() { + sstate_setscene(d) +} +addtask do_create_deploy_sbom_setscene +SSTATE_SKIP_CREATION:task-create-deploy-sbom = "1" diff --git a/meta/classes/spdx-common.bbclass b/meta/classes/spdx-common.bbclass index 40701730a6..bca169670d 100644 --- a/meta/classes/spdx-common.bbclass +++ b/meta/classes/spdx-common.bbclass @@ -26,6 +26,7 @@ SPDX_TOOL_VERSION ??= "1.0" SPDXRECIPEDEPLOY = "${SPDXDIR}/recipe-deploy" SPDXRUNTIMEDEPLOY = "${SPDXDIR}/runtime-deploy" SPDXRECIPESBOMDEPLOY = "${SPDXDIR}/recipes-bom-deploy" +SPDXDEPLOYSBOMDEPLOY = "${SPDXDIR}/deploy-bom-deploy" SPDX_INCLUDE_SOURCES ??= "0" SPDX_INCLUDE_SOURCES[doc] = "If set to '1', include source code files in the \ diff --git a/meta/lib/oe/sbom30.py b/meta/lib/oe/sbom30.py index e279cfc82b..520f9df3ef 100644 --- a/meta/lib/oe/sbom30.py +++ b/meta/lib/oe/sbom30.py @@ -1108,6 +1108,25 @@ def write_jsonld_doc(d, objset, dest): objset.objects.remove(objset.doc) +def make_jsonld_link(d, fn, subdir, name, deploydir): + pkg_arch = d.getVar("SSTATE_PKGARCH") + + link_name = jsonld_arch_path( + d, + pkg_arch, + subdir, + name, + deploydir=deploydir, + ) + try: + link_name.parent.mkdir(exist_ok=True, parents=True) + link_name.symlink_to(os.path.relpath(fn, link_name.parent)) + except: + target = link_name.readlink() + bb.warn(f"Unable to link {fn} as {link_name}. Already points to {target}") + raise + + def write_recipe_jsonld_doc( d, objset, @@ -1115,6 +1134,7 @@ def write_recipe_jsonld_doc( deploydir, *, create_spdx_id_links=True, + create_task_link=False, ): pkg_arch = d.getVar("SSTATE_PKGARCH") @@ -1122,23 +1142,7 @@ def write_recipe_jsonld_doc( def link_id(_id): hash_path = jsonld_hash_path(hash_id(_id)) - - link_name = jsonld_arch_path( - d, - pkg_arch, - *hash_path, - deploydir=deploydir, - ) - try: - link_name.parent.mkdir(exist_ok=True, parents=True) - link_name.symlink_to(os.path.relpath(dest, link_name.parent)) - except: - target = link_name.readlink() - bb.warn( - f"Unable to link {_id} in {dest} as {link_name}. Already points to {target}" - ) - raise - + make_jsonld_link(d, dest, *hash_path, deploydir) return hash_path[-1] objset.add_aliases() @@ -1154,6 +1158,14 @@ def write_recipe_jsonld_doc( # out, so always do that even if there is an error making the links write_jsonld_doc(d, objset, dest) + if create_task_link: + pn = d.getVar("PN") + current_task = "do_" + d.getVar("BB_CURRENTTASK") + + make_jsonld_link(d, dest, "by-task", f"{pn}:{current_task}", deploydir) + + return dest + def find_root_obj_in_jsonld(d, subdir, fn_name, obj_type, **attr_filter): objset, fn = find_jsonld(d, subdir, fn_name, required=True) diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 3c3ba15e74..43e196806f 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -80,7 +80,9 @@ def add_license_expression( if lic is None: p, _ = oe.license.get_license_path(d, node) if p is None: - bb.fatal(f"{pn}: No generic license file exists for: {node.ident} in any provider") + bb.fatal( + f"{pn}: No generic license file exists for: {node.ident} in any provider" + ) return with open(p, errors="replace") as f: @@ -598,6 +600,135 @@ def get_is_native(d): return bb.data.inherits_class("native", d) or bb.data.inherits_class("cross", d) +def set_var_field(d, var, obj, name, package=None): + val = None + if package: + val = d.getVar("%s:%s" % (var, package)) + + if not val: + val = d.getVar(var) + + if val: + setattr(obj, name, val) + + +def find_build_dep_objsets(d, start_task): + def find_deps(d, taskdepdata, current_dep, start_dep, visited, depth=0): + key = f"{current_dep.pn}:{current_dep.taskname}" + + dep_objsets = [] + + if key not in visited: + visited.add(key) + + for n in current_dep.deps: + dep = taskdepdata[n] + dep_name = f"{dep.pn}:{dep.taskname}" + + dep_objset, dep_path = oe.sbom30.find_jsonld(d, "by-task", dep_name) + if dep_objset: + dep_objsets.append(dep_objset) + + elif dep.pn == start_dep.pn: + # If this task is still part of the same recipe, continue + # searching up the dependency tree until a valid dependency + # is found. This detects transitive dependencies that may + # have been pulled in by previous tasks in the same recipe. + dep_objsets.extend( + find_deps(d, taskdepdata, dep, start_dep, visited, depth + 1) + ) + + return dep_objsets + + pn = d.getVar("PN") + taskdepdata = d.getVar("BB_TASKDEPDATA", False) + for dep in taskdepdata.values(): + if dep.pn == pn and dep.taskname == start_task: + start_dep = dep + break + else: + bb.fatal(f"Unable to find {pn}:{start_task} in taskdepdata") + + return find_deps(d, taskdepdata, start_dep, start_dep, set()) + + +def create_deploy_package(d, objset, build, spdxid, name, start_task, files, **attrs): + recipe, _ = load_recipe_spdx(d) + + deploy_package = objset.add_root( + oe.spdx30.software_Package( + _id=spdxid, + creationInfo=objset.doc.creationInfo, + name=name, + software_packageVersion=d.getVar("PV"), + ) + ) + + objset.new_scoped_relationship( + [oe.sbom30.get_element_link_id(recipe)], + oe.spdx30.RelationshipType.generates, + oe.spdx30.LifecycleScopeType.build, + [deploy_package], + ) + + set_var_field(d, "HOMEPAGE", deploy_package, "software_homePage") + set_var_field(d, "SUMMARY", deploy_package, "summary") + set_var_field(d, "DESCRIPTION", deploy_package, "description") + + set_purls(deploy_package, (d.getVar("SPDX_PACKAGE_URLS") or "").split()) + + set_timestamp_now(d, deploy_package, "builtTime") + + supplier = objset.new_agent("SPDX_PACKAGE_SUPPLIER") + if supplier is not None: + deploy_package.suppliedBy = ( + supplier if isinstance(supplier, str) else supplier._id + ) + + if files: + objset.new_relationship( + [deploy_package], + oe.spdx30.RelationshipType.contains, + sorted(list(files)), + ) + + objset.new_scoped_relationship( + [build], + oe.spdx30.RelationshipType.hasOutput, + oe.spdx30.LifecycleScopeType.build, + sorted(list(files) + [deploy_package]), + ) + + # Collect dependencies + if start_task is not None: + dep_builds = set() + dep_packages = set() + for o in find_build_dep_objsets(d, start_task): + if obj := o.find_root(oe.spdx30.software_Package): + dep_packages.add(oe.sbom30.get_element_link_id(obj)) + + if obj := o.find_root(oe.spdx30.build_Build): + dep_builds.add(oe.sbom30.get_element_link_id(obj)) + + if dep_packages: + objset.new_scoped_relationship( + [deploy_package], + oe.spdx30.RelationshipType.dependsOn, + oe.spdx30.LifecycleScopeType.build, + sorted(list(dep_packages)), + ) + + if dep_builds: + objset.new_scoped_relationship( + [build], + oe.spdx30.RelationshipType.dependsOn, + oe.spdx30.LifecycleScopeType.build, + sorted(list(dep_builds)), + ) + + return deploy_package + + def create_recipe_spdx(d): deploydir = Path(d.getVar("SPDXRECIPEDEPLOY")) pn = d.getVar("PN") @@ -790,7 +921,9 @@ def create_recipe_spdx(d): sorted(list(all_cves)), ) - oe.sbom30.write_recipe_jsonld_doc(d, recipe_objset, "static", deploydir) + oe.sbom30.write_recipe_jsonld_doc( + d, recipe_objset, "static", deploydir, create_task_link=True + ) def load_recipe_spdx(d): @@ -804,17 +937,6 @@ def load_recipe_spdx(d): def create_spdx(d): - def set_var_field(var, obj, name, package=None): - val = None - if package: - val = d.getVar("%s:%s" % (var, package)) - - if not val: - val = d.getVar(var) - - if val: - setattr(obj, name, val) - license_data = oe.spdx_common.load_spdx_license_data(d) pn = d.getVar("PN") @@ -943,10 +1065,12 @@ def create_spdx(d): ) set_var_field( - "HOMEPAGE", spdx_package, "software_homePage", package=package + d, "HOMEPAGE", spdx_package, "software_homePage", package=package + ) + set_var_field(d, "SUMMARY", spdx_package, "summary", package=package) + set_var_field( + d, "DESCRIPTION", spdx_package, "description", package=package ) - set_var_field("SUMMARY", spdx_package, "summary", package=package) - set_var_field("DESCRIPTION", spdx_package, "description", package=package) purls = ( d.getVar("SPDX_PACKAGE_URLS:%s" % package) @@ -1133,7 +1257,9 @@ def create_spdx(d): f"Added PACKAGECONFIG entries: {len(enabled)} enabled, {len(disabled)} disabled" ) - oe.sbom30.write_recipe_jsonld_doc(d, build_objset, "builds", deploydir) + oe.sbom30.write_recipe_jsonld_doc( + d, build_objset, "builds", deploydir, create_task_link=True + ) def create_package_spdx(d): @@ -1369,26 +1495,9 @@ def create_rootfs_spdx(d): d, "%s-%s-rootfs" % (image_basename, machine) ) - rootfs = objset.add_root( - oe.spdx30.software_Package( - _id=objset.new_spdxid("rootfs", image_basename), - creationInfo=objset.doc.creationInfo, - name=image_basename, - software_primaryPurpose=oe.spdx30.software_SoftwarePurpose.archive, - ) - ) - set_timestamp_now(d, rootfs, "builtTime") - rootfs_build = objset.add_root(objset.new_task_build("rootfs", "rootfs")) set_timestamp_now(d, rootfs_build, "build_buildEndTime") - objset.new_scoped_relationship( - [rootfs_build], - oe.spdx30.RelationshipType.hasOutput, - oe.spdx30.LifecycleScopeType.build, - [rootfs], - ) - files_by_hash = {} collect_build_package_inputs(d, objset, rootfs_build, packages, files_by_hash) @@ -1421,14 +1530,20 @@ def create_rootfs_spdx(d): ) ) - if files: - objset.new_relationship( - [rootfs], - oe.spdx30.RelationshipType.contains, - sorted(list(files)), - ) + rootfs = create_deploy_package( + d, + objset, + rootfs_build, + objset.new_spdxid("rootfs", image_basename), + image_basename, + None, + files, + ) + rootfs.software_primaryPurpose = oe.spdx30.software_SoftwarePurpose.archive - oe.sbom30.write_recipe_jsonld_doc(d, objset, "rootfs", deploydir) + oe.sbom30.write_recipe_jsonld_doc( + d, objset, "rootfs", deploydir, create_task_link=True + ) def create_image_spdx(d): @@ -1508,10 +1623,13 @@ def create_image_spdx(d): set_timestamp_now(d, a, "builtTime") if artifacts: - objset.new_scoped_relationship( - [image_build], - oe.spdx30.RelationshipType.hasOutput, - oe.spdx30.LifecycleScopeType.build, + create_deploy_package( + d, + objset, + image_build, + objset.new_spdxid(taskname, "image", imagetype), + "image", + f"do_{taskname}", artifacts, ) @@ -1532,7 +1650,9 @@ def create_image_spdx(d): objset.add_aliases() objset.link() - oe.sbom30.write_recipe_jsonld_doc(d, objset, "image", spdx_work_dir) + oe.sbom30.write_recipe_jsonld_doc( + d, objset, "image", spdx_work_dir, create_task_link=True + ) def create_image_sbom_spdx(d): @@ -1720,3 +1840,80 @@ def create_recipe_sbom(d, deploydir): objset, sbom = oe.sbom30.create_sbom(d, sbom_name, [recipe], [recipe_objset]) oe.sbom30.write_jsonld_doc(d, objset, deploydir / (sbom_name + ".spdx.json")) + + +def create_deploy_spdx(d, spdxdeploydir, artifactsdir, artifacts): + pn = d.getVar("PN") + current_task = "do_" + d.getVar("BB_CURRENTTASK") + + recipe, recipe_objset = load_recipe_spdx(d) + + if artifacts == "AUTO": + artifacts = [] + for root, dirs, files in os.walk(artifactsdir): + for p in [Path(os.path.join(root, f)) for f in files]: + if p.is_file(): + artifacts.append(p) + else: + artifacts = [artifactsdir / p for p in artifacts.split()] + + artifacts.sort(key=lambda p: (p.is_symlink(), p)) + + objset = oe.sbom30.ObjectSet.new_objset(d, f"{pn}-{current_task}-deploy") + + build = objset.add_root(objset.new_task_build(current_task, "deploy")) + set_timestamp_now(d, build, "build_buildEndTime") + objset.set_is_native(get_is_native(d)) + + files = set() + for a in artifacts: + relpath = a.relative_to(artifactsdir) + f = objset.new_file( + objset.new_spdxid("deploy", str(relpath)), + a.name, + a, + ) + files.add(f) + + if not files: + if ( + d.getVar("SPDX_DEPLOY_ALLOW_EMPTY:task-" + d.getVar("BB_CURRENTTASK")) or "" + ) != "1": + bb.fatal(f"No deployed artifacts found in {artifactsdir}") + return + + create_deploy_package( + d, + objset, + build, + objset.new_spdxid("deploy", pn, current_task), + pn, + current_task, + files, + ) + + # Create document + dest = oe.sbom30.write_recipe_jsonld_doc( + d, + objset, + "deploy", + spdxdeploydir, + create_task_link=True, + ) + + +def create_deploy_sbom(d, deploydir, deploy_tasks): + pn = d.getVar("PN") + sbom_name = d.getVar("SPDX_DEPLOY_SBOM_NAME") + + objsets = [] + for t in deploy_tasks: + o, _ = oe.sbom30.find_jsonld(d, "deploy", f"{pn}-{t}-deploy", required=True) + objsets.append(o) + + root_objs = [] + for o in objsets: + root_objs.extend(o.doc.rootElement) + + objset, sbom = oe.sbom30.create_sbom(d, sbom_name, root_objs, objsets) + oe.sbom30.write_jsonld_doc(d, objset, deploydir / (sbom_name + ".spdx.json")) diff --git a/meta/lib/oe/spdx_common.py b/meta/lib/oe/spdx_common.py index 07bf9650e2..9a862d9f5a 100644 --- a/meta/lib/oe/spdx_common.py +++ b/meta/lib/oe/spdx_common.py @@ -118,7 +118,7 @@ def collect_direct_deps(d, dep_task): ) for this_dep in taskdepdata.values(): - if this_dep[0] == pn and this_dep[1] == current_task: + if this_dep.pn == pn and this_dep.taskname == current_task: break else: bb.fatal(f"Unable to find this {pn}:{current_task} in taskdepdata") From patchwork Wed Nov 4 15:33:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102924 Received: from mail-oa1-f54.google.com (mail-oa1-f54.google.com [209.85.160.54]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11865.1793806542339566873 for ; Wed, 04 Nov 2026 07:35:42 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=xnIky3Ro; spf=pass (domain: gmail.com, ip: 209.85.160.54, mailfrom: jpewhacker@gmail.com) Received: by mail-oa1-f54.google.com with SMTP id 586e51a60fabf-483c607ccb4so538262fac.0 for ; Wed, 04 Nov 2026 07:35:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806541; x=1794411341; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Z1y3RBDJoDIw4KgYSPBJM4umu5zeYQMe7A/eNaaMe0w=; b=xnIky3RoKlFw9fsYf/Ymg4a+FspZRub84Tof26ePiVxWGBmTPlC0d1QPDER2HAm8K5 0HhGDx1iyM8nrwID6X5kIJwxNp17FyMa8dIgiJCy+EBiqaohhWSSLD83tIDFDpApGLex 9Fm/s0GHuvtNWbT2oYE6talD72R+4zs4Y80V4u0cl9uOnPswFxcahdkSoOBCTjGIUR25 roZlQ6G+TutLvNS84wHa3x16jJ7Txl5F42QqCpc9JVnDKHhZYWz5CVSG0mciI6/dc+yj LPDGtN1kxdVQEHa0vH7k7dBJm4l8IeAIadmdgIHR8NwbAvTYVgis/A4vnhNeQyO2GrnQ nYRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806541; x=1794411341; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Z1y3RBDJoDIw4KgYSPBJM4umu5zeYQMe7A/eNaaMe0w=; b=NRmtZc4WMAGpA8+ZiYDFWjCnkw8yJFRc50XhQX/ITsm8VBVR9YfLhK7BpHBypVcAYk EowX1GXslHyJzD0E5hjcfO6hxw61+qXGDPJ30ldCsbCGhwH6RaOrNXnQYYJl0uhnizC9 +tPPcjOgpRNydCgK9Ih0TiVTRFbYqOocKFN/PBVnS59HS/JwyeO8lDkDuFyUvnlKstk6 em+e21m5AQPHVDLmoJTYda58wYwUKbT0WNrZ1YH1af5UvhfMWMiUmQNW679JCcYFUe9R WqcgRZlQA3aA292JGL5BmbLZ9769soDW+zY0Y67a5zM2oVXoeeEotWQTV1apIDQiTHF8 MVwA== X-Gm-Message-State: APuU4Z9v4t2T6D4IpJxCI8MZhA/hXFWGicV3QgsbmCAEnf8XytyqKxRm 3yRopAP6zTlyhgAXQxjVJ1OMMZozTQy4fMrWV9i+2ZN8OW/z958f/ZkIci3OGw== X-Gm-Gg: AYBFou29Hc/UUXCuWz0tuyAYzTIMW71hvrOuPf6GzB1yT0m7HFPTq34jVlb2c79TlY1 tusbYe/xmPpaSRx4HKPg35z3AiJ3s5nIMoD83c0NAa2EIvekJAGc6smC5SvRxvLNXhay8f2X6N3 KJAvqXxHi82apV0stxwG8NcuwE8BJWzN1sq80kQ6U/YKJULRFDCywRMDnUR9ROFs1uBsTH9bMb7 P7rdsQHC29R2GUr0dU3R8hBUmRZrGgOtvbMTSISNwMajy1xXEKqC3DnWz/NbvcX/ur8ixsOZZBr nHUQuvSbAfitZ1cNsZ4hpbo0rgeJF8SEsrAbTV5dSSN8Px73LYQcnwhR9DtN4CQFKXk3GXs2HPu HP+G3/C4IniDCugihPuS2HXfpIhW7Dl9DYhsLRf9BS2PcPsMiTYzfavHmWaR35YoO61B5wOONhH HNnu92eK20n5ArTi9KXFrldKHDSW1boTtx5jf3PBhUWo/59tjjQz0XMBll3O3GlRXmIOWBaFgJJ 6Gt8IyzMFQxpQ+pgAX1T94eQvEwxwtOVdDcvseBAm+eLXZjNT+y4kfS/N71p/s8AlFhPG3uxoE2 +7dJS8cfo/UjqHrPMGMRULaRmoo= X-Received: by 2002:a05:6808:181f:b0:4fb:a089:bf26 with SMTP id 5614622812f47-5640ddf687dmr10139740b6e.56.1793806541368; Wed, 04 Nov 2026 07:35:41 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:41 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 3/9] oeqa: Add SPDX deploy SBoM test Date: Wed, 4 Nov 2026 08:33:56 -0700 Message-ID: <20261104153535.3184146-4-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:44 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249396 Adds a test that verifies that the deploy SBoM is created correctly Signed-off-by: Joshua Watt --- meta/lib/oeqa/selftest/cases/spdx.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py index c900558b44..8cc51c1369 100644 --- a/meta/lib/oeqa/selftest/cases/spdx.py +++ b/meta/lib/oeqa/selftest/cases/spdx.py @@ -485,3 +485,14 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): for candidate in objset.foreach_type(oe.spdx30.software_Package): self.assertIsNone(candidate.releaseTime) + + def test_deploy_sbom(self): + kernel_recipe = get_bb_var("PREFERRED_PROVIDER_virtual/kernel") + + objset = self.check_recipe_spdx( + "virtual/kernel", + f"{{DEPLOY_DIR_IMAGE}}/{kernel_recipe}-deploy-sbom.spdx.json", + ) + + # Document should be fully linked + self.check_objset_missing_ids(objset) From patchwork Wed Nov 4 15:33:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102925 Received: from mail-oo1-f53.google.com (mail-oo1-f53.google.com [209.85.161.53]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11866.1793806542973624314 for ; Wed, 04 Nov 2026 07:35:43 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=ua1em9b3; spf=pass (domain: gmail.com, ip: 209.85.161.53, mailfrom: jpewhacker@gmail.com) Received: by mail-oo1-f53.google.com with SMTP id 006d021491bc7-6b8e2d8df4fso520290eaf.1 for ; Wed, 04 Nov 2026 07:35:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806542; x=1794411342; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=/2WIZpwPimqavDkzbT1ZpVYufGFe+CtcAal/HZACf5Y=; b=ua1em9b31pU4ALP4OJII3ijc0gfZAZisGWROFT9lVsdvN4DT1iUgWnpcoIKFIJwQmF SxclQzMzuWi59Z/ABg4hx8PcvAQ34YsHctL4xQnNlBY6s5uzLeajtgMyQE/bM6kf/DHE z4ENgiCC1o7gtyu9uN2JQpBWysWReeDVU3EhE8cyX9RsLnP4orm5naCa/mupP2IC0QTR SDrkTbMhvvVpNxdfGeAaywxEzWEAStorTF+cZ557FvFQFsOGiM4wB//vIBfGjbc9YmrX HeiIZ8JxOp2/BQlqam2jfw9qvH0mI384nfbvctQ4ncRjZKDTS0dvPnp1CUiVHQpALv1i aumw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806542; x=1794411342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=/2WIZpwPimqavDkzbT1ZpVYufGFe+CtcAal/HZACf5Y=; b=0nbnuvNpHrefzEVLZbjFeLXi5NgnAzoJcTptdTE0nggWZSK8vHZCasuCcsHuqrR9KJ gWFA/P/oUI8fsIvcSjOIneELUXnjcy3VwFbMBVQ8qd3XLyyGhLQzngCdqE+UZ8c4ePhG lxc8iPKAy3U+pzPF0I2oodwVjPmXD/yIqCceAG5daMTCOlI9A9otABawq1457I7t54/v pmZP31MFSlNlR+ObSkxIM1DX/wXH1tuSmeUq/RkW58dQsxgpdffdiZEYRXDSEK6PaezF 1K/X69dzQVpAHk/kktu4muCF1GkaopWztz/cx76dAlNI3BeGxYRNfcVa6DwBKATiSSuP gD3g== X-Gm-Message-State: APuU4Z903U/jFTIAOJE30pvel85/P5e8XeT6HVfJ8ixtetQcFhl4LVSq 34mFBLkixbZZy6LUJ1bbzOrgJXDJa/YXk6cKOo0xD0EtLjx4qajBpQjHxdq90Q== X-Gm-Gg: AYBFou34Fprwf56Bx4c9ApFodBzQ0xczBbeNgor58/brkNDdAFwlx2N2oXySUEKhZdx S87gY/CWDku516se3KFLt4Yk990OWkD3Ol+yfr0BXE07qLvyOYk9W2tm0b7JnmiPu6dUmSrjpOC b6/2gNVCsqRIfyCzsceGV/F/VLkhjqwSQvwYVgrdyNSUKCrEH/cqN6e3Q21mOO6RtmvpgJKaFkB ckC7d5rzqQRLevUajyUU421za7etFK9+v1KBSaoKP8YEPs1GlLqxT902RYno27ACkaqA7Tk5a6E z4FOOkEBDZ/5eyhPPqGIY5j3ypzOFKGb9f0bVG07niPXGiOq5i4Q/chSrsJ3w1wSgAhRukinomg oTZwhSY1VMhBjH4BLZK3q8teJxv75WFTpyPrDdgpeUaRRJCuac8Ub6m4/PhIYzoDzn84vIB9NXk 1V2Rirom77mrQ/R1ICIpj6BMkTWLroS8AfspYwCW2GcUc94U7w7MILWUEceygUuoMt5yEFvL27q Ew9P3PHt0OEJaGwkFDClyklbthYaFAxJ3jZ7M6tJP/zw/+bCk6XmM1E4+pCfmdkP4jl4c1y5DFv vp0jjuhXDoR+iS9+gofPsZsZpOse X-Received: by 2002:a05:6808:6408:b0:4d6:9283:1df2 with SMTP id 5614622812f47-5640de79c53mr11156288b6e.61.1793806542039; Wed, 04 Nov 2026 07:35:42 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:41 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 4/9] classes-global/sstate: Keep SPDX generating setscene dependencies Date: Wed, 4 Nov 2026 08:33:57 -0700 Message-ID: <20261104153535.3184146-5-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:44 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249397 Tasks that create SPDX documents can reference SPDX ids from documents created by any task they depend on. When it comes time to create the final SBoM, these referenced SPDX ids must be present so that they can be merged into the SBoM. Specifically, when a task that restores from sstate (a setscene task) is one that can create an SPDX document, and that task is depended on by at least one other task that can create an SPDX document, it must always be restored. Signed-off-by: Joshua Watt --- meta/classes-global/sstate.bbclass | 38 ++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/meta/classes-global/sstate.bbclass b/meta/classes-global/sstate.bbclass index b2fa93650a..c6d9459182 100644 --- a/meta/classes-global/sstate.bbclass +++ b/meta/classes-global/sstate.bbclass @@ -1125,11 +1125,28 @@ def setscene_depvalid(task, taskdependees, notneeded, d, log=None): logit("Considering setscene task: %s" % (str(taskdependees[task])), log) - directtasks = ["do_populate_lic", "do_deploy_source_date_epoch", "do_shared_workdir", "do_stash_locale", "do_gcc_stash_builddir", "do_create_spdx", "do_create_recipe_spdx", "do_deploy_archives"] + directtasks = ["do_populate_lic", "do_deploy_source_date_epoch", "do_shared_workdir", "do_stash_locale", "do_gcc_stash_builddir", "do_deploy_archives"] + + # SPDX tasks are only needed if depended on directly, unless they are + # needed by another task that is creating SPDX documents + SPDX_TASKS = {"do_create_spdx", "do_create_recipe_spdx", "do_create_package_spdx"} def isNativeCross(x): return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross") + def isSpdxTask(key): + taskname = taskdependees[key][1] + # Tasks that start with "do_deploy" might be included in + # SPDX_DEPLOY_TASKS and should be kept + if taskname.startswith("do_deploy"): + return True + + # Tasks that are don't start with do_deploy, but still deploy SPDX data + if taskname in {"do_image_complete", "do_populate_sdk", "do_populate_sdk_ext"}: + return True + + return taskname in SPDX_TASKS + # We only need to trigger deploy_source_date_epoch through direct dependencies if taskdependees[task][1] in directtasks: return True @@ -1142,6 +1159,8 @@ def setscene_depvalid(task, taskdependees, notneeded, d, log=None): return False return True + spdx_deps = [] + for dep in taskdependees: logit(" considering dependency: %s" % (str(taskdependees[dep])), log) if task == dep: @@ -1198,12 +1217,27 @@ def setscene_depvalid(task, taskdependees, notneeded, d, log=None): # Target populate_sysroot need their dependencies return False - if taskdependees[dep][1] in directtasks: + # Collect dependees that create SPDX documents + if isSpdxTask(dep): + spdx_deps.append(dep) + continue + + if taskdependees[dep][1] in directtasks or taskdependees[dep][1] in SPDX_TASKS: continue # Safe fallthrough default logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log) return False + + # SPDX generating tasks can refer to the SPDXID from the SPDX output of + # their dependencies. Therefore if the current task can generate SPDX and + # is depended on by another SPDX generating task, it must be kept so that + # the IDs can be correctly resolved when merging SPDX output into a + # complete SBoM + if spdx_deps and isSpdxTask(task): + logit(f"Keeping SPDX task {taskdependees[task]} needed by SPDX task(s) {', '.join(str(taskdependees[k]) for k in spdx_deps)}", log) + return False + return True addhandler sstate_eventhandler From patchwork Wed Nov 4 15:33:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102926 Received: from mail-oa1-f54.google.com (mail-oa1-f54.google.com [209.85.160.54]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.11933.1793806543738734323 for ; Wed, 04 Nov 2026 07:35:43 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=QGQN5x4N; spf=pass (domain: gmail.com, ip: 209.85.160.54, mailfrom: jpewhacker@gmail.com) Received: by mail-oa1-f54.google.com with SMTP id 586e51a60fabf-48e94879f02so316813fac.0 for ; Wed, 04 Nov 2026 07:35:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806543; x=1794411343; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BWf9nPwSiawEirgLzEzSMAEs/S1YebD127It0ONYkPc=; b=QGQN5x4N2ZmjuHLHrelAcURX5L3D9Y3BK1CSmM9AvVbwIb4XPxVQD5i0tWflufuV3Y biRoS9TRrLJ+FMpan06uxrgkNQlHWaBTURVTFA3HLq2Sryj2WsCHjMx+Aj9stprbwUgw 4ZYuCLxcyBFHMoSfDHCqpAiYPLLv4RD4wXowdBwtEw7geMDL6qa3dmrn4BfYejCWBWIP mvT7ldQk75cGVAVI5a+1oINO9BvCnyZWqhLOjQnUY0tUiYKle4et4XYxys/8MoGp5ENT 9rX9pyjia22sgziuqKs6QM5HMw+pZK5oAigBvILFvvuiRZqNjsR+Knxgkgr1rM+sTi6G rVRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806543; x=1794411343; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=BWf9nPwSiawEirgLzEzSMAEs/S1YebD127It0ONYkPc=; b=Ja0nypdblUZy3ndZiurHszNK+TA9YP6wONYd5CpVyQQJICBByJ9LVoo7Djes/OISbI oKRSGfAkE2uaSoEQH/4LvaQItj6/8wYoJYu1VmZVlaWEaA8GmwWZpa9g9bzXS+YUtbVA Tcj0uqAzUIeHW6ttc2eY9qx+U55BHgi5PTXclr8NxVFzYH/KP5Nqb7gkFeu5rtkHvZdX COsE7XCadmAMoJohcRrCZ7GPDO68Qf1iYZtQX3MsHBu7ydJE4J5NfRH2YiDJjVaANz// M9W41lHH9ZEzC1/Xyy6lFyXUmRVmcZJ1QzZWvNYprFHuNBkB3MbjGsg6rw+F3WU1RSbF 9FaA== X-Gm-Message-State: APuU4Z9T0bU4zLeuFF+kMcxk21EdnEihQjvRcT7UdiS25wo2clQeNFuA TghzcLbbQRmXrN4Si3r4+QpeC1dISOOyo/5Q6FpDKvyhz/lKqyPZUwWhJQRL5g== X-Gm-Gg: AYBFou3QW+A97CiwKvankEBsABPFyKsXn1rdW9eJteKDluXYfSGoRTyp8HWjXrhbebA MN+FTXFiCXrw7kF4AokU5hKg40L9qP0N8xT1UbrKv4Hc1zpeOY2hF7Opk1WYLOvmnyumshjCCjk vEadMeuaMAjI2bEF45aeXTieETl8Ts5aOEchz+E5+obECks/Qczzkg5OXyeO0rwS2hq2csuEFRE C60AMlAP8QkULjRdjkMLrxBRiCuFUYWytBXd5yZ+vmaAJ/4IynV0wrEmUTfEzke35tUi6JyPPC5 HQFVyEdXZxFJ2pUnCnLLbfaaoSUZXXtod2VC8oR8BD9RXCM3KHyYmlQgJjhYPUBRHOwexd1LYF1 VQxf4BFE14sfdvxRcjzFPQg6Y9xb/3r6Lhg43fN+B9Oj7EGwr9Qyfyej4/sW9yY41VHbU/exihD ZASPk+wV226WCqUlOljsTLRS9RdYc1uIjtP6xMwQz8kT9bpvxtkae9HEeog2930JjJirQqK02Ll tccwPE434pEiYOe2KUZ081u3qYgGmU0Kj0LWosyO/4of/+j5ybst6Ll+QOeZhjZQt3W6X/SZh8P miMx1W5WipLakpMfNO6rnl9KZfo= X-Received: by 2002:a05:6808:179b:b0:4e4:86b1:f7a0 with SMTP id 5614622812f47-5640de57e3fmr10724240b6e.53.1793806542816; Wed, 04 Nov 2026 07:35:42 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:42 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 5/9] classes-recipe/deploy: Add do_deploy to SPDX_DEPLOY_TASKS Date: Wed, 4 Nov 2026 08:33:58 -0700 Message-ID: <20261104153535.3184146-6-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:45 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249399 Any recipe that inherits this class will automatically generate deploy SPDX data for the do_deploy task Signed-off-by: Joshua Watt --- meta/classes-recipe/deploy.bbclass | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/classes-recipe/deploy.bbclass b/meta/classes-recipe/deploy.bbclass index f222a8560f..a3b48d6f7a 100644 --- a/meta/classes-recipe/deploy.bbclass +++ b/meta/classes-recipe/deploy.bbclass @@ -6,6 +6,7 @@ DEPLOYDIR = "${WORKDIR}/deploy-${PN}" SSTATETASKS += "do_deploy" +SPDX_DEPLOY_TASKS += "do_deploy" SPDX_DEPLOY_ARTIFACTS_DIR:task-deploy = "${DEPLOYDIR}" do_deploy[sstate-inputdirs] = "${DEPLOYDIR}" do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}" From patchwork Wed Nov 4 15:33:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102927 Received: from mail-oo1-f51.google.com (mail-oo1-f51.google.com [209.85.161.51]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11867.1793806544645950549 for ; Wed, 04 Nov 2026 07:35:44 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=i6R8LxJJ; spf=pass (domain: gmail.com, ip: 209.85.161.51, mailfrom: jpewhacker@gmail.com) Received: by mail-oo1-f51.google.com with SMTP id 006d021491bc7-6df5e315bd1so695561eaf.2 for ; Wed, 04 Nov 2026 07:35:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806544; x=1794411344; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=znJsOH+KAlXRhXhiVX0zyArJLwg5I7pykD+KpriRkIo=; b=i6R8LxJJTa8Da6EckPjbU1ihGnm8zh0hjztb+G6gvlIMjCiLNyNcu842XiQbc2IljU 1W3GTMiE9aHarnMU5g+pcSRCEF+XYFJzFCwBAeeO9zTdTiqLlo8nWX4pSaG0Pk8vRSRX QX7L5r31zecsvgXJChkq+hBWvrnNnL6aK3VFLUgloQyC0kiTLTdH4lQf0WCKc1llecbf HK1ICL4By0ZtcrJ0uN6b/4AlaBZPxfXIBHHumpdBP1vOf0gmTk+CUdbe+qi//uIHM9lt TRv8xm8qz5WMpMUvIbdQHFjul6wHRS56jlWWDel2OXtQbr0EZjx94OHUr7hXVdgCgaBc TzNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806544; x=1794411344; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=znJsOH+KAlXRhXhiVX0zyArJLwg5I7pykD+KpriRkIo=; b=OQehuL8xyx5sX1eCm2je/iUri58k/952XaAslShl+D5kqptE4jbHSAjoqM+Ay8h6Kk 8fneWgr/bJ7SUdSyTTfXAXRxiyCrqrJmAebH4/aG0amSUlYkJ9Gf7J3yM0FADPR7nMAx yQVvqvrJ9wn0bqxcv1aorgmadcpLVw/tIiRn5IbCU2Ai+DtLeKvFC1Vcm4z1E5ZWNtti Kv4UQDpT13v7DCp/vLD2k9aAFG7gcrTSS/8bBe6tKE79GDTE2y8S8Bl62UDUeqduu/OG XEXHNH2+BPjsgAXlKbmi3yz+iMfDKOwTD209Cp7LikpiZGhgbZ4dNnBwy5GXteKoK0fr /vCg== X-Gm-Message-State: APuU4Z9Cj0bGZf1QLAiyjT7WXi5yKrNKHCNgCqpSf4hbqwhbbq1uC9v+ quFseC2CRnUBNAm2aeuLWS6mxKblytopBD6DyTrhSt6njioOy+R7LTqOMYHwiQ== X-Gm-Gg: AYBFou0Uc5MdKtOMPAIEsziBFvUO2n09xGo3EiCQPk+DbITllenAR/pE7vCzj6qLwyV e1/7u3ojsxjTYEQ+uSFvPWN06DSLnXqTAeerOUl4zWIpHdcd3ZZKj3kffjS8TyQhX0Zvt0OyvfV Gv7fxtT5AX3JPbw7mCvo6kj/+Gk4zkJR1HKDPOLvNFk0fyBDDDYDs30/D2qCB+aReM/rBie1wWI wxZW1PdHv2WO9xtZrEr+KNmgksQ6lbBTEvkC3x9SQRFgGDxF4n2p3ff+FHLth0YQ63r+DC3oLVl iEmx+bcdyGRi4Yd4RDXIDdnozaAQRo0Ns71YndCn2PIGZ1p/USF/qH1hmTU8yvHoCBsIJEBNvzV Y+cGWJhJPXOF1pHj6yxkc/a747tEVCPjOcOLE7OSdm8OoAmedSOMleP8XDLLXwFn9/a+DyiJThC /bYqUR9tVjsz8hsdfNGgIinIFm6dqrf6eul9tYP5MO98QLpAdToCcaVQ2B3eJ/qTjRRxA3rL1VF 4L7+5tbfD3KnC4zyX4IVblxe7wjoJZKmKAZz7iWD03Hwr2t6Te4iszr7IZwmjR7O1UtQxALlDEt FC6hmkp2+X4m33I5vyHLFRjthIJe X-Received: by 2002:a05:6808:3206:b0:4cb:818f:d56f with SMTP id 5614622812f47-5640deeb28cmr10965329b6e.23.1793806543716; Wed, 04 Nov 2026 07:35:43 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:43 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 6/9] spdx: Replace do_create_image_spdx with deploy task Date: Wed, 4 Nov 2026 08:33:59 -0700 Message-ID: <20261104153535.3184146-7-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:45 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249400 Replaces the dedicated do_create_image_spdx task with a deploy task tied to do_image_complete (which is task that deploys images). This has the advantage that images recipe SPDX dependencies are now completely automatically detected in the task graph, and the SPDX documents are merged in automatically when dependencies on do_image_complete are detected Signed-off-by: Joshua Watt --- .../create-spdx-image-3.0.bbclass | 32 +++++++------------ meta/classes-recipe/nospdx.bbclass | 1 - meta/classes/create-spdx-3.0.bbclass | 3 -- meta/classes/spdx-common.bbclass | 1 - meta/lib/oe/spdx30_tasks.py | 23 ++++++++----- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/meta/classes-recipe/create-spdx-image-3.0.bbclass b/meta/classes-recipe/create-spdx-image-3.0.bbclass index b60cdd826f..64cb065632 100644 --- a/meta/classes-recipe/create-spdx-image-3.0.bbclass +++ b/meta/classes-recipe/create-spdx-image-3.0.bbclass @@ -30,7 +30,7 @@ python do_create_rootfs_spdx() { import oe.spdx30_tasks oe.spdx30_tasks.create_rootfs_spdx(d) } -addtask do_create_rootfs_spdx after do_rootfs do_create_recipe_spdx before do_image +addtask do_create_rootfs_spdx after do_rootfs do_create_recipe_spdx before do_image do_image_complete SSTATETASKS += "do_create_rootfs_spdx" do_create_rootfs_spdx[sstate-inputdirs] = "${SPDXROOTFSDEPLOY}" do_create_rootfs_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}" @@ -43,33 +43,25 @@ python do_create_rootfs_spdx_setscene() { } addtask do_create_rootfs_spdx_setscene -python do_create_image_spdx() { +python create_image_spdx() { import oe.spdx30_tasks - oe.spdx30_tasks.create_image_spdx(d) -} -addtask do_create_image_spdx after do_image_complete do_create_rootfs_spdx do_create_recipe_spdx before do_build -SSTATETASKS += "do_create_image_spdx" -SSTATE_SKIP_CREATION:task-create-image-spdx = "1" -do_create_image_spdx[sstate-inputdirs] = "${SPDXIMAGEWORK}" -do_create_image_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}" -do_create_image_spdx[cleandirs] = "${SPDXIMAGEWORK}" -do_create_image_spdx[dirs] = "${SPDXIMAGEWORK}" -do_create_image_spdx[file-checksums] += "${SPDX3_DEP_FILES}" -do_create_image_spdx[vardeps] += "\ - SPDX_IMAGE_PURPOSE \ - " + from pathlib import Path + current_task = "do_" + d.getVar("BB_CURRENTTASK") -python do_create_image_spdx_setscene() { - sstate_setscene(d) -} -addtask do_create_image_spdx_setscene + spdxdeploydir = Path(d.getVar("SPDXDIR") + "/deploy-" + current_task) + oe.spdx30_tasks.create_image_spdx(d, spdxdeploydir) +} +oe.spdx30_tasks.create_image_spdx[vardeps] += "SPDX_IMAGE_PURPOSE" +SPDX_DEPLOY_TASKS += "do_image_complete:create_image_spdx" +# No deploy sbom is needed since do_create_image_sbom_spdx() is used instead +SPDX_DEPLOY_SBOM = "0" python do_create_image_sbom_spdx() { import oe.spdx30_tasks oe.spdx30_tasks.create_image_sbom_spdx(d) } -addtask do_create_image_sbom_spdx after do_create_rootfs_spdx do_create_image_spdx before do_build +addtask do_create_image_sbom_spdx after do_create_rootfs_spdx do_image_complete before do_build SSTATETASKS += "do_create_image_sbom_spdx" SSTATE_SKIP_CREATION:task-create-image-sbom-spdx = "1" do_create_image_sbom_spdx[sstate-inputdirs] = "${SPDXIMAGEDEPLOYDIR}" diff --git a/meta/classes-recipe/nospdx.bbclass b/meta/classes-recipe/nospdx.bbclass index 723194da2d..fafcdd0a13 100644 --- a/meta/classes-recipe/nospdx.bbclass +++ b/meta/classes-recipe/nospdx.bbclass @@ -10,6 +10,5 @@ deltask do_create_spdx deltask do_create_spdx_runtime deltask do_create_package_spdx deltask do_create_rootfs_spdx -deltask do_create_image_spdx deltask do_create_image_sbom_spdx deltask do_create_deploy_sbom diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index fb6a4f249e..0d0bddcc67 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -381,9 +381,6 @@ python () { # for the recipe, at least until it's possible for do_populate_sysroot # to describe it's own output. "do_populate_sysroot": "do_create_spdx", - # If an image is needed, also depend on the task to create the SBoM for - # the image - "do_image_complete": "do_create_image_spdx", } def map_task_deps(task, flag): diff --git a/meta/classes/spdx-common.bbclass b/meta/classes/spdx-common.bbclass index bca169670d..13839aac3a 100644 --- a/meta/classes/spdx-common.bbclass +++ b/meta/classes/spdx-common.bbclass @@ -15,7 +15,6 @@ CVE_VERSION ??= "${PV}" SPDXDIR ??= "${WORKDIR}/spdx/${SPDX_VERSION}" SPDXDEPLOY = "${SPDXDIR}/deploy" SPDXWORK = "${SPDXDIR}/work" -SPDXIMAGEWORK = "${SPDXDIR}/image-work" SPDXSDKWORK = "${SPDXDIR}/sdk-work" SPDXSDKEXTWORK = "${SPDXDIR}/sdk-ext-work" SPDXDEPS = "${SPDXDIR}/deps.json" diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 43e196806f..069c759523 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -1546,19 +1546,19 @@ def create_rootfs_spdx(d): ) -def create_image_spdx(d): +def create_image_spdx(d, spdx_deploy_dir): import oe.sbom30 - image_deploy_dir = Path(d.getVar("DEPLOY_DIR_IMAGE")) + pn = d.getVar("PN") + current_task = "do_" + d.getVar("BB_CURRENTTASK") + + image_deploy_dir = Path(d.getVar("IMGDEPLOYDIR")) manifest_path = Path(d.getVar("IMAGE_OUTPUT_MANIFEST")) - spdx_work_dir = Path(d.getVar("SPDXIMAGEWORK")) image_basename = d.getVar("IMAGE_BASENAME") machine = d.getVar("MACHINE") - objset = oe.sbom30.ObjectSet.new_objset( - d, "%s-%s-image" % (image_basename, machine) - ) + objset = oe.sbom30.ObjectSet.new_objset(d, f"{pn}-{current_task}-deploy") with manifest_path.open("r") as f: manifest = json.load(f) @@ -1651,13 +1651,18 @@ def create_image_spdx(d): objset.add_aliases() objset.link() oe.sbom30.write_recipe_jsonld_doc( - d, objset, "image", spdx_work_dir, create_task_link=True + d, + objset, + "deploy", + spdx_deploy_dir, + create_task_link=True, ) def create_image_sbom_spdx(d): import oe.sbom30 + pn = d.getVar("PN") image_name = d.getVar("IMAGE_NAME") image_basename = d.getVar("IMAGE_BASENAME") image_link_name = d.getVar("IMAGE_LINK_NAME") @@ -1679,7 +1684,9 @@ def create_image_sbom_spdx(d): root_elements.append(oe.sbom30.get_element_link_id(rootfs_image)) image_objset, _ = oe.sbom30.find_jsonld( - d, "image", "%s-%s-image" % (image_basename, machine), required=True + d, + "deploy", + f"{pn}-do_image_complete-deploy", ) for o in image_objset.foreach_root(oe.spdx30.software_File): root_elements.append(oe.sbom30.get_element_link_id(o)) From patchwork Wed Nov 4 15:34:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102928 Received: from mail-ot1-f53.google.com (mail-ot1-f53.google.com [209.85.210.53]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11869.1793806545574063074 for ; Wed, 04 Nov 2026 07:35:45 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=Hr1two/v; spf=pass (domain: gmail.com, ip: 209.85.210.53, mailfrom: jpewhacker@gmail.com) Received: by mail-ot1-f53.google.com with SMTP id 46e09a7af769-845788309b4so321252a34.1 for ; Wed, 04 Nov 2026 07:35:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806545; x=1794411345; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=JgGgrsdYcAYFv20+scFd1l2zyAhrCHmz+MgfiomwYHo=; b=Hr1two/vebX1SyR2U8kkplC2jb97eNDW4/EwxFuRcB/5vs9JmlY7rIZNgQB30W/eAE UDuD2kk5BU3XIOJr39sssrGFvHoovj3c9f8cGtXQqw3PoDsY251SjQd/XY1qqA0KrtgQ pPQj/9b1swrHkFqhDi/NAfS0gj1QbO0JfLCL5uNsYaSlIeNIu6nKsc3L2i76lNU8KS/Z R3wAGki33zIlCL7GBlWCkGUzuFhKF8E9gSAkLjey952LC9CtQgD4R2uVI2cqe2haTMMX C7JqyyBGIcnEj4I1JGwFnrj4P0fwpXBsHQBGBqq/nPJ/ltEpVwwRtVQbfVTwKUN0g3XA /Swg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806545; x=1794411345; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=JgGgrsdYcAYFv20+scFd1l2zyAhrCHmz+MgfiomwYHo=; b=I3goZeKwIiZy1vR1RO2hLLhygMsfMykjsyMEvWkZds5QUMy7Zic0NqO8KE2H3y2ZMv /mFRtovRV3PwqHcnGdEOxC8Vtk4bz1roK4VoZUDO/XdRwS+ol0mvfADb51sVQwFMAOAV jbJd9E4OAtJCpjPnHBd79TrFALLONAtoedIikCYkFmKfONxdhnhOP0kxW87KYZtYGOlZ ZvTdo8QPceD+VblqvEisv3KNmXyLQNaUvQxHrKNf49aPHXLTtHogA3RJ1bWpizkCV7pB 8lNKLkQ+R355Xk1bscpu4PqHqq1xZimhseZ7vlqa5NrbW7rQMaWFQfJOeqNeeMge6llU stgQ== X-Gm-Message-State: APuU4Z+/giZx+9TQGms+zxYdvVUlFAPf8eWR1hupDqF+2k0NJIvLmFWn Ku/st/7lYDHTGAvVPicuLgqhDQlPeuA1zpCgP++ondoC3oLx7VY5TzKBdHWNEw== X-Gm-Gg: AYBFou1kIDpw/hA3foo3OQ44vhkStEU1QogdOjREWDqs/JeWkTGM2Ftyj+Osrqnt3A1 JtRKWczZAgE+ypd3rUpyYucgSEGOjM9R4j8rfG4wU4xbNsxGIx8GdgTCWhkvfrJA6iAT/tag6nY YfC4qOUHVutJP9p2V6C39pYGi9ia2R3tnPG4qNeItR4GoityilVJy74+bSkhjiL/Y7mx2doOg7Q gb03ED3Falvtp/URYIZxLU0x4eq1TGLi2S4ZiiKOWaSoIeYp/pu0/bW+f6d/o1+NGdT6Jc3zWHS mZE4JrVajpYXlndOdfYV6ucpr9p1ernRXStx7jiW4+8hWjJNFGxjwPEsfZqpbjZwGW/mSKln0qv PEZ1MtjsRYOIr2byh05Imuq1xrAlxUgOqlroSi/1wvfrLzJ0jfLCNhEdZzwGo/XGOu2k9L03P2V 07GgAj18lpo/0dQZw/2vzD/v1pwAEBawhWd3yqFlkGxddY//z9sF2gk9Rp01c3DRa102su4XZHO bpkatpWlkGrWfMCVlscFotzJverfQgxjkWA8Y+vVbFaxUiTizGezWLtAD0O3MIrArbd1OQdo7Ct Z19pfMQ6c6GL7NNIFtAfUivcgh/inOu9w/n6u6e65N0I3uz3 X-Received: by 2002:a05:6808:c413:b0:4f3:e98f:fa26 with SMTP id 5614622812f47-5640de625damr11693287b6e.58.1793806544558; Wed, 04 Nov 2026 07:35:44 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:44 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 7/9] layer.conf: Fix initramfs-framework not knowing which udev it has Date: Wed, 4 Nov 2026 08:34:00 -0700 Message-ID: <20261104153535.3184146-8-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:55 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249401 The SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS from initramfs-framework to eudev and systemd meant that it would not correctly update when switching udev providers (for example, when switching from the "poky" distro to "poky-altcfg" distro). Fix this by removing both entries. This also requires that the recipe no longer be allarch since it will change based on distro. Signed-off-by: Joshua Watt --- meta/conf/layer.conf | 2 -- meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb | 2 -- 2 files changed, 4 deletions(-) diff --git a/meta/conf/layer.conf b/meta/conf/layer.conf index 13c920be6c..b55d50c60c 100644 --- a/meta/conf/layer.conf +++ b/meta/conf/layer.conf @@ -59,8 +59,6 @@ SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS += " \ docbook-xsl-stylesheets->perl \ ca-certificates->openssl \ initramfs-framework->${VIRTUAL-RUNTIME_base-utils} \ - initramfs-framework->eudev \ - initramfs-framework->systemd \ initramfs-module-install-efi->dosfstools \ initramfs-module-install-efi->e2fsprogs \ initramfs-module-install-efi->parted \ diff --git a/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb b/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb index 2ec03bc34c..2c5ff10813 100644 --- a/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb +++ b/meta/recipes-core/initrdscripts/initramfs-framework_1.0.bb @@ -4,8 +4,6 @@ LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384 RDEPENDS:${PN} += "${VIRTUAL-RUNTIME_base-utils}" RRECOMMENDS:${PN} = "${VIRTUAL-RUNTIME_base-utils-syslog}" -inherit allarch - SRC_URI = "file://init \ file://exec \ file://nfsrootfs \ From patchwork Wed Nov 4 15:34:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102929 Received: from mail-oi1-f169.google.com (mail-oi1-f169.google.com [209.85.167.169]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11870.1793806546882519766 for ; Wed, 04 Nov 2026 07:35:46 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=cxabRe2d; spf=pass (domain: gmail.com, ip: 209.85.167.169, mailfrom: jpewhacker@gmail.com) Received: by mail-oi1-f169.google.com with SMTP id 5614622812f47-4c5d8c7f326so311790b6e.1 for ; Wed, 04 Nov 2026 07:35:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806546; x=1794411346; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BTYMigd0+ZyC4B85UyNY8s3jidM5wVxaP5djY52xhfM=; b=cxabRe2dIDWW7Da23Ygi9A/REHjtYB/ZThDLz3yGwPK4YqNKhGR6K4dtT7XeKB5vrd SyXePapJs0PJp6cruVp26wBDPOFKUDnGeUoe9Mqirl94WHhAH3LZRrdqMmMxQHXEAgHH ldlANVeeGwj52eWi0F1D/5j+/sJ8I8h/GgA+9RbbYluHZT9igM6DbMKxS1bvdcj4+lzj pF71G9rkt6/4rwUuNyhzB5agA1Lw87TlmOCP8LrXf46ejVrhDrDXFhl3/nuacDbe77Vl Q+lHQrJRE8RR+iPeCBGsINZfzOa4vuXT8W2iD1G/LaaOdd7iRbNwfpVMN9N7TMErNftj FQlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806546; x=1794411346; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=BTYMigd0+ZyC4B85UyNY8s3jidM5wVxaP5djY52xhfM=; b=EGuOffJ9apkA9Mj/3j9ubGy+orGWc4EalIJFjDyY4VzMiKZhqJsSys5PhbCtB21n71 7yLcjTNkp1a1RDHxJjwF8fKbLwuFSDagk6rQ+W2x08RG0axC9ktgV2X+f0MKBlFZKYrN zVWnF3is5exOjQGm7MIQtDAlFUKamZak7nj/4cLjc3gq8USZH2ajsMUDbR0AmowwTumN ClqcYXxjtwA3lSYhVySmKWEOLeOs8HJ/oDHLn5UlxLVdu0YwBq9pDR+Gt2OUW4SSWowD 9ynoK6Pr8/aLeKCls6rhHIjOBXekzx7WCWqfJwMgDNmXaNApVunrLp1cHBOoIyWrXqGe qZNg== X-Gm-Message-State: APuU4Z/eVGi5E8HYrL4bNwLy+5AyPi/OyXEZ4A/duqvmdaJN93lk3Bxp a/YOTsw+gOF5NMsrEhAODrKyTBpe0juIydDzKKw3T1MCO6rto7Cq1zj+Hweb4Q== X-Gm-Gg: AYBFou1ySkW4+UWpPh8xssae1Zu1i1+SgOzXy1QyBa01yMSF7D/DV/3gZHKrk+yVP7f GqVFcj+OtyzOIdLPujXE3MCNatiKBiwSC7FYzL6+qzEofK59Kn5ECvGiKYYKahSpLzpHsVs1ecF 3wLVtfDTXZS/uXA2ddPm2YOqOuolaq762v+ID9+WE7VRv82N3TFaaEgqvGxrSi582eQHGCO6vBl gWXFHRygfG8/eCnSMMVGjbprboSKilAOTQ5mhff7rPHz/RVuSHrSRGgomE59RXgXZugGguQdpU9 jYtZaj2WfatWitwNHdVAaYfBcjYB+j1IzAMA/eT5u1xiq2nkxUFfanVwuoHH8G8UpwjNvXxEnGi ZJdGB0DqXKH/GpOTfie1PlZuuRoT/oeERG4O9UCv0MDq3ISSAClTYMf64h0YMhNlE1U4csQOozV tPirU/0B/QohigcnKIktCwlEnvFygRaSoxTxJS89fRwLaihz7cM73D/AEQfsvtTpoJ5+KMFDPcm vSfz5Ld6EevWjBSauF/HF+5JbSGx5hEmI9nosV4d8AHvj2xJ2Jd+d4qrFwXZcSmrTVQOMI3+P// pkO5AcC6tV/78vQIKVzHd+BUmRGoDFW1wUS+JqDAS8aToJZm X-Received: by 2002:a05:6808:6503:b0:53b:1d13:dffd with SMTP id 5614622812f47-5640d917ea3mr11707243b6e.7.1793806545917; Wed, 04 Nov 2026 07:35:45 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:44 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 8/9] ovmf: Allow empty SPDX deploy artifacts Date: Wed, 4 Nov 2026 08:34:01 -0700 Message-ID: <20261104153535.3184146-9-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:55 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249402 In native builds, ovfm do_deploy doesn't produce any artifacts. Set the SPDX_DEPLOY_ALLOW_EMPTY flag to prevent SPDX from erroring when this occurs. Signed-off-by: Joshua Watt --- meta/recipes-core/ovmf/ovmf_git.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb index bf69108f0a..7cc844dfa6 100644 --- a/meta/recipes-core/ovmf/ovmf_git.bb +++ b/meta/recipes-core/ovmf/ovmf_git.bb @@ -249,5 +249,6 @@ do_deploy:class-target() { fi } addtask do_deploy after do_compile before do_build +SPDX_DEPLOY_ALLOW_EMPTY:task-deploy = "1" BBCLASSEXTEND = "native" From patchwork Wed Nov 4 15:34:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joshua Watt X-Patchwork-Id: 102930 Received: from mail-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.50]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.11871.1793806548433220465 for ; Wed, 04 Nov 2026 07:35:48 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20260707 header.b=NEGFlf41; spf=pass (domain: gmail.com, ip: 209.85.210.50, mailfrom: jpewhacker@gmail.com) Received: by mail-ot1-f50.google.com with SMTP id 46e09a7af769-8451a619da7so550148a34.1 for ; Wed, 04 Nov 2026 07:35:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793806547; x=1794411347; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=eQGYr8GCQvUsr05n7h4ns23NXlVBlfSkuZZYFiRn/H0=; b=NEGFlf41kHXDfjY11MooK2bpejdE7BACGicyGwG/wU+ntBEWJ2o9EA204+XqwkECtg pMRsksaXp6ch2goFZAQjZuJgsqmMfwiwmNM7Ar8I2MQKp2t5Ei8l7JGvzCz1AJ4CukAy DDHavPzeVeW5fuBnix3rM+45NdwLIqAdvNZL/V+KvIPgUtZQ8HsSX2IQrzRBHUYec8LR R4U8Rs4AnPiazJLwtYkgK3L7pDBekOq/yiggo9EgLa476eBTlekezkLp2vwlOyrVS7lX 8heO/Avd1bsDa8L2pZQYG8W25tXwGz3YM3Ltcj5quzuBt0s5gvqdEqTwD1E7M5ybszkW ZAjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793806547; x=1794411347; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=eQGYr8GCQvUsr05n7h4ns23NXlVBlfSkuZZYFiRn/H0=; b=I5Ql5iX93gjmtfMAkbiGifvyMdV8vKBtDvfn0XInRczN5T3OPz9AtE8XAWcSnGI1kp WWST0oL0XjAZ5tzUp2ijrELwj0kCEU4HQZYhxetf12uiSupa9y0DsQjwzkYZn9QErgjh b9VgoASM/WZUetvt7/ZhwBmCzSM/p8SWc10Jtt24m4TnoVJonG6UgCNKLtgT7tO3mcp5 Mq3SqaUaZKaan6kfFGYew+8MF0TOgoiqBuuYpkyFMlvE0iLYf6vMa3NLJJtly3W7cQrj sC/eyFnUTqAtEqmlRIjpbBJ6/NaNYSTJld+JJLoUK/XqGewAedb5TaVXExvSSwkmkfeD LtlQ== X-Gm-Message-State: APuU4Z/QrCm72KTfA2aF3uSQvR4U+aQykn7cUFs42bHKMc0oGRkNKhVD ZI5Kikw0GkU811J95A6ahg71PftNc3tP7HF+Or/p36yqw9HVw6xgFmfTei2XHQ== X-Gm-Gg: AYBFou3zd6IpX3kJ72wadKZz26FcAGcS/owf4H2WyG99z/FSZtjX2A1gtUcRNUIdkKq z6lplYvZ3medfX209rQxORyOF/SO+imNO/CAO0FynAsup3VOhy6YRF9I+/W+ZowUNMiG0bEmRj5 Nz7HphHEVI9ErXNudDLUb1TgOqVHO1fu2dvDBgrFpGg84ZDYMyemkGwP2h3O8DTXiLnHy3rial9 tjmgjhb0EL7kUGVRmmgQzf42VpuFk9lF+Cu5v38IjUfVBjbJLqmSkPcEgZq3tPTm7EY3mEW91Yh jiruPTGt7JqcFzMKgX3oYrxWdPLeklsCuyiKzpj5JVfp8l7MGMfbMXkdCfKXXeJTc1jyxHBrV2W QgIiEqSnfkoYuh0axUMK4HNkrIr46vVBYQGYHI7VSoqJw+zcPPumlrLNetMSRRw5T6i0NeOOziT 0s5FxmkWr90gU3MEubhaknSeTL1Id4lkHSGIyMc/kY2VFvP3/AkbAn0IXkv61DLyQ2bKFWmSA2q 0DTx+Sfj+NPoR1pido3JM2qRhnapMReFJvotAhjAl0gLiVxvXca+RaZddRkp6F7t+pYekio4fUe J8414VOgLgjZPULZzy6VF83trJM= X-Received: by 2002:a05:6808:4e0b:b0:564:3fe1:2f95 with SMTP id 5614622812f47-5643fe14f4amr6879850b6e.56.1793806547426; Wed, 04 Nov 2026 07:35:47 -0800 (PST) Return-Path: Received: from localhost.localdomain ([2601:283:4b01:ba50::1d6f]) by smtp.gmail.com with ESMTPSA id 5614622812f47-567a9f9f8basm1894928b6e.12.2026.11.04.07.35.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Nov 2026 07:35:46 -0800 (PST) From: Joshua Watt X-Google-Original-From: Joshua Watt To: openembedded-core@lists.openembedded.org Cc: Joshua Watt Subject: [OE-core][PATCH v8 9/9] linux-dummy: Allow empty SPDX deploy artifacts Date: Wed, 4 Nov 2026 08:34:02 -0700 Message-ID: <20261104153535.3184146-10-JPEWhacker@gmail.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104153535.3184146-1-JPEWhacker@gmail.com> References: <20261028220609.1348489-1-JPEWhacker@gmail.com> <20261104153535.3184146-1-JPEWhacker@gmail.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Wed, 04 Nov 2026 15:35:55 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/249403 The recipe doesn't deploy anything so set SPDX_DEPLOY_ALLOW_EMPTY so that it doesn't generate an error Signed-off-by: Joshua Watt --- meta/recipes-kernel/linux/linux-dummy.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta/recipes-kernel/linux/linux-dummy.bb b/meta/recipes-kernel/linux/linux-dummy.bb index d7f39a452d..c45352aab2 100644 --- a/meta/recipes-kernel/linux/linux-dummy.bb +++ b/meta/recipes-kernel/linux/linux-dummy.bb @@ -23,6 +23,8 @@ FILES:kernel-vmlinux = "" ALLOW_EMPTY:kernel-vmlinux = "1" DESCRIPTION:kernel-vmlinux = "Kernel vmlinux meta package" +SPDX_DEPLOY_ALLOW_EMPTY:task-deploy = "1" + INHIBIT_DEFAULT_DEPS = "1" COMPATIBLE_HOST = ".*-linux"