aboutsummaryrefslogtreecommitdiffstats
path: root/classes/bom.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'classes/bom.bbclass')
-rw-r--r--classes/bom.bbclass212
1 files changed, 212 insertions, 0 deletions
diff --git a/classes/bom.bbclass b/classes/bom.bbclass
new file mode 100644
index 0000000..a4c645f
--- /dev/null
+++ b/classes/bom.bbclass
@@ -0,0 +1,212 @@
+# This class integrates real-time license scanning, generation of SPDX standard
+# output and verifiying license info during the building process.
+# It is a combination of efforts from the OE-Core, SPDX and bom projects.
+#
+# For more information on the following :
+# https://github.com/kubernetes-sigs/bom
+#
+# For more information on SPDX:
+# http://www.spdx.org
+# install bom on your host:https://github.com/kubernetes-sigs/bom
+HOSTTOOLS += "bom"
+
+COPYLEFT_RECIPE_TYPES ?= 'target nativesdk'
+inherit copyleft_filter
+inherit spdx-common
+HOSTTOOLS += "bom"
+
+do_get_report[dirs] = "${SPDX_OUTDIR}"
+
+CREATOR_TOOL = "bom.bbclass in meta-spdxscanner"
+
+python () {
+ pn = d.getVar('PN')
+ #If not for target, won't creat spdx.
+ if bb.data.inherits_class('nopackages', d) and not pn.startswith('gcc-source'):
+ return
+
+ assume_provided = (d.getVar("ASSUME_PROVIDED") or "").split()
+ if pn in assume_provided:
+ for p in d.getVar("PROVIDES").split():
+ if p != pn:
+ pn = p
+ break
+
+ # glibc-locale: do_fetch, do_unpack and do_patch tasks have been deleted,
+ # so avoid archiving source here.
+ if pn.startswith('glibc-locale'):
+ return
+ if (d.getVar('PN') == "libtool-cross"):
+ return
+ if (d.getVar('PN') == "libgcc-initial"):
+ return
+ if (d.getVar('PN') == "shadow-sysroot"):
+ return
+
+ # We just archive gcc-source for all the gcc related recipes
+ if d.getVar('BPN') in ['gcc', 'libgcc'] \
+ and not pn.startswith('gcc-source'):
+ bb.debug(1, 'archiver: %s is excluded, covered by gcc-source' % pn)
+ return
+
+ def hasTask(task):
+ return bool(d.getVarFlag(task, "task", False)) and not bool(d.getVarFlag(task, "noexec", False))
+
+ manifest_dir = (d.getVar('SPDX_DEPLOY_DIR') or "")
+ if not os.path.exists( manifest_dir ):
+ bb.utils.mkdirhier( manifest_dir )
+
+ info = {}
+ info['pn'] = (d.getVar( 'PN') or "")
+ info['pv'] = (d.getVar( 'PKGV') or "").replace('-', '+')
+ info['pr'] = (d.getVar( 'PR') or "")
+
+ if (d.getVar('BPN') == "perf"):
+ info['pv'] = d.getVar("KERNEL_VERSION").split("-")[0]
+ if 'AUTOINC' in info['pv']:
+ info['pv'] = info['pv'].replace("AUTOINC", "0")
+
+ if d.getVar('SAVE_SPDX_ACHIVE'):
+ if d.getVar('PACKAGES') or pn.startswith('gcc-source'):
+ # Some recipes do not have any packaging tasks
+ if hasTask("do_package_write_rpm") or hasTask("do_package_write_ipk") or hasTask("do_package_write_deb") or pn.startswith('gcc-source'):
+ d.appendVarFlag('do_spdx', 'depends', ' %s:do_spdx_creat_tarball' % pn)
+
+ spdx_outdir = d.getVar('SPDX_OUTDIR')
+ if pn.startswith('gcc-source'):
+ spdx_name = "gcc-" + info['pv'] + "-" + info['pr'] + ".spdx"
+ else:
+ spdx_name = info['pn'] + "-" + info['pv'] + "-" + info['pr'] + ".spdx"
+
+ info['outfile'] = os.path.join(manifest_dir, spdx_name )
+ sstatefile = os.path.join(spdx_outdir, spdx_name )
+ if os.path.exists(info['outfile']):
+ bb.note(info['pn'] + "spdx file has been exist, do nothing")
+ return
+ if os.path.exists( sstatefile ):
+ bb.note(info['pn'] + "spdx file has been exist, do nothing")
+ create_manifest(info,sstatefile)
+ return
+
+ if d.getVar('PACKAGES') or pn.startswith('gcc-source'):
+ # Some recipes do not have any packaging tasks
+ if hasTask("do_package_write_rpm") or hasTask("do_package_write_ipk") or hasTask("do_package_write_deb"):
+ d.appendVarFlag('do_spdx', 'depends', ' %s:do_get_report' % pn)
+ d.appendVarFlag('do_get_report', 'depends', ' %s:do_spdx_get_src' % pn)
+ bb.build.addtask('do_spdx_get_src', 'do_configure', 'do_patch', d)
+ bb.build.addtask('do_get_report', 'do_configure', 'do_patch', d)
+ bb.build.addtask('do_spdx', 'do_configure', 'do_get_report', d)
+}
+
+python do_get_report(){
+
+ import os, sys, json, shutil
+
+ #If not for target, won't creat spdx.
+ if bb.data.inherits_class('nopackages', d):
+ return
+
+ bb.note("Begin to get report!")
+
+ pn = d.getVar('PN')
+
+ manifest_dir = (d.getVar('SPDX_DEPLOY_DIR') or "")
+ if not os.path.exists( manifest_dir ):
+ bb.utils.mkdirhier( manifest_dir )
+
+ spdx_workdir = d.getVar('SPDX_WORKDIR')
+ temp_dir = os.path.join(d.getVar('WORKDIR'), "temp")
+ spdx_temp_dir = os.path.join(spdx_workdir, "temp")
+ spdx_outdir = d.getVar('SPDX_OUTDIR')
+
+ cur_ver_code = get_ver_code(spdx_workdir).split()[0]
+ info = {}
+ info['workdir'] = (d.getVar('WORKDIR') or "")
+ info['pn'] = (d.getVar( 'PN') or "")
+ info['pv'] = (d.getVar( 'PV') or "").replace('-', '+')
+ info['package_download_location'] = (d.getVar( 'SRC_URI') or "")
+ if info['package_download_location'] != "":
+ info['package_download_location'] = info['package_download_location'].split()[0]
+ info['spdx_version'] = (d.getVar('SPDX_VERSION') or '')
+ info['outfile'] = os.path.join(manifest_dir, info['pn'] + "-" + info['pv'] + ".spdx" )
+ spdx_file = os.path.join(spdx_outdir, info['pn'] + "-" + info['pv'] + ".spdx" )
+ if os.path.exists(info['outfile']):
+ bb.note(info['pn'] + "spdx file has been exist, do nothing")
+ return
+ if os.path.exists( spdx_file ):
+ bb.note(info['pn'] + "spdx file has been exist, do nothing")
+ create_manifest(info,spdx_file)
+ return
+ info['data_license'] = (d.getVar('DATA_LICENSE') or '')
+ info['creator'] = {}
+ info['creator']['Tool'] = (d.getVar('CREATOR_TOOL') or '')
+ info['license_list_version'] = (d.getVar('LICENSELISTVERSION') or '')
+ info['package_homepage'] = (d.getVar('HOMEPAGE') or "")
+ info['package_summary'] = (d.getVar('SUMMARY') or "")
+ info['package_summary'] = info['package_summary'].replace("\n","")
+ info['package_summary'] = info['package_summary'].replace("'"," ")
+ info['package_contains'] = (d.getVar('CONTAINED') or "")
+ info['package_static_link'] = (d.getVar('STATIC_LINK') or "")
+ info['modified'] = "false"
+ info['external_refs'] = get_external_refs(d)
+ info['purpose'] = get_pkgpurpose(d)
+ info['release_date'] = (d.getVar('REALASE_DATE') or "")
+ info['build_time'] = get_build_date(d)
+ info['depends_on'] = get_depends_on(d)
+ info['pkg_spdx_id'] = get_spdxid_pkg(d)
+ srcuri = d.getVar("SRC_URI", False).split()
+ length = len("file://")
+ for item in srcuri:
+ if item.startswith("file://"):
+ item = item[length:]
+ if item.endswith(".patch") or item.endswith(".diff"):
+ info['modified'] = "true"
+ d.setVar('WORKDIR', d.getVar('SPDX_WORKDIR', True))
+ info['sourcedir'] = spdx_workdir
+ git_path = "%s/git/.git" % info['sourcedir']
+ if os.path.exists(git_path):
+ remove_dir_tree(git_path)
+ invoke_bom(info['sourcedir'],spdx_file)
+ bb.note("info['sourcedir'] = " + info['sourcedir'])
+ write_cached_spdx(info,spdx_file,cur_ver_code)
+ create_manifest(info,spdx_file)
+}
+
+def invoke_bom(OSS_src_dir, spdx_file):
+ import subprocess
+ import string
+ import json
+ import codecs
+ import logging
+
+ logger = logging.getLogger()
+ logger.setLevel(logging.INFO)
+ logging.basicConfig(level=logging.INFO)
+
+ path = os.getenv('PATH')
+ bom_cmd = bb.utils.which(os.getenv('PATH'), "bom")
+ bom_cmd = bom_cmd + " generate -d " + OSS_src_dir + " --output=" + spdx_file
+ bb.note("bom_cmd = " + bom_cmd)
+ print(bom_cmd)
+ try:
+ subprocess.check_output(bom_cmd,
+ stderr=subprocess.STDOUT,
+ shell=True)
+ except subprocess.CalledProcessError as e:
+ bb.fatal("Could not invoke bom Command "
+ "'%s' returned %d:\n%s" % (bom_cmd, e.returncode, e.output))
+
+SSTATETASKS += "do_spdx"
+python do_spdx_setscene () {
+ sstate_setscene(d)
+}
+addtask do_spdx_setscene
+do_spdx () {
+ echo "Create spdx file."
+}
+addtask do_spdx_get_src after do_patch
+addtask do_get_report after do_spdx_get_src
+addtask do_spdx
+do_build[recrdeptask] += "do_spdx"
+do_populate_sdk[recrdeptask] += "do_spdx"
+