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.bbclass219
1 files changed, 153 insertions, 66 deletions
diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass
index 8c6e2d2c9b..8c64e4cd8a 100644
--- a/meta/classes/license.bbclass
+++ b/meta/classes/license.bbclass
@@ -1,17 +1,12 @@
1# Populates LICENSE_DIRECTORY as set in distro config with the license files as set by 1# Populates LICENSE_DIRECTORY as set in distro config with the license files as set by
2# LIC_FILES_CHKSUM. 2# LIC_FILES_CHKSUM.
3# TODO: 3# TODO:
4# - We should also enable the ability to put the generated license directory onto the 4# - There is a real issue revolving around license naming standards.
5# rootfs
6# - Gather up more generic licenses
7# - There is a real issue revolving around license naming standards. See license names
8# licenses.conf and compare them to the license names in the recipes. You'll see some
9# differences and that should be corrected.
10 5
11LICENSE_DIRECTORY ??= "${DEPLOY_DIR}/licenses" 6LICENSE_DIRECTORY ??= "${DEPLOY_DIR}/licenses"
12LICSSTATEDIR = "${WORKDIR}/license-destdir/" 7LICSSTATEDIR = "${WORKDIR}/license-destdir/"
13 8
14addtask populate_lic after do_patch before do_package 9addtask populate_lic after do_patch before do_compile
15do_populate_lic[dirs] = "${LICSSTATEDIR}/${PN}" 10do_populate_lic[dirs] = "${LICSSTATEDIR}/${PN}"
16do_populate_lic[cleandirs] = "${LICSSTATEDIR}" 11do_populate_lic[cleandirs] = "${LICSSTATEDIR}"
17 12
@@ -22,33 +17,122 @@ do_populate_lic[cleandirs] = "${LICSSTATEDIR}"
22# 17#
23# We should really discuss standardizing this field, but that's a longer term goal. 18# 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. 19# For now, we can do this and it should grab the most common LICENSE naming variations.
25 20#
26#GPL variations 21# Changing GPL mapping to GPL-2 as it's not very likely to be GPL-1
27SPDXLICENSEMAP[GPL] = "GPL-1" 22# We should NEVER have a GPL/LGPL without a version!!!!
28SPDXLICENSEMAP[GPLv2] = "GPL-2" 23# Any mapping to MPL/LGPL/GPL should be fixed
29SPDXLICENSEMAP[GPLv3] = "GPL-3" 24# see: https://wiki.yoctoproject.org/wiki/License_Audit
25
26# GPL variations
27SPDXLICENSEMAP[GPL-2] = "GPL-2.0"
28SPDXLICENSEMAP[GPLv2] = "GPL-2.0"
29SPDXLICENSEMAP[GPLv2.0] = "GPL-2.0"
30SPDXLICENSEMAP[GPL-3] = "GPL-3.0"
31SPDXLICENSEMAP[GPLv3] = "GPL-3.0"
32SPDXLICENSEMAP[GPLv3.0] = "GPL-3.0"
30 33
31#LGPL variations 34#LGPL variations
32SPDXLICENSEMAP[LGPL] = "LGPL-2" 35SPDXLICENSEMAP[LGPLv2] = "LGPL-2.0"
33SPDXLICENSEMAP[LGPLv2] = "LGPL-2"
34SPDXLICENSEMAP[LGPL2.1] = "LGPL-2.1" 36SPDXLICENSEMAP[LGPL2.1] = "LGPL-2.1"
35SPDXLICENSEMAP[LGPLv2.1] = "LGPL-2.1" 37SPDXLICENSEMAP[LGPLv2.1] = "LGPL-2.1"
36SPDXLICENSEMAP[LGPLv3] = "LGPL-3" 38SPDXLICENSEMAP[LGPLv3] = "LGPL-3.0"
37 39
38#MPL variations 40#MPL variations
39SPDXLICENSEMAP[MPL] = "MPL-1" 41SPDXLICENSEMAP[MPL-1] = "MPL-1.0"
40SPDXLICENSEMAP[MPLv1] = "MPL-1" 42SPDXLICENSEMAP[MPLv1] = "MPL-1.0"
41SPDXLICENSEMAP[MPLv1.1] = "MPL-1" 43SPDXLICENSEMAP[MPLv1.1] = "MPL-1.1"
42 44
43#MIT variations 45#MIT variations
44SPDXLICENSEMAP[MIT-X] = "MIT" 46SPDXLICENSEMAP[MIT-X] = "MIT"
47SPDXLICENSEMAP[MIT-style] = "MIT"
45 48
46#Openssl variations 49#Openssl variations
47SPDXLICENSEMAP[openssl] = "OpenSSL" 50SPDXLICENSEMAP[openssl] = "OpenSSL"
48 51
52#Python variations
53SPDXLICENSEMAP[PSF] = "Python-2.0"
54SPDXLICENSEMAP[PSFv2] = "Python-2.0"
55SPDXLICENSEMAP[Python-2] = "Python-2.0"
56
57#Apache variations
58SPDXLICENSEMAP[Apachev2] = "Apache-2.0"
59SPDXLICENSEMAP[Apache-2] = "Apache-2.0"
60
61#Artistic variations
62SPDXLICENSEMAP[Artisticv1] = "Artistic-1.0"
63SPDXLICENSEMAP[Artistic-1] = "Artistic-1.0"
64
65#Academic variations
66SPDXLICENSEMAP[AFL-2] = "AFL-2.0"
67SPDXLICENSEMAP[AFL-1] = "AFL-1.2"
68SPDXLICENSEMAP[AFLv2] = "AFL-2.0"
69SPDXLICENSEMAP[AFLv1] = "AFL-1.2"
70
49#Other variations 71#Other variations
50SPDXLICENSEMAP[AFL2.1] = "AFL-2" 72SPDXLICENSEMAP[EPLv1.0] = "EPL-1.0"
51SPDXLICENSEMAP[EPLv1.0] = "EPL-1" 73
74license_create_manifest() {
75 mkdir -p ${LICENSE_DIRECTORY}/${IMAGE_NAME}
76 # Get list of installed packages
77 list_installed_packages | grep -v "locale" |sort > ${LICENSE_DIRECTORY}/${IMAGE_NAME}/package.manifest
78 INSTALLED_PKGS=`cat ${LICENSE_DIRECTORY}/${IMAGE_NAME}/package.manifest`
79 # list of installed packages is broken for deb
80 if [ ${IMAGE_PKGTYPE} != "deb" ]; then
81
82 for pkg in ${INSTALLED_PKGS}; do
83 # not the best way to do this but licenses are not arch dependant iirc
84 files=`find ${TMPDIR}/pkgdata/*/runtime -name ${pkg}| head -1`
85 for filename in $files; do
86 pkged_pn="$(sed -n 's/^PN: //p' ${filename})"
87 pkged_lic="$(sed -n '/^LICENSE: /{ s/^LICENSE: //; s/[+|&()*]/ /g; s/ */ /g; p }' ${filename})"
88 # check to see if the package name exists in the manifest. if so, bail.
89 if ! grep -q "PACKAGE NAME: ${pkg}" ${filename}; then
90 # exclude local recipes
91 if [ ! ${pkged_pn} == "*locale*" ]; then
92 echo "PACKAGE NAME:" ${pkg} >> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
93 echo "RECIPE NAME:" ${pkged_pn} >> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
94 echo "LICENSE: " >> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
95 for lic in ${pkged_lic}; do
96 if [ -e "${LICENSE_DIRECTORY}/${pkged_pn}/generic_${lic}" ]; then
97 echo ${lic}|sed s'/generic_//'g >> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
98 else
99 echo "WARNING: The license listed, " ${lic} " was not in the licenses collected for " ${pkged_pn}>> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
100 fi
101 done
102 echo "" >> ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest
103 fi
104 fi
105 done
106 done
107 fi
108
109 # Two options here:
110 # - Just copy the manifest
111 # - Copy the manifest and the license directories
112 # This will make your image a bit larger, however
113 # if you are concerned about license compliance
114 # and delivery this should cover all your bases
115
116 if [ -n ${COPY_LIC_MANIFEST} ]; then
117 mkdir -p ${IMAGE_ROOTFS}/usr/share/common-licenses/
118 cp ${LICENSE_DIRECTORY}/${IMAGE_NAME}/license.manifest ${IMAGE_ROOTFS}/usr/share/common-licenses/license.manifest
119 if [ -n ${COPY_LIC_DIRS} ]; then
120 for pkg in ${INSTALLED_PKGS}; do
121 mkdir -p ${IMAGE_ROOTFS}/usr/share/common-licenses/${pkg}
122 for lic in `ls ${LICENSE_DIRECTORY}/${pkged_pn}`; do
123 # Really don't need to copy the generics as they're
124 # represented in the manifest and in the actual pkg licenses
125 # Doing so would make your image quite a bit larger
126 if [ ! ${lic} == "generic_*" ]; then
127 cp ${LICENSE_DIRECTORY}/${pkged_pn}/${lic} ${IMAGE_ROOTFS}/usr/share/common-licenses/${pkg}/${lic}
128 fi
129 done
130 done
131 fi
132 fi
133
134}
135
52 136
53python do_populate_lic() { 137python do_populate_lic() {
54 """ 138 """
@@ -59,6 +143,26 @@ python do_populate_lic() {
59 import shutil 143 import shutil
60 import oe.license 144 import oe.license
61 145
146 # All the license types for the package
147 license_types = d.getVar('LICENSE', True)
148 # All the license files for the package
149 lic_files = d.getVar('LIC_FILES_CHKSUM', True)
150 pn = d.getVar('PN', True)
151 # The base directory we wrangle licenses to
152 destdir = os.path.join(d.getVar('LICSSTATEDIR', True), pn)
153 # The license files are located in S/LIC_FILE_CHECKSUM.
154 srcdir = d.getVar('S', True)
155 # Directory we store the generic licenses as set in the distro configuration
156 generic_directory = d.getVar('COMMON_LICENSE_DIR', True)
157 license_source_dirs = []
158 license_source_dirs.append(generic_directory)
159 try:
160 additional_lic_dirs = d.getVar('LICENSE_DIR', True).split()
161 for lic_dir in additional_lic_dirs:
162 license_source_dirs.append(lic_dir)
163 except:
164 pass
165
62 class FindVisitor(oe.license.LicenseVisitor): 166 class FindVisitor(oe.license.LicenseVisitor):
63 def visit_Str(self, node): 167 def visit_Str(self, node):
64 # 168 #
@@ -70,54 +174,38 @@ python do_populate_lic() {
70 find_license(node.s.replace("+", "").replace("*", "")) 174 find_license(node.s.replace("+", "").replace("*", ""))
71 self.generic_visit(node) 175 self.generic_visit(node)
72 176
73 def copy_license(source, destination, file_name):
74 try:
75 bb.copyfile(os.path.join(source, file_name), os.path.join(destination, file_name))
76 except:
77 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, file_name, source))
78 pass
79
80 def link_license(source, destination, file_name):
81 try:
82 os.symlink(os.path.join(source, file_name), os.path.join(destination, "generic_" + file_name))
83 except:
84 bb.warn("%s: Could not symlink: %s at %s to %s at %s" % (pn, file_name, source, file_name, destination))
85 pass
86
87 def find_license(license_type): 177 def find_license(license_type):
88 try: 178 try:
89 bb.mkdirhier(gen_lic_dest) 179 bb.mkdirhier(gen_lic_dest)
90 except: 180 except:
91 pass 181 pass
92 182 spdx_generic = None
183 license_source = None
93 # If the generic does not exist we need to check to see if there is an SPDX mapping to it 184 # If the generic does not exist we need to check to see if there is an SPDX mapping to it
94 if not os.path.isfile(os.path.join(generic_directory, license_type)): 185 for lic_dir in license_source_dirs:
95 if d.getVarFlag('SPDXLICENSEMAP', license_type) != None: 186 if not os.path.isfile(os.path.join(lic_dir, license_type)):
96 # Great, there is an SPDXLICENSEMAP. We can copy! 187 if d.getVarFlag('SPDXLICENSEMAP', license_type) != None:
97 bb.note("We need to use a SPDXLICENSEMAP for %s" % (license_type)) 188 # Great, there is an SPDXLICENSEMAP. We can copy!
98 spdx_generic = d.getVarFlag('SPDXLICENSEMAP', license_type) 189 bb.debug(1, "We need to use a SPDXLICENSEMAP for %s" % (license_type))
99 copy_license(generic_directory, gen_lic_dest, spdx_generic) 190 spdx_generic = d.getVarFlag('SPDXLICENSEMAP', license_type)
100 link_license(gen_lic_dest, destdir, spdx_generic) 191 license_source = lic_dir
101 else: 192 break
102 # And here is where we warn people that their licenses are lousy 193 elif os.path.isfile(os.path.join(lic_dir, license_type)):
103 bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory)) 194 spdx_generic = license_type
104 bb.warn("%s: There is also no SPDXLICENSEMAP for this license type: %s at %s" % (pn, license_type, generic_directory)) 195 license_source = lic_dir
105 pass 196 break
106 elif os.path.isfile(os.path.join(generic_directory, license_type)): 197
107 copy_license(generic_directory, gen_lic_dest, license_type) 198 if spdx_generic and license_source:
108 link_license(gen_lic_dest, destdir, license_type) 199 # we really should copy to generic_ + spdx_generic, however, that ends up messing the manifest
109 200 # audit up. This should be fixed in emit_pkgdata (or, we actually got and fix all the recipes)
110 # All the license types for the package 201 ret = bb.copyfile(os.path.join(license_source, spdx_generic), os.path.join(os.path.join(d.getVar('LICSSTATEDIR', True), pn), "generic_" + license_type))
111 license_types = d.getVar('LICENSE', True) 202 # If the copy didn't occur, something horrible went wrong and we fail out
112 # All the license files for the package 203 if not ret:
113 lic_files = d.getVar('LIC_FILES_CHKSUM', True) 204 bb.warn("%s for %s could not be copied for some reason. It may not exist. WARN for now." % (spdx_generic, pn))
114 pn = d.getVar('PN', True) 205 else:
115 # The base directory we wrangle licenses to 206 # And here is where we warn people that their licenses are lousy
116 destdir = os.path.join(d.getVar('LICSSTATEDIR', True), pn) 207 bb.warn("%s: No generic license file exists for: %s in any provider" % (pn, license_type))
117 # The license files are located in S/LIC_FILE_CHECKSUM. 208 pass
118 srcdir = d.getVar('S', True)
119 # Directory we store the generic licenses as set in the distro configuration
120 generic_directory = d.getVar('COMMON_LICENSE_DIR', True)
121 209
122 try: 210 try:
123 bb.mkdirhier(destdir) 211 bb.mkdirhier(destdir)
@@ -139,11 +227,9 @@ python do_populate_lic() {
139 srclicfile = os.path.join(srcdir, path) 227 srclicfile = os.path.join(srcdir, path)
140 ret = bb.copyfile(srclicfile, os.path.join(destdir, os.path.basename(path))) 228 ret = bb.copyfile(srclicfile, os.path.join(destdir, os.path.basename(path)))
141 # If the copy didn't occur, something horrible went wrong and we fail out 229 # If the copy didn't occur, something horrible went wrong and we fail out
142 if ret is False or ret == 0: 230 if not ret:
143 bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile) 231 bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile)
144 232
145 gen_lic_dest = os.path.join(d.getVar('LICENSE_DIRECTORY', True), "common-licenses")
146
147 v = FindVisitor() 233 v = FindVisitor()
148 try: 234 try:
149 v.visit_string(license_types) 235 v.visit_string(license_types)
@@ -156,8 +242,9 @@ do_populate_lic[sstate-name] = "populate-lic"
156do_populate_lic[sstate-inputdirs] = "${LICSSTATEDIR}" 242do_populate_lic[sstate-inputdirs] = "${LICSSTATEDIR}"
157do_populate_lic[sstate-outputdirs] = "${LICENSE_DIRECTORY}/" 243do_populate_lic[sstate-outputdirs] = "${LICENSE_DIRECTORY}/"
158 244
245ROOTFS_POSTINSTALL_COMMAND += "license_create_manifest; "
246
159python do_populate_lic_setscene () { 247python do_populate_lic_setscene () {
160 sstate_setscene(d) 248 sstate_setscene(d)
161} 249}
162addtask do_populate_lic_setscene 250addtask do_populate_lic_setscene
163