summaryrefslogtreecommitdiffstats
path: root/meta/classes
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2023-05-31 14:24:52 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-06-02 15:59:07 +0100
commit15acbd10906568a1ed9c548b465f1cb6b5205202 (patch)
treedd23d3054f0ac685dbdffaf051568a926dd4feb8 /meta/classes
parentaf0136ee4e5436d840d53a4cae856f88dbb4b660 (diff)
downloadpoky-15acbd10906568a1ed9c548b465f1cb6b5205202.tar.gz
classes/create-spdx-2.2: Fix build time dependency calculations
Build time dependencies were not being correctly calculated for SPDX documents because while a task can `deptask` itself (as do_create_spdx did), those dependencies do not appear in BB_TASKDEPDATA (to avoid circular dependencies). To fix this, an intermediate task called do_collect_sdpx_deps is created that does the 'deptask' on do_create_spdx and records the recipe dependencies. do_create_spdx then runs after this new task. This breaks the circular dependency and thus all of the do_create_spdx tasks correctly show up as dependencies of do_collect_spdx_deps. In addition, the dependency collection logic was improved to handle the case of transitive dependencies (that is, a dependency of a dependency) SPDX documents missing and causing an error. These transitive dependencies don't actually need to be included anyway since one can follow the relationship of the direct dependency to find them. As such, the code is reworked to find the current task in BB_TASKDEPDATA, and then only collect the immediate dependencies of the current task. (From OE-Core rev: 55b3f160b13c6db778db09476cc4c73e70c5e930) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes')
-rw-r--r--meta/classes/create-spdx-2.2.bbclass71
1 files changed, 54 insertions, 17 deletions
diff --git a/meta/classes/create-spdx-2.2.bbclass b/meta/classes/create-spdx-2.2.bbclass
index f12e155f6b..c461c77744 100644
--- a/meta/classes/create-spdx-2.2.bbclass
+++ b/meta/classes/create-spdx-2.2.bbclass
@@ -16,6 +16,7 @@ SPDXDEPLOY = "${SPDXDIR}/deploy"
16SPDXWORK = "${SPDXDIR}/work" 16SPDXWORK = "${SPDXDIR}/work"
17SPDXIMAGEWORK = "${SPDXDIR}/image-work" 17SPDXIMAGEWORK = "${SPDXDIR}/image-work"
18SPDXSDKWORK = "${SPDXDIR}/sdk-work" 18SPDXSDKWORK = "${SPDXDIR}/sdk-work"
19SPDXDEPS = "${SPDXDIR}/deps.json"
19 20
20SPDX_TOOL_NAME ??= "oe-spdx-creator" 21SPDX_TOOL_NAME ??= "oe-spdx-creator"
21SPDX_TOOL_VERSION ??= "1.0" 22SPDX_TOOL_VERSION ??= "1.0"
@@ -337,30 +338,21 @@ def add_package_sources_from_debug(d, package_doc, spdx_package, package, packag
337 338
338 package_doc.add_relationship(pkg_file, "GENERATED_FROM", ref_id, comment=debugsrc) 339 package_doc.add_relationship(pkg_file, "GENERATED_FROM", ref_id, comment=debugsrc)
339 340
340def collect_deps(d):
341 current_task = "do_" + d.getVar("BB_CURRENTTASK")
342
343 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
344 deps = sorted(set(
345 (dep[0], dep[7]) for dep in taskdepdata.values() if
346 dep[1] == current_task and dep[0] != d.getVar("PN")
347 ))
348
349 return deps
350
351collect_deps[vardepsexclude] += "BB_TASKDEPDATA"
352collect_deps[vardeps] += "DEPENDS"
353
354def collect_dep_recipes(d, doc, spdx_recipe): 341def collect_dep_recipes(d, doc, spdx_recipe):
342 import json
355 from pathlib import Path 343 from pathlib import Path
356 import oe.sbom 344 import oe.sbom
357 import oe.spdx 345 import oe.spdx
358 346
359 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX")) 347 deploy_dir_spdx = Path(d.getVar("DEPLOY_DIR_SPDX"))
348 spdx_deps_file = Path(d.getVar("SPDXDEPS"))
360 349
361 dep_recipes = [] 350 dep_recipes = []
362 351
363 for dep_pn, dep_hashfn in collect_deps(d): 352 with spdx_deps_file.open("r") as f:
353 deps = json.load(f)
354
355 for dep_pn, dep_hashfn in deps:
364 dep_recipe_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, "recipe-" + dep_pn, dep_hashfn) 356 dep_recipe_path = oe.sbom.doc_path_by_hashfn(deploy_dir_spdx, "recipe-" + dep_pn, dep_hashfn)
365 357
366 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_recipe_path) 358 spdx_dep_doc, spdx_dep_sha1 = oe.sbom.read_doc(dep_recipe_path)
@@ -462,6 +454,52 @@ def add_download_packages(d, doc, recipe):
462 # but this should be sufficient for now 454 # but this should be sufficient for now
463 doc.add_relationship(package, "BUILD_DEPENDENCY_OF", recipe) 455 doc.add_relationship(package, "BUILD_DEPENDENCY_OF", recipe)
464 456
457def collect_deps(d, dep_task):
458 current_task = "do_" + d.getVar("BB_CURRENTTASK")
459 pn = d.getVar("PN")
460
461 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
462
463 for this_dep in taskdepdata.values():
464 if this_dep[0] == pn and this_dep[1] == current_task:
465 break
466 else:
467 bb.fatal(f"Unable to find this {pn}:{current_task} in taskdepdata")
468
469 deps = set()
470 for dep_name in this_dep[3]:
471 dep_data = taskdepdata[dep_name]
472 if dep_data[1] == dep_task and dep_data[0] != pn:
473 deps.add((dep_data[0], dep_data[7]))
474
475 return sorted(deps)
476
477collect_deps[vardepsexclude] += "BB_TASKDEPDATA"
478collect_deps[vardeps] += "DEPENDS"
479
480python do_collect_spdx_deps() {
481 # This task calculates the build time dependencies of the recipe, and is
482 # required because while a task can deptask on itself, those dependencies
483 # do not show up in BB_TASKDEPDATA. To work around that, this task does the
484 # deptask on do_create_spdx and writes out the dependencies it finds, then
485 # do_create_spdx reads in the found dependencies when writing the actual
486 # SPDX document
487 import json
488 from pathlib import Path
489
490 spdx_deps_file = Path(d.getVar("SPDXDEPS"))
491
492 deps = collect_deps(d, "do_create_spdx")
493
494 with spdx_deps_file.open("w") as f:
495 json.dump(deps, f)
496}
497# NOTE: depending on do_unpack is a hack that is necessary to get it's dependencies for archive the source
498addtask do_collect_spdx_deps after do_unpack
499do_collect_spdx_deps[depends] += "${PATCHDEPENDENCY}"
500do_collect_spdx_deps[deptask] = "do_create_spdx"
501do_collect_spdx_deps[dirs] = "${SPDXDIR}"
502
465python do_create_spdx() { 503python do_create_spdx() {
466 from datetime import datetime, timezone 504 from datetime import datetime, timezone
467 import oe.sbom 505 import oe.sbom
@@ -647,7 +685,7 @@ python do_create_spdx() {
647 oe.sbom.write_doc(d, package_doc, d.getVar("SSTATE_PKGARCH"), "packages", indent=get_json_indent(d)) 685 oe.sbom.write_doc(d, package_doc, d.getVar("SSTATE_PKGARCH"), "packages", indent=get_json_indent(d))
648} 686}
649# NOTE: depending on do_unpack is a hack that is necessary to get it's dependencies for archive the source 687# NOTE: depending on do_unpack is a hack that is necessary to get it's dependencies for archive the source
650addtask do_create_spdx after do_package do_packagedata do_unpack before do_populate_sdk do_build do_rm_work 688addtask do_create_spdx after do_package do_packagedata do_unpack do_collect_spdx_deps before do_populate_sdk do_build do_rm_work
651 689
652SSTATETASKS += "do_create_spdx" 690SSTATETASKS += "do_create_spdx"
653do_create_spdx[sstate-inputdirs] = "${SPDXDEPLOY}" 691do_create_spdx[sstate-inputdirs] = "${SPDXDEPLOY}"
@@ -661,7 +699,6 @@ addtask do_create_spdx_setscene
661do_create_spdx[dirs] = "${SPDXWORK}" 699do_create_spdx[dirs] = "${SPDXWORK}"
662do_create_spdx[cleandirs] = "${SPDXDEPLOY} ${SPDXWORK}" 700do_create_spdx[cleandirs] = "${SPDXDEPLOY} ${SPDXWORK}"
663do_create_spdx[depends] += "${PATCHDEPENDENCY}" 701do_create_spdx[depends] += "${PATCHDEPENDENCY}"
664do_create_spdx[deptask] = "do_create_spdx"
665 702
666def collect_package_providers(d): 703def collect_package_providers(d):
667 from pathlib import Path 704 from pathlib import Path