summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meta/classes/license.bbclass152
1 files changed, 114 insertions, 38 deletions
diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass
index 4fd1f8513..a4d34e7c0 100644
--- a/meta/classes/license.bbclass
+++ b/meta/classes/license.bbclass
@@ -14,6 +14,42 @@ LICSSTATEDIR = "${WORKDIR}/license-destdir/"
addtask populate_lic after do_patch before do_package
do_populate_lic[dirs] = "${LICSSTATEDIR}/${PN}"
do_populate_lic[cleandirs] = "${LICSSTATEDIR}"
+
+# Standards are great! Everyone has their own. In an effort to standardize licensing
+# names, common-licenses will use the SPDX standard license names. In order to not
+# break the non-standardized license names that we find in LICENSE, we'll set
+# up a bunch of VarFlags to accomodate non-SPDX license names.
+#
+# We should really discuss standardizing this field, but that's a longer term goal.
+# For now, we can do this and it should grab the most common LICENSE naming variations.
+#
+#GPL variations
+SPDXLICENSEMAP[GPL] = "GPL-1"
+SPDXLICENSEMAP[GPLv2] = "GPL-2"
+SPDXLICENSEMAP[GPLv3] = "GPL-3"
+
+#LGPL variations
+SPDXLICENSEMAP[LGPL] = "LGPL-2"
+SPDXLICENSEMAP[LGPLv2] = "LGPL-2"
+SPDXLICENSEMAP[LGPL2.1] = "LGPL-2.1"
+SPDXLICENSEMAP[LGPLv2.1] = "LGPL-2.1"
+SPDXLICENSEMAP[LGPLv3] = "LGPL-3"
+
+#MPL variations
+SPDXLICENSEMAP[MPL] = "MPL-1"
+SPDXLICENSEMAP[MPLv1] = "MPL-1"
+SPDXLICENSEMAP[MPLv1.1] = "MPL-1"
+
+#MIT variations
+SPDXLICENSEMAP[MIT-X] = "MIT"
+
+#Openssl variations
+SPDXLICENSEMAP[openssl] = "Openssl"
+
+#Other variations
+SPDXLICENSEMAP[AFL2.1] = "AFL-2"
+SPDXLICENSEMAP[EPLv1.0] = "EPL-1"
+
python do_populate_lic() {
"""
Populate LICENSE_DIRECTORY with licenses.
@@ -21,6 +57,68 @@ python do_populate_lic() {
import os
import bb
import shutil
+ import ast
+
+ class LicenseVisitor(ast.NodeVisitor):
+ def generic_visit(self, node):
+ ast.NodeVisitor.generic_visit(self, node)
+
+ def visit_Str(self, node):
+ #
+ # Until I figure out what to do with
+ # the two modifiers I support (or greater = +
+ # and "with exceptions" being *
+ # we'll just strip out the modifier and put
+ # the base license.
+ find_license(node.s.replace("+", "").replace("*", ""))
+ ast.NodeVisitor.generic_visit(self, node)
+
+ def visit_BinOp(self, node):
+ op = node.op
+ if isinstance(op, ast.BitOr):
+ x = LicenseVisitor()
+ x.visit(node)
+ else:
+ ast.NodeVisitor.generic_visit(self, node)
+
+ def copy_license(source, destination, file_name):
+ try:
+ bb.copyfile(os.path.join(source, file_name), os.path.join(destination, file_name))
+ except:
+ bb.warn("%s: No generic license file exists for: %s at %s" % (pn, file_name, source))
+ pass
+
+ def link_license(source, destination, file_name):
+ try:
+ os.symlink(os.path.join(source, file_name), os.path.join(destination, "generic_" + file_name))
+ except:
+ bb.warn("%s: Could not symlink: %s at %s to %s at %s" % (pn, file_name, source, file_name, destination))
+ pass
+
+ def find_license(license_type):
+
+ try:
+ bb.mkdirhier(gen_lic_dest)
+ except:
+ pass
+
+ # If the generic does not exist we need to check to see if there is an SPDX mapping to it
+ if not os.path.isfile(os.path.join(generic_directory, license_type)):
+ if bb.data.getVarFlag('SPDXLICENSEMAP', license_type, d) != None:
+ # Great, there is an SPDXLICENSEMAP. We can copy!
+ bb.warn("We need to use a SPDXLICENSEMAP for %s" % (license_type))
+ spdx_generic = bb.data.getVarFlag('SPDXLICENSEMAP', license_type, d)
+ copy_license(generic_directory, gen_lic_dest, spdx_generic)
+ link_license(gen_lic_dest, destdir, spdx_generic)
+ else:
+ # And here is where we warn people that their licenses are lousy
+ bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
+ bb.warn("%s: There is also no SPDXLICENSEMAP for this license type: %s at %s" % (pn, license_type, generic_directory))
+ pass
+ elif os.path.isfile(os.path.join(generic_directory, license_type)):
+ copy_license(generic_directory, gen_lic_dest, license_type)
+ link_license(gen_lic_dest, destdir, license_type)
+
# All the license types for the package
license_types = bb.data.getVar('LICENSE', d, True)
@@ -33,6 +131,12 @@ python do_populate_lic() {
srcdir = bb.data.getVar('S', d, True)
# Directory we store the generic licenses as set in the distro configuration
generic_directory = bb.data.getVar('COMMON_LICENSE_DIR', d, True)
+ bb.warn(generic_directory)
+ try:
+ bb.mkdirhier(destdir)
+ except:
+ pass
+
if not generic_directory:
raise bb.build.FuncFailed("COMMON_LICENSE_DIR is unset. Please set this in your distro config")
@@ -51,45 +155,18 @@ python do_populate_lic() {
if ret is False or ret == 0:
bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile)
- # This takes some explaining.... we now are going to go an try to symlink
- # to a generic file. But, with the way LICENSE works, a package can have multiple
- # licenses. Some of them are, for example, GPLv2+, which means it can use that version
- # of GPLv2 specified in it's license, or a later version of GPLv2. For the purposes of
- # what we're doing here, we really don't track license revisions (although we may want to)
- # So, we strip out the + and link to a generic GPLv2
- #
- # That said, there are some entries into LICENSE that either have no generic (bzip, zlib, ICS)
- # or the LICENSE is messy (Apache 2.0 .... when they mean Apache-2.0). This should be corrected
- # but it's outside of scope for this.
- #
- # Also, you get some clever license fields with logic in the field.
- # I'm sure someone has written a logic parser for these fields, but if so, I don't know where it is.
- # So what I do is just link to every license mentioned in the license field.
+ gen_lic_dest = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), "common-licenses")
- for license_type in ((license_types.replace('+', '').replace('|', '&')
- .replace('(', '').replace(')', '').replace(';', '')
- .replace(',', '').replace(" ", "").split("&"))):
- if os.path.isfile(os.path.join(generic_directory, license_type)):
- gen_lic_dest = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), "common-licenses")
- try:
- bb.mkdirhier(gen_lic_dest)
- except:
- pass
-
- try:
- bb.copyfile(os.path.join(generic_directory, license_type), os.path.join(gen_lic_dest, license_type))
- except:
- bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
- pass
- try:
- os.symlink(os.path.join(gen_lic_dest, license_type), os.path.join(destdir, "generic_" + license_type))
- except:
- bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
- pass
+ clean_licenses = ""
+ for x in license_types.replace("(", " ( ").replace(")", " ) ").split():
+ if ((x != "(") and (x != ")") and (x != "&") and (x != "|")):
+ clean_licenses += "'" + x + "'"
else:
- bb.warn("%s: Something went wrong with copying: %s to %s" % (pn, license_type, generic_directory))
- bb.warn("This could be either because we do not have a generic for this license or the LICENSE field is incorrect")
- pass
+ clean_licenses += " " + x + " "
+
+ node = ast.parse(clean_licenses)
+ v = LicenseVisitor()
+ v.visit(node)
}
SSTATETASKS += "do_populate_lic"
@@ -102,4 +179,3 @@ python do_populate_lic_setscene () {
}
addtask do_populate_lic_setscene
-