package_pkgdata.bbclass 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. WORKDIR_PKGDATA = "${WORKDIR}/pkgdata-sysroot"
  2. def package_populate_pkgdata_dir(pkgdatadir, d):
  3. import glob
  4. postinsts = []
  5. seendirs = set()
  6. stagingdir = d.getVar("PKGDATA_DIR")
  7. pkgarchs = ['${MACHINE_ARCH}']
  8. pkgarchs = pkgarchs + list(reversed(d.getVar("PACKAGE_EXTRA_ARCHS").split()))
  9. pkgarchs.append('allarch')
  10. bb.utils.mkdirhier(pkgdatadir)
  11. for pkgarch in pkgarchs:
  12. for manifest in glob.glob(d.expand("${SSTATE_MANIFESTS}/manifest-%s-*.packagedata" % pkgarch)):
  13. with open(manifest, "r") as f:
  14. for l in f:
  15. l = l.strip()
  16. dest = l.replace(stagingdir, "")
  17. if l.endswith("/"):
  18. staging_copydir(l, pkgdatadir, dest, seendirs)
  19. continue
  20. try:
  21. staging_copyfile(l, pkgdatadir, dest, postinsts, seendirs)
  22. except FileExistsError:
  23. continue
  24. python package_prepare_pkgdata() {
  25. import copy
  26. import glob
  27. taskdepdata = d.getVar("BB_TASKDEPDATA", False)
  28. mytaskname = d.getVar("BB_RUNTASK")
  29. if mytaskname.endswith("_setscene"):
  30. mytaskname = mytaskname.replace("_setscene", "")
  31. workdir = d.getVar("WORKDIR")
  32. pn = d.getVar("PN")
  33. stagingdir = d.getVar("PKGDATA_DIR")
  34. pkgdatadir = d.getVar("WORKDIR_PKGDATA")
  35. # Detect bitbake -b usage
  36. nodeps = d.getVar("BB_LIMITEDDEPS") or False
  37. if nodeps:
  38. staging_package_populate_pkgdata_dir(pkgdatadir, d)
  39. return
  40. start = None
  41. configuredeps = []
  42. for dep in taskdepdata:
  43. data = taskdepdata[dep]
  44. if data[1] == mytaskname and data[0] == pn:
  45. start = dep
  46. break
  47. if start is None:
  48. bb.fatal("Couldn't find ourself in BB_TASKDEPDATA?")
  49. # We need to figure out which sysroot files we need to expose to this task.
  50. # This needs to match what would get restored from sstate, which is controlled
  51. # ultimately by calls from bitbake to setscene_depvalid().
  52. # That function expects a setscene dependency tree. We build a dependency tree
  53. # condensed to inter-sstate task dependencies, similar to that used by setscene
  54. # tasks. We can then call into setscene_depvalid() and decide
  55. # which dependencies we can "see" and should expose in the recipe specific sysroot.
  56. setscenedeps = copy.deepcopy(taskdepdata)
  57. start = set([start])
  58. sstatetasks = d.getVar("SSTATETASKS").split()
  59. # Add recipe specific tasks referenced by setscene_depvalid()
  60. sstatetasks.append("do_stash_locale")
  61. # If start is an sstate task (like do_package) we need to add in its direct dependencies
  62. # else the code below won't recurse into them.
  63. for dep in set(start):
  64. for dep2 in setscenedeps[dep][3]:
  65. start.add(dep2)
  66. start.remove(dep)
  67. # Create collapsed do_populate_sysroot -> do_populate_sysroot tree
  68. for dep in taskdepdata:
  69. data = setscenedeps[dep]
  70. if data[1] not in sstatetasks:
  71. for dep2 in setscenedeps:
  72. data2 = setscenedeps[dep2]
  73. if dep in data2[3]:
  74. data2[3].update(setscenedeps[dep][3])
  75. data2[3].remove(dep)
  76. if dep in start:
  77. start.update(setscenedeps[dep][3])
  78. start.remove(dep)
  79. del setscenedeps[dep]
  80. # Remove circular references
  81. for dep in setscenedeps:
  82. if dep in setscenedeps[dep][3]:
  83. setscenedeps[dep][3].remove(dep)
  84. # Direct dependencies should be present and can be depended upon
  85. for dep in set(start):
  86. if setscenedeps[dep][1] == "do_packagedata":
  87. if dep not in configuredeps:
  88. configuredeps.append(dep)
  89. msgbuf = []
  90. # Call into setscene_depvalid for each sub-dependency and only copy sysroot files
  91. # for ones that would be restored from sstate.
  92. done = list(start)
  93. next = list(start)
  94. while next:
  95. new = []
  96. for dep in next:
  97. data = setscenedeps[dep]
  98. for datadep in data[3]:
  99. if datadep in done:
  100. continue
  101. taskdeps = {}
  102. taskdeps[dep] = setscenedeps[dep][:2]
  103. taskdeps[datadep] = setscenedeps[datadep][:2]
  104. retval = setscene_depvalid(datadep, taskdeps, [], d, msgbuf)
  105. done.append(datadep)
  106. new.append(datadep)
  107. if retval:
  108. msgbuf.append("Skipping setscene dependency %s" % datadep)
  109. continue
  110. if datadep not in configuredeps and setscenedeps[datadep][1] == "do_packagedata":
  111. configuredeps.append(datadep)
  112. msgbuf.append("Adding dependency on %s" % setscenedeps[datadep][0])
  113. else:
  114. msgbuf.append("Following dependency on %s" % setscenedeps[datadep][0])
  115. next = new
  116. # This logging is too verbose for day to day use sadly
  117. #bb.debug(2, "\n".join(msgbuf))
  118. seendirs = set()
  119. postinsts = []
  120. multilibs = {}
  121. manifests = {}
  122. msg_adding = []
  123. for dep in configuredeps:
  124. c = setscenedeps[dep][0]
  125. msg_adding.append(c)
  126. manifest, d2 = oe.sstatesig.find_sstate_manifest(c, setscenedeps[dep][2], "packagedata", d, multilibs)
  127. destsysroot = pkgdatadir
  128. if manifest:
  129. targetdir = destsysroot
  130. with open(manifest, "r") as f:
  131. manifests[dep] = manifest
  132. for l in f:
  133. l = l.strip()
  134. dest = targetdir + l.replace(stagingdir, "")
  135. if l.endswith("/"):
  136. staging_copydir(l, targetdir, dest, seendirs)
  137. continue
  138. staging_copyfile(l, targetdir, dest, postinsts, seendirs)
  139. bb.note("Installed into pkgdata-sysroot: %s" % str(msg_adding))
  140. }
  141. package_prepare_pkgdata[cleandirs] = "${WORKDIR_PKGDATA}"
  142. package_prepare_pkgdata[vardepsexclude] += "MACHINE_ARCH PACKAGE_EXTRA_ARCHS SDK_ARCH BUILD_ARCH SDK_OS BB_TASKDEPDATA"