@@ -36,6 +36,19 @@ SPDX_LICENSES ??= "${COREBASE}/meta/files/spdx-licenses.json"
SPDX_CUSTOM_ANNOTATION_VARS ??= ""
+SPDX_CONCLUDED_LICENSE ??= ""
+SPDX_CONCLUDED_LICENSE[doc] = "The license concluded by manual or external \
+ license analysis. This should only be set when license analysis (manual review \
+ or external scanning tools) identifies differences from the declared LICENSE. \
+ When unset or empty, the concluded license defaults to the declared license, \
+ indicating no separate analysis was performed. When differences are found, the \
+ preferred approach is to correct the LICENSE field in the recipe and contribute \
+ the fix upstream to OpenEmbedded. Use this variable locally only when upstream \
+ contribution is not immediately possible or when the license conclusion is \
+ environment-specific. This allows tracking license analysis results in SBOM \
+ while maintaining recipe LICENSE field for build compatibility. \
+ Example: SPDX_CONCLUDED_LICENSE = 'MIT & Apache-2.0'"
+
SPDX_MULTILIB_SSTATE_ARCHS ??= "${SSTATE_ARCHS}"
python () {
@@ -712,6 +712,27 @@ def create_spdx(d):
oe.spdx30.RelationshipType.hasDeclaredLicense,
[oe.sbom30.get_element_link_id(package_spdx_license)],
)
+
+ # Add concluded license relationship
+ # Use SPDX_CONCLUDED_LICENSE if set, otherwise default to declared license
+ concluded_license_str = d.getVar("SPDX_CONCLUDED_LICENSE")
+ if concluded_license_str:
+ # Use explicitly set concluded license
+ if concluded_license_str != package_license and concluded_license_str != d.getVar("LICENSE"):
+ concluded_spdx_license = add_license_expression(
+ d, build_objset, concluded_license_str, license_data
+ )
+ else:
+ concluded_spdx_license = package_spdx_license
+ else:
+ # Default: concluded = declared (no analysis performed)
+ concluded_spdx_license = package_spdx_license
+
+ pkg_objset.new_relationship(
+ [spdx_package],
+ oe.spdx30.RelationshipType.hasConcludedLicense,
+ [oe.sbom30.get_element_link_id(concluded_spdx_license)],
+ )
# NOTE: CVE Elements live in the recipe collection
all_cves = set()