summaryrefslogtreecommitdiffstats
path: root/meta/classes/license.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/license.bbclass')
-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 4fd1f85130..a4d34e7c02 100644
--- a/meta/classes/license.bbclass
+++ b/meta/classes/license.bbclass
@@ -14,6 +14,42 @@ LICSSTATEDIR = "${WORKDIR}/license-destdir/"
14addtask populate_lic after do_patch before do_package 14addtask populate_lic after do_patch before do_package
15do_populate_lic[dirs] = "${LICSSTATEDIR}/${PN}" 15do_populate_lic[dirs] = "${LICSSTATEDIR}/${PN}"
16do_populate_lic[cleandirs] = "${LICSSTATEDIR}" 16do_populate_lic[cleandirs] = "${LICSSTATEDIR}"
17
18# Standards are great! Everyone has their own. In an effort to standardize licensing
19# names, common-licenses will use the SPDX standard license names. In order to not
20# break the non-standardized license names that we find in LICENSE, we'll set
21# up a bunch of VarFlags to accomodate non-SPDX license names.
22#
23# We should really discuss standardizing this field, but that's a longer term goal.
24# For now, we can do this and it should grab the most common LICENSE naming variations.
25#
26#GPL variations
27SPDXLICENSEMAP[GPL] = "GPL-1"
28SPDXLICENSEMAP[GPLv2] = "GPL-2"
29SPDXLICENSEMAP[GPLv3] = "GPL-3"
30
31#LGPL variations
32SPDXLICENSEMAP[LGPL] = "LGPL-2"
33SPDXLICENSEMAP[LGPLv2] = "LGPL-2"
34SPDXLICENSEMAP[LGPL2.1] = "LGPL-2.1"
35SPDXLICENSEMAP[LGPLv2.1] = "LGPL-2.1"
36SPDXLICENSEMAP[LGPLv3] = "LGPL-3"
37
38#MPL variations
39SPDXLICENSEMAP[MPL] = "MPL-1"
40SPDXLICENSEMAP[MPLv1] = "MPL-1"
41SPDXLICENSEMAP[MPLv1.1] = "MPL-1"
42
43#MIT variations
44SPDXLICENSEMAP[MIT-X] = "MIT"
45
46#Openssl variations
47SPDXLICENSEMAP[openssl] = "Openssl"
48
49#Other variations
50SPDXLICENSEMAP[AFL2.1] = "AFL-2"
51SPDXLICENSEMAP[EPLv1.0] = "EPL-1"
52
17python do_populate_lic() { 53python do_populate_lic() {
18 """ 54 """
19 Populate LICENSE_DIRECTORY with licenses. 55 Populate LICENSE_DIRECTORY with licenses.
@@ -21,6 +57,68 @@ python do_populate_lic() {
21 import os 57 import os
22 import bb 58 import bb
23 import shutil 59 import shutil
60 import ast
61
62 class LicenseVisitor(ast.NodeVisitor):
63 def generic_visit(self, node):
64 ast.NodeVisitor.generic_visit(self, node)
65
66 def visit_Str(self, node):
67 #
68 # Until I figure out what to do with
69 # the two modifiers I support (or greater = +
70 # and "with exceptions" being *
71 # we'll just strip out the modifier and put
72 # the base license.
73 find_license(node.s.replace("+", "").replace("*", ""))
74 ast.NodeVisitor.generic_visit(self, node)
75
76 def visit_BinOp(self, node):
77 op = node.op
78 if isinstance(op, ast.BitOr):
79 x = LicenseVisitor()
80 x.visit(node)
81 else:
82 ast.NodeVisitor.generic_visit(self, node)
83
84 def copy_license(source, destination, file_name):
85 try:
86 bb.copyfile(os.path.join(source, file_name), os.path.join(destination, file_name))
87 except:
88 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, file_name, source))
89 pass
90
91 def link_license(source, destination, file_name):
92 try:
93 os.symlink(os.path.join(source, file_name), os.path.join(destination, "generic_" + file_name))
94 except:
95 bb.warn("%s: Could not symlink: %s at %s to %s at %s" % (pn, file_name, source, file_name, destination))
96 pass
97
98 def find_license(license_type):
99
100 try:
101 bb.mkdirhier(gen_lic_dest)
102 except:
103 pass
104
105 # If the generic does not exist we need to check to see if there is an SPDX mapping to it
106 if not os.path.isfile(os.path.join(generic_directory, license_type)):
107 if bb.data.getVarFlag('SPDXLICENSEMAP', license_type, d) != None:
108 # Great, there is an SPDXLICENSEMAP. We can copy!
109 bb.warn("We need to use a SPDXLICENSEMAP for %s" % (license_type))
110 spdx_generic = bb.data.getVarFlag('SPDXLICENSEMAP', license_type, d)
111 copy_license(generic_directory, gen_lic_dest, spdx_generic)
112 link_license(gen_lic_dest, destdir, spdx_generic)
113 else:
114 # And here is where we warn people that their licenses are lousy
115 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
116 bb.warn("%s: There is also no SPDXLICENSEMAP for this license type: %s at %s" % (pn, license_type, generic_directory))
117 pass
118 elif os.path.isfile(os.path.join(generic_directory, license_type)):
119 copy_license(generic_directory, gen_lic_dest, license_type)
120 link_license(gen_lic_dest, destdir, license_type)
121
24 122
25 # All the license types for the package 123 # All the license types for the package
26 license_types = bb.data.getVar('LICENSE', d, True) 124 license_types = bb.data.getVar('LICENSE', d, True)
@@ -33,6 +131,12 @@ python do_populate_lic() {
33 srcdir = bb.data.getVar('S', d, True) 131 srcdir = bb.data.getVar('S', d, True)
34 # Directory we store the generic licenses as set in the distro configuration 132 # Directory we store the generic licenses as set in the distro configuration
35 generic_directory = bb.data.getVar('COMMON_LICENSE_DIR', d, True) 133 generic_directory = bb.data.getVar('COMMON_LICENSE_DIR', d, True)
134 bb.warn(generic_directory)
135 try:
136 bb.mkdirhier(destdir)
137 except:
138 pass
139
36 if not generic_directory: 140 if not generic_directory:
37 raise bb.build.FuncFailed("COMMON_LICENSE_DIR is unset. Please set this in your distro config") 141 raise bb.build.FuncFailed("COMMON_LICENSE_DIR is unset. Please set this in your distro config")
38 142
@@ -51,45 +155,18 @@ python do_populate_lic() {
51 if ret is False or ret == 0: 155 if ret is False or ret == 0:
52 bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile) 156 bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile)
53 157
54 # This takes some explaining.... we now are going to go an try to symlink 158 gen_lic_dest = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), "common-licenses")
55 # to a generic file. But, with the way LICENSE works, a package can have multiple
56 # licenses. Some of them are, for example, GPLv2+, which means it can use that version
57 # of GPLv2 specified in it's license, or a later version of GPLv2. For the purposes of
58 # what we're doing here, we really don't track license revisions (although we may want to)
59 # So, we strip out the + and link to a generic GPLv2
60 #
61 # That said, there are some entries into LICENSE that either have no generic (bzip, zlib, ICS)
62 # or the LICENSE is messy (Apache 2.0 .... when they mean Apache-2.0). This should be corrected
63 # but it's outside of scope for this.
64 #
65 # Also, you get some clever license fields with logic in the field.
66 # I'm sure someone has written a logic parser for these fields, but if so, I don't know where it is.
67 # So what I do is just link to every license mentioned in the license field.
68 159
69 for license_type in ((license_types.replace('+', '').replace('|', '&') 160 clean_licenses = ""
70 .replace('(', '').replace(')', '').replace(';', '') 161 for x in license_types.replace("(", " ( ").replace(")", " ) ").split():
71 .replace(',', '').replace(" ", "").split("&"))): 162 if ((x != "(") and (x != ")") and (x != "&") and (x != "|")):
72 if os.path.isfile(os.path.join(generic_directory, license_type)): 163 clean_licenses += "'" + x + "'"
73 gen_lic_dest = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), "common-licenses")
74 try:
75 bb.mkdirhier(gen_lic_dest)
76 except:
77 pass
78
79 try:
80 bb.copyfile(os.path.join(generic_directory, license_type), os.path.join(gen_lic_dest, license_type))
81 except:
82 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
83 pass
84 try:
85 os.symlink(os.path.join(gen_lic_dest, license_type), os.path.join(destdir, "generic_" + license_type))
86 except:
87 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory))
88 pass
89 else: 164 else:
90 bb.warn("%s: Something went wrong with copying: %s to %s" % (pn, license_type, generic_directory)) 165 clean_licenses += " " + x + " "
91 bb.warn("This could be either because we do not have a generic for this license or the LICENSE field is incorrect") 166
92 pass 167 node = ast.parse(clean_licenses)
168 v = LicenseVisitor()
169 v.visit(node)
93} 170}
94 171
95SSTATETASKS += "do_populate_lic" 172SSTATETASKS += "do_populate_lic"
@@ -102,4 +179,3 @@ python do_populate_lic_setscene () {
102} 179}
103addtask do_populate_lic_setscene 180addtask do_populate_lic_setscene
104 181
105