diff options
Diffstat (limited to 'meta/classes')
-rw-r--r-- | meta/classes/license.bbclass | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/meta/classes/license.bbclass b/meta/classes/license.bbclass new file mode 100644 index 0000000000..ddedd577cc --- /dev/null +++ b/meta/classes/license.bbclass | |||
@@ -0,0 +1,101 @@ | |||
1 | # Populates LICENSE_DIRECTORY as set in poky.conf with the license files as set by | ||
2 | # LIC_FILES_CHKSUM. | ||
3 | # TODO: | ||
4 | # - We should also enable the ability to put the generated license directory onto the | ||
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 | |||
11 | LICENSE_DIRECTORY ??= "${DEPLOY_DIR_IMAGE}/licenses" | ||
12 | |||
13 | addtask populate_lic after do_patch before do_package | ||
14 | do_populate_lic[nostamp] = "1" | ||
15 | python do_populate_lic() { | ||
16 | """ | ||
17 | Populate LICENSE_DIRECTORY with licenses. | ||
18 | """ | ||
19 | import os | ||
20 | import bb | ||
21 | import shutil | ||
22 | |||
23 | # All the license types for the package | ||
24 | license_types = bb.data.getVar('LICENSE', d, True) | ||
25 | # All the license files for the package | ||
26 | lic_files = bb.data.getVar('LIC_FILES_CHKSUM', d, True) | ||
27 | pn = bb.data.getVar('PN', d, True) | ||
28 | # The base directory we wrangle licenses to | ||
29 | destdir = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), pn) | ||
30 | # The license files are located in S/LIC_FILE_CHECKSUM. | ||
31 | srcdir = bb.data.getVar('S', d, True) | ||
32 | # Directory we store the generic licenses as set in poky.conf | ||
33 | generic_directory = bb.data.getVar('COMMON_LICENSE_DIR', d, True) | ||
34 | if not generic_directory: | ||
35 | raise bb.build.FuncFailed("COMMON_LICENSE_DIR is unset. Please set this in your distro config") | ||
36 | |||
37 | try: | ||
38 | # Let's try to clean up the packages license directory | ||
39 | shutil.rmtree(destdir) | ||
40 | except: | ||
41 | pass | ||
42 | |||
43 | try: | ||
44 | # Create the package license directory structure. | ||
45 | bb.mkdirhier(destdir) | ||
46 | except: | ||
47 | pass | ||
48 | |||
49 | if not lic_files: | ||
50 | # No recipe should have an invalid license file. This is checked else | ||
51 | # where, but let's be pedantic | ||
52 | bb.note(pn + ": Recipe file does not have license file information.") | ||
53 | return True | ||
54 | |||
55 | for url in lic_files.split(): | ||
56 | (type, host, path, user, pswd, parm) = bb.decodeurl(url) | ||
57 | # We want the license file to be copied into the destination | ||
58 | srclicfile = os.path.join(srcdir, path) | ||
59 | ret = bb.copyfile(srclicfile, os.path.join(destdir, os.path.basename(path))) | ||
60 | # If the copy didn't occur, something horrible went wrong and we fail out | ||
61 | if ret is False or ret == 0: | ||
62 | bb.warn("%s could not be copied for some reason. It may not exist. WARN for now." % srclicfile) | ||
63 | |||
64 | # This takes some explaining.... we now are going to go an try to symlink | ||
65 | # to a generic file. But, with the way LICENSE works, a package can have multiple | ||
66 | # licenses. Some of them are, for example, GPLv2+, which means it can use that version | ||
67 | # of GPLv2 specified in it's license, or a later version of GPLv2. For the purposes of | ||
68 | # what we're doing here, we really don't track license revisions (although we may want to) | ||
69 | # So, we strip out the + and link to a generic GPLv2 | ||
70 | # | ||
71 | # That said, there are some entries into LICENSE that either have no generic (bzip, zlib, ICS) | ||
72 | # or the LICENSE is messy (Apache 2.0 .... when they mean Apache-2.0). This should be corrected | ||
73 | # but it's outside of scope for this. | ||
74 | # | ||
75 | # Also, you get some clever license fields with logic in the field. | ||
76 | # I'm sure someone has written a logic parser for these fields, but if so, I don't know where it is. | ||
77 | # So what I do is just link to every license mentioned in the license field. | ||
78 | |||
79 | for license_type in license_types.replace('&', '').replace('+', '').replace('&', '').replace('(', '').replace(')', '').split(): | ||
80 | if os.path.isfile(os.path.join(generic_directory, license_type)): | ||
81 | gen_lic_dest = os.path.join(bb.data.getVar('LICENSE_DIRECTORY', d, True), "common-licenses") | ||
82 | try: | ||
83 | bb.mkdirhier(gen_lic_dest) | ||
84 | except: | ||
85 | pass | ||
86 | |||
87 | try: | ||
88 | bb.copyfile(os.path.join(generic_directory, license_type), os.path.join(gen_lic_dest, license_type)) | ||
89 | except: | ||
90 | bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory)) | ||
91 | pass | ||
92 | try: | ||
93 | os.symlink(os.path.join(gen_lic_dest, license_type), os.path.join(destdir, "generic_" + license_type)) | ||
94 | except: | ||
95 | bb.warn("%s: No generic license file exists for: %s at %s" % (pn, license_type, generic_directory)) | ||
96 | pass | ||
97 | else: | ||
98 | bb.warn("%s: Something went wrong with copying: %s to %s" % (pn, license_type, generic_directory)) | ||
99 | bb.warn("This could be either because we do not have a generic for this license or the LICENSE field is incorrect") | ||
100 | pass | ||
101 | } | ||