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