package_pkgdata.bbclass 6.1 KB

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