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