From 67738a6e1d1574cc84888c32f9fb0c5bad03201e Mon Sep 17 00:00:00 2001 From: Thomas Perale Date: Mon, 26 Jan 2026 14:04:14 +0100 Subject: [PATCH] utils/generate-cyclonedx: fix dependencies w/o virtual Since its introduction in [1], by default the `generate-cyclonedx` script doesn't include buildroot's virtual packages in its 'components' list, unless using the `--virtual` argument. References to virtual packages present in the 'show-info' output are filtered out in the resulting dependencies. This patch fix the default CycloneDX dependencies generation without virtual packages to reference the packages that provide the virtual package instead of just dropping the virtual package itself. If we use the package `lbase64` that depends on the virtual package `luainterpreter` as an example. The 'dependency' entry looks like the following: ``` { "ref": "lbase64", "dependsOn": [ "host-skeleton", "skeleton-init-common", "skeleton-init-sysv", "toolchain-external-bootlin" ] } ``` The `luainterpreter` dependency is missing. After applying this patch, package that provides the `luainterpreter` is present: ``` { "ref": "lbase64", "dependsOn": [ "host-skeleton", "lua", "skeleton-custom", "skeleton-init-sysv" ] } ``` In the case of a virtual package provided by multiple packages all those packages will be listed. This happens when generating an SBOM on the entire Buildroot packages. [1] dbab39e2d9 support/scripts/generate-cyclonedx.py: add script to generate CycloneDX-style SBOM Signed-off-by: Thomas Perale Signed-off-by: Peter Korsgaard --- utils/generate-cyclonedx | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/utils/generate-cyclonedx b/utils/generate-cyclonedx index 04ce8fc3a1..2b6c6d63d3 100755 --- a/utils/generate-cyclonedx +++ b/utils/generate-cyclonedx @@ -337,7 +337,25 @@ def cyclonedx_vulnerabilities(show_info_dict): } for cve, components in cves.items()] -def br2_parse_deps(ref, show_info_dict, virtual=False): +def br2_virtual_is_provided_by(ref, show_info_dict) -> list: + """Retrieve the list of packages that provide a virtual package. + + Args: + ref (str): The identifier of the virtual package. + show_info_dict (dict): The JSON output of the show-info + command, parsed into a Python dictionary. + + Returns: + list: package list that provides the virtual package. + """ + return [ + name + for name, comp in show_info_dict.items() + if "provides" in comp and ref in comp["provides"] + ] + + +def br2_parse_deps(ref, show_info_dict, virtual=False) -> list: """This function will collect all dependencies from the show-info output. The dependency on virtual package will collect the final dependency without @@ -352,13 +370,15 @@ def br2_parse_deps(ref, show_info_dict, virtual=False): Returns: list: A list of dependencies of the 'ref' package. """ - deps = [] + deps = set() for dep in show_info_dict.get(ref, {}).get("dependencies", []): - if virtual or show_info_dict.get(dep, {}).get("virtual") is False: - deps.append(dep) + if not virtual and show_info_dict.get(dep, {}).get("virtual"): + deps.update(br2_virtual_is_provided_by(dep, show_info_dict)) + else: + deps.add(dep) - return deps + return list(deps) def main():