license.bbclass 4.9 KB

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