blob: de3a19815a35978356b632eb843b23ef8df522b4 [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001# These directories will be staged in the sysroot
2SYSROOT_DIRS = " \
3 ${includedir} \
4 ${libdir} \
5 ${base_libdir} \
6 ${nonarch_base_libdir} \
7 ${datadir} \
8"
9
10# These directories are also staged in the sysroot when they contain files that
11# are usable on the build system
12SYSROOT_DIRS_NATIVE = " \
13 ${bindir} \
14 ${sbindir} \
15 ${base_bindir} \
16 ${base_sbindir} \
17 ${libexecdir} \
18 ${sysconfdir} \
19 ${localstatedir} \
20"
21SYSROOT_DIRS_append_class-native = " ${SYSROOT_DIRS_NATIVE}"
22SYSROOT_DIRS_append_class-cross = " ${SYSROOT_DIRS_NATIVE}"
23SYSROOT_DIRS_append_class-crosssdk = " ${SYSROOT_DIRS_NATIVE}"
24
25# These directories will not be staged in the sysroot
26SYSROOT_DIRS_BLACKLIST = " \
27 ${mandir} \
28 ${docdir} \
29 ${infodir} \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060030 ${datadir}/applications \
31 ${datadir}/fonts \
Brad Bishopc342db32019-05-15 21:57:59 -040032 ${datadir}/gtk-doc/html \
33 ${datadir}/locale \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060034 ${datadir}/pixmaps \
Andrew Geissler82c905d2020-04-13 13:39:40 -050035 ${libdir}/${BPN}/ptest \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060036"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050037
38sysroot_stage_dir() {
39 src="$1"
40 dest="$2"
41 # if the src doesn't exist don't do anything
42 if [ ! -d "$src" ]; then
43 return
44 fi
45
46 mkdir -p "$dest"
47 (
48 cd $src
49 find . -print0 | cpio --null -pdlu $dest
50 )
51}
52
Patrick Williamsc124f4f2015-09-15 14:41:29 -050053sysroot_stage_dirs() {
54 from="$1"
55 to="$2"
56
Patrick Williamsc0f7c042017-02-23 20:41:17 -060057 for dir in ${SYSROOT_DIRS}; do
58 sysroot_stage_dir "$from$dir" "$to$dir"
59 done
60
61 # Remove directories we do not care about
62 for dir in ${SYSROOT_DIRS_BLACKLIST}; do
63 rm -rf "$to$dir"
64 done
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065}
66
67sysroot_stage_all() {
68 sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR}
69}
70
71python sysroot_strip () {
Brad Bishopd7bf8c12018-02-25 22:55:05 -050072 inhibit_sysroot = d.getVar('INHIBIT_SYSROOT_STRIP')
73 if inhibit_sysroot and oe.types.boolean(inhibit_sysroot):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080074 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075
Brad Bishopd7bf8c12018-02-25 22:55:05 -050076 dstdir = d.getVar('SYSROOT_DESTDIR')
Brad Bishop6e60e8b2018-02-01 10:27:11 -050077 pn = d.getVar('PN')
Andrew Geissler82c905d2020-04-13 13:39:40 -050078 libdir = d.getVar("libdir")
79 base_libdir = d.getVar("base_libdir")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050080 qa_already_stripped = 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split()
81 strip_cmd = d.getVar("STRIP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080083 oe.package.strip_execs(pn, dstdir, strip_cmd, libdir, base_libdir, d,
Brad Bishopd7bf8c12018-02-25 22:55:05 -050084 qa_already_stripped=qa_already_stripped)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085}
86
87do_populate_sysroot[dirs] = "${SYSROOT_DESTDIR}"
88do_populate_sysroot[umask] = "022"
89
90addtask populate_sysroot after do_install
91
92SYSROOT_PREPROCESS_FUNCS ?= ""
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050093SYSROOT_DESTDIR = "${WORKDIR}/sysroot-destdir"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050094
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095python do_populate_sysroot () {
Andrew Geissler4b740dc2020-05-05 08:54:39 -050096 # SYSROOT 'version' 2
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 bb.build.exec_func("sysroot_stage_all", d)
98 bb.build.exec_func("sysroot_strip", d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050099 for f in (d.getVar('SYSROOT_PREPROCESS_FUNCS') or '').split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 bb.build.exec_func(f, d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500101 pn = d.getVar("PN")
102 multiprov = d.getVar("MULTI_PROVIDER_WHITELIST").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500103 provdir = d.expand("${SYSROOT_DESTDIR}${base_prefix}/sysroot-providers/")
104 bb.utils.mkdirhier(provdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105 for p in d.getVar("PROVIDES").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106 if p in multiprov:
107 continue
108 p = p.replace("/", "_")
109 with open(provdir + p, "w") as f:
110 f.write(pn)
111}
112
113do_populate_sysroot[vardeps] += "${SYSROOT_PREPROCESS_FUNCS}"
114do_populate_sysroot[vardepsexclude] += "MULTI_PROVIDER_WHITELIST"
115
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500116POPULATESYSROOTDEPS = ""
117POPULATESYSROOTDEPS_class-target = "virtual/${MLPREFIX}${TARGET_PREFIX}binutils:do_populate_sysroot"
118POPULATESYSROOTDEPS_class-nativesdk = "virtual/${TARGET_PREFIX}binutils-crosssdk:do_populate_sysroot"
119do_populate_sysroot[depends] += "${POPULATESYSROOTDEPS}"
120
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121SSTATETASKS += "do_populate_sysroot"
122do_populate_sysroot[cleandirs] = "${SYSROOT_DESTDIR}"
123do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500124do_populate_sysroot[sstate-outputdirs] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
125do_populate_sysroot[sstate-fixmedir] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500126
127python do_populate_sysroot_setscene () {
128 sstate_setscene(d)
129}
130addtask do_populate_sysroot_setscene
131
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500132def staging_copyfile(c, target, dest, postinsts, seendirs):
133 import errno
134
135 destdir = os.path.dirname(dest)
136 if destdir not in seendirs:
137 bb.utils.mkdirhier(destdir)
138 seendirs.add(destdir)
139 if "/usr/bin/postinst-" in c:
140 postinsts.append(dest)
141 if os.path.islink(c):
142 linkto = os.readlink(c)
143 if os.path.lexists(dest):
144 if not os.path.islink(dest):
145 raise OSError(errno.EEXIST, "Link %s already exists as a file" % dest, dest)
146 if os.readlink(dest) == linkto:
147 return dest
148 raise OSError(errno.EEXIST, "Link %s already exists to a different location? (%s vs %s)" % (dest, os.readlink(dest), linkto), dest)
149 os.symlink(linkto, dest)
150 #bb.warn(c)
151 else:
152 try:
153 os.link(c, dest)
154 except OSError as err:
155 if err.errno == errno.EXDEV:
156 bb.utils.copyfile(c, dest)
157 else:
158 raise
159 return dest
160
161def staging_copydir(c, target, dest, seendirs):
162 if dest not in seendirs:
163 bb.utils.mkdirhier(dest)
164 seendirs.add(dest)
165
166def staging_processfixme(fixme, target, recipesysroot, recipesysrootnative, d):
167 import subprocess
168
169 if not fixme:
170 return
171 cmd = "sed -e 's:^[^/]*/:%s/:g' %s | xargs sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (target, " ".join(fixme), recipesysroot, recipesysrootnative)
Brad Bishop15ae2502019-06-18 21:44:24 -0400172 for fixmevar in ['PSEUDO_SYSROOT', 'HOSTTOOLS_DIR', 'PKGDATA_DIR', 'PSEUDO_LOCALSTATEDIR', 'LOGFIFO']:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500173 fixme_path = d.getVar(fixmevar)
174 cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
175 bb.debug(2, cmd)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400176 subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500177
178
179def staging_populate_sysroot_dir(targetsysroot, nativesysroot, native, d):
180 import glob
181 import subprocess
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500182 import errno
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500183
184 fixme = []
185 postinsts = []
186 seendirs = set()
187 stagingdir = d.getVar("STAGING_DIR")
188 if native:
189 pkgarchs = ['${BUILD_ARCH}', '${BUILD_ARCH}_*']
190 targetdir = nativesysroot
191 else:
192 pkgarchs = ['${MACHINE_ARCH}']
193 pkgarchs = pkgarchs + list(reversed(d.getVar("PACKAGE_EXTRA_ARCHS").split()))
194 pkgarchs.append('allarch')
195 targetdir = targetsysroot
196
197 bb.utils.mkdirhier(targetdir)
198 for pkgarch in pkgarchs:
199 for manifest in glob.glob(d.expand("${SSTATE_MANIFESTS}/manifest-%s-*.populate_sysroot" % pkgarch)):
200 if manifest.endswith("-initial.populate_sysroot"):
Brad Bishop79641f22019-09-10 07:20:22 -0400201 # skip libgcc-initial due to file overlap
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500202 continue
Brad Bishop19323692019-04-05 15:28:33 -0400203 if not native and (manifest.endswith("-native.populate_sysroot") or "nativesdk-" in manifest):
204 continue
205 if native and not (manifest.endswith("-native.populate_sysroot") or manifest.endswith("-cross.populate_sysroot") or "-cross-" in manifest):
206 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500207 tmanifest = targetdir + "/" + os.path.basename(manifest)
208 if os.path.exists(tmanifest):
209 continue
210 try:
211 os.link(manifest, tmanifest)
212 except OSError as err:
213 if err.errno == errno.EXDEV:
214 bb.utils.copyfile(manifest, tmanifest)
215 else:
216 raise
217 with open(manifest, "r") as f:
218 for l in f:
219 l = l.strip()
220 if l.endswith("/fixmepath"):
221 fixme.append(l)
222 continue
223 if l.endswith("/fixmepath.cmd"):
224 continue
225 dest = l.replace(stagingdir, "")
226 dest = targetdir + "/" + "/".join(dest.split("/")[3:])
227 if l.endswith("/"):
228 staging_copydir(l, targetdir, dest, seendirs)
229 continue
230 try:
231 staging_copyfile(l, targetdir, dest, postinsts, seendirs)
232 except FileExistsError:
233 continue
234
235 staging_processfixme(fixme, targetdir, targetsysroot, nativesysroot, d)
236 for p in postinsts:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400237 subprocess.check_output(p, shell=True, stderr=subprocess.STDOUT)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500238
239#
240# Manifests here are complicated. The main sysroot area has the unpacked sstate
241# which us unrelocated and tracked by the main sstate manifests. Each recipe
242# specific sysroot has manifests for each dependency that is installed there.
243# The task hash is used to tell whether the data needs to be reinstalled. We
244# use a symlink to point to the currently installed hash. There is also a
245# "complete" stamp file which is used to mark if installation completed. If
246# something fails (e.g. a postinst), this won't get written and we would
247# remove and reinstall the dependency. This also means partially installed
248# dependencies should get cleaned up correctly.
249#
250
251python extend_recipe_sysroot() {
252 import copy
253 import subprocess
254 import errno
255 import collections
256 import glob
257
258 taskdepdata = d.getVar("BB_TASKDEPDATA", False)
259 mytaskname = d.getVar("BB_RUNTASK")
260 if mytaskname.endswith("_setscene"):
261 mytaskname = mytaskname.replace("_setscene", "")
262 workdir = d.getVar("WORKDIR")
263 #bb.warn(str(taskdepdata))
264 pn = d.getVar("PN")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500265 stagingdir = d.getVar("STAGING_DIR")
266 sharedmanifests = d.getVar("COMPONENTS_DIR") + "/manifests"
267 recipesysroot = d.getVar("RECIPE_SYSROOT")
268 recipesysrootnative = d.getVar("RECIPE_SYSROOT_NATIVE")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500269
270 # Detect bitbake -b usage
271 nodeps = d.getVar("BB_LIMITEDDEPS") or False
272 if nodeps:
273 lock = bb.utils.lockfile(recipesysroot + "/sysroot.lock")
274 staging_populate_sysroot_dir(recipesysroot, recipesysrootnative, True, d)
275 staging_populate_sysroot_dir(recipesysroot, recipesysrootnative, False, d)
276 bb.utils.unlockfile(lock)
277 return
278
279 start = None
280 configuredeps = []
Andrew Geissler82c905d2020-04-13 13:39:40 -0500281 owntaskdeps = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500282 for dep in taskdepdata:
283 data = taskdepdata[dep]
284 if data[1] == mytaskname and data[0] == pn:
285 start = dep
Andrew Geissler82c905d2020-04-13 13:39:40 -0500286 elif data[0] == pn:
287 owntaskdeps.append(data[1])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500288 if start is None:
289 bb.fatal("Couldn't find ourself in BB_TASKDEPDATA?")
290
291 # We need to figure out which sysroot files we need to expose to this task.
292 # This needs to match what would get restored from sstate, which is controlled
293 # ultimately by calls from bitbake to setscene_depvalid().
294 # That function expects a setscene dependency tree. We build a dependency tree
295 # condensed to inter-sstate task dependencies, similar to that used by setscene
296 # tasks. We can then call into setscene_depvalid() and decide
297 # which dependencies we can "see" and should expose in the recipe specific sysroot.
298 setscenedeps = copy.deepcopy(taskdepdata)
299
300 start = set([start])
301
302 sstatetasks = d.getVar("SSTATETASKS").split()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800303 # Add recipe specific tasks referenced by setscene_depvalid()
304 sstatetasks.append("do_stash_locale")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500305
306 def print_dep_tree(deptree):
307 data = ""
308 for dep in deptree:
309 deps = " " + "\n ".join(deptree[dep][3]) + "\n"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800310 data = data + "%s:\n %s\n %s\n%s %s\n %s\n" % (deptree[dep][0], deptree[dep][1], deptree[dep][2], deps, deptree[dep][4], deptree[dep][5])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500311 return data
312
313 #bb.note("Full dep tree is:\n%s" % print_dep_tree(taskdepdata))
314
315 #bb.note(" start2 is %s" % str(start))
316
317 # If start is an sstate task (like do_package) we need to add in its direct dependencies
318 # else the code below won't recurse into them.
319 for dep in set(start):
320 for dep2 in setscenedeps[dep][3]:
321 start.add(dep2)
322 start.remove(dep)
323
324 #bb.note(" start3 is %s" % str(start))
325
326 # Create collapsed do_populate_sysroot -> do_populate_sysroot tree
327 for dep in taskdepdata:
328 data = setscenedeps[dep]
329 if data[1] not in sstatetasks:
330 for dep2 in setscenedeps:
331 data2 = setscenedeps[dep2]
332 if dep in data2[3]:
333 data2[3].update(setscenedeps[dep][3])
334 data2[3].remove(dep)
335 if dep in start:
336 start.update(setscenedeps[dep][3])
337 start.remove(dep)
338 del setscenedeps[dep]
339
340 # Remove circular references
341 for dep in setscenedeps:
342 if dep in setscenedeps[dep][3]:
343 setscenedeps[dep][3].remove(dep)
344
345 #bb.note("Computed dep tree is:\n%s" % print_dep_tree(setscenedeps))
346 #bb.note(" start is %s" % str(start))
347
348 # Direct dependencies should be present and can be depended upon
349 for dep in set(start):
350 if setscenedeps[dep][1] == "do_populate_sysroot":
351 if dep not in configuredeps:
352 configuredeps.append(dep)
353 bb.note("Direct dependencies are %s" % str(configuredeps))
354 #bb.note(" or %s" % str(start))
355
356 msgbuf = []
357 # Call into setscene_depvalid for each sub-dependency and only copy sysroot files
358 # for ones that would be restored from sstate.
359 done = list(start)
360 next = list(start)
361 while next:
362 new = []
363 for dep in next:
364 data = setscenedeps[dep]
365 for datadep in data[3]:
366 if datadep in done:
367 continue
368 taskdeps = {}
369 taskdeps[dep] = setscenedeps[dep][:2]
370 taskdeps[datadep] = setscenedeps[datadep][:2]
371 retval = setscene_depvalid(datadep, taskdeps, [], d, msgbuf)
372 if retval:
373 msgbuf.append("Skipping setscene dependency %s for installation into the sysroot" % datadep)
374 continue
375 done.append(datadep)
376 new.append(datadep)
377 if datadep not in configuredeps and setscenedeps[datadep][1] == "do_populate_sysroot":
378 configuredeps.append(datadep)
379 msgbuf.append("Adding dependency on %s" % setscenedeps[datadep][0])
380 else:
381 msgbuf.append("Following dependency on %s" % setscenedeps[datadep][0])
382 next = new
383
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500384 # This logging is too verbose for day to day use sadly
385 #bb.debug(2, "\n".join(msgbuf))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500386
387 depdir = recipesysrootnative + "/installeddeps"
388 bb.utils.mkdirhier(depdir)
389 bb.utils.mkdirhier(sharedmanifests)
390
391 lock = bb.utils.lockfile(recipesysroot + "/sysroot.lock")
392
393 fixme = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500394 seendirs = set()
395 postinsts = []
396 multilibs = {}
397 manifests = {}
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500398 # All files that we're going to be installing, to find conflicts.
399 fileset = {}
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500400
401 for f in os.listdir(depdir):
402 if not f.endswith(".complete"):
403 continue
404 f = depdir + "/" + f
405 if os.path.islink(f) and not os.path.exists(f):
406 bb.note("%s no longer exists, removing from sysroot" % f)
407 lnk = os.readlink(f.replace(".complete", ""))
408 sstate_clean_manifest(depdir + "/" + lnk, d, workdir)
409 os.unlink(f)
410 os.unlink(f.replace(".complete", ""))
411
412 installed = []
413 for dep in configuredeps:
414 c = setscenedeps[dep][0]
415 if mytaskname in ["do_sdk_depends", "do_populate_sdk_ext"] and c.endswith("-initial"):
416 bb.note("Skipping initial setscene dependency %s for installation into the sysroot" % c)
417 continue
418 installed.append(c)
419
420 # We want to remove anything which this task previously installed but is no longer a dependency
421 taskindex = depdir + "/" + "index." + mytaskname
422 if os.path.exists(taskindex):
423 potential = []
424 with open(taskindex, "r") as f:
425 for l in f:
426 l = l.strip()
427 if l not in installed:
428 fl = depdir + "/" + l
429 if not os.path.exists(fl):
430 # Was likely already uninstalled
431 continue
432 potential.append(l)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500433 # We need to ensure no other task needs this dependency. We hold the sysroot
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500434 # lock so we ca search the indexes to check
435 if potential:
436 for i in glob.glob(depdir + "/index.*"):
437 if i.endswith("." + mytaskname):
438 continue
439 with open(i, "r") as f:
440 for l in f:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500441 if l.startswith("TaskDeps:"):
442 prevtasks = l.split()[1:]
443 if mytaskname in prevtasks:
444 # We're a dependency of this task so we can clear items out the sysroot
445 break
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500446 l = l.strip()
447 if l in potential:
448 potential.remove(l)
449 for l in potential:
450 fl = depdir + "/" + l
451 bb.note("Task %s no longer depends on %s, removing from sysroot" % (mytaskname, l))
452 lnk = os.readlink(fl)
453 sstate_clean_manifest(depdir + "/" + lnk, d, workdir)
454 os.unlink(fl)
455 os.unlink(fl + ".complete")
456
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500457 msg_exists = []
458 msg_adding = []
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800459
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500460 # Handle all removals first since files may move between recipes
461 for dep in configuredeps:
462 c = setscenedeps[dep][0]
463 if c not in installed:
464 continue
465 taskhash = setscenedeps[dep][5]
466 taskmanifest = depdir + "/" + c + "." + taskhash
467
468 if os.path.exists(depdir + "/" + c):
469 lnk = os.readlink(depdir + "/" + c)
470 if lnk == c + "." + taskhash and os.path.exists(depdir + "/" + c + ".complete"):
471 continue
472 else:
473 bb.note("%s exists in sysroot, but is stale (%s vs. %s), removing." % (c, lnk, c + "." + taskhash))
474 sstate_clean_manifest(depdir + "/" + lnk, d, workdir)
475 os.unlink(depdir + "/" + c)
476 if os.path.lexists(depdir + "/" + c + ".complete"):
477 os.unlink(depdir + "/" + c + ".complete")
478 elif os.path.lexists(depdir + "/" + c):
479 os.unlink(depdir + "/" + c)
480
Andrew Geissler82c905d2020-04-13 13:39:40 -0500481 binfiles = {}
Brad Bishop1d80a2e2019-11-15 16:35:03 -0500482 # Now handle installs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500483 for dep in configuredeps:
484 c = setscenedeps[dep][0]
485 if c not in installed:
486 continue
487 taskhash = setscenedeps[dep][5]
488 taskmanifest = depdir + "/" + c + "." + taskhash
489
490 if os.path.exists(depdir + "/" + c):
491 lnk = os.readlink(depdir + "/" + c)
492 if lnk == c + "." + taskhash and os.path.exists(depdir + "/" + c + ".complete"):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500493 msg_exists.append(c)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500494 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500495
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500496 msg_adding.append(c)
497
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500498 os.symlink(c + "." + taskhash, depdir + "/" + c)
499
Brad Bishop316dfdd2018-06-25 12:45:53 -0400500 manifest, d2 = oe.sstatesig.find_sstate_manifest(c, setscenedeps[dep][2], "populate_sysroot", d, multilibs)
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700501 if d2 is not d:
502 # If we don't do this, the recipe sysroot will be placed in the wrong WORKDIR for multilibs
503 # We need a consistent WORKDIR for the image
504 d2.setVar("WORKDIR", d.getVar("WORKDIR"))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400505 destsysroot = d2.getVar("RECIPE_SYSROOT")
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700506 # We put allarch recipes into the default sysroot
507 if manifest and "allarch" in manifest:
508 destsysroot = d.getVar("RECIPE_SYSROOT")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500509
510 native = False
Brad Bishop316dfdd2018-06-25 12:45:53 -0400511 if c.endswith("-native") or "-cross-" in c or "-crosssdk" in c:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500512 native = True
Brad Bishop316dfdd2018-06-25 12:45:53 -0400513
514 if manifest:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500515 newmanifest = collections.OrderedDict()
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700516 targetdir = destsysroot
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500517 if native:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500518 targetdir = recipesysrootnative
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700519 if targetdir not in fixme:
520 fixme[targetdir] = []
521 fm = fixme[targetdir]
522
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500523 with open(manifest, "r") as f:
524 manifests[dep] = manifest
525 for l in f:
526 l = l.strip()
527 if l.endswith("/fixmepath"):
528 fm.append(l)
529 continue
530 if l.endswith("/fixmepath.cmd"):
531 continue
532 dest = l.replace(stagingdir, "")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500533 dest = "/" + "/".join(dest.split("/")[3:])
534 newmanifest[l] = targetdir + dest
535
536 # Check if files have already been installed by another
537 # recipe and abort if they have, explaining what recipes are
538 # conflicting.
539 hashname = targetdir + dest
540 if not hashname.endswith("/"):
541 if hashname in fileset:
542 bb.fatal("The file %s is installed by both %s and %s, aborting" % (dest, c, fileset[hashname]))
543 else:
544 fileset[hashname] = c
545
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500546 # Having multiple identical manifests in each sysroot eats diskspace so
547 # create a shared pool of them and hardlink if we can.
548 # We create the manifest in advance so that if something fails during installation,
549 # or the build is interrupted, subsequent exeuction can cleanup.
550 sharedm = sharedmanifests + "/" + os.path.basename(taskmanifest)
551 if not os.path.exists(sharedm):
552 smlock = bb.utils.lockfile(sharedm + ".lock")
553 # Can race here. You'd think it just means we may not end up with all copies hardlinked to each other
554 # but python can lose file handles so we need to do this under a lock.
555 if not os.path.exists(sharedm):
556 with open(sharedm, 'w') as m:
557 for l in newmanifest:
558 dest = newmanifest[l]
559 m.write(dest.replace(workdir + "/", "") + "\n")
560 bb.utils.unlockfile(smlock)
561 try:
562 os.link(sharedm, taskmanifest)
563 except OSError as err:
564 if err.errno == errno.EXDEV:
565 bb.utils.copyfile(sharedm, taskmanifest)
566 else:
567 raise
568 # Finally actually install the files
569 for l in newmanifest:
570 dest = newmanifest[l]
571 if l.endswith("/"):
572 staging_copydir(l, targetdir, dest, seendirs)
573 continue
Andrew Geissler82c905d2020-04-13 13:39:40 -0500574 if "/bin/" in l or "/sbin/" in l:
575 # defer /*bin/* files until last in case they need libs
576 binfiles[l] = (targetdir, dest)
577 else:
578 staging_copyfile(l, targetdir, dest, postinsts, seendirs)
579
580 # Handle deferred binfiles
581 for l in binfiles:
582 (targetdir, dest) = binfiles[l]
583 staging_copyfile(l, targetdir, dest, postinsts, seendirs)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500584
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500585 bb.note("Installed into sysroot: %s" % str(msg_adding))
586 bb.note("Skipping as already exists in sysroot: %s" % str(msg_exists))
587
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500588 for f in fixme:
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700589 staging_processfixme(fixme[f], f, recipesysroot, recipesysrootnative, d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500590
591 for p in postinsts:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400592 subprocess.check_output(p, shell=True, stderr=subprocess.STDOUT)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500593
594 for dep in manifests:
595 c = setscenedeps[dep][0]
596 os.symlink(manifests[dep], depdir + "/" + c + ".complete")
597
598 with open(taskindex, "w") as f:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500599 f.write("TaskDeps: " + " ".join(owntaskdeps) + "\n")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500600 for l in sorted(installed):
601 f.write(l + "\n")
602
603 bb.utils.unlockfile(lock)
604}
605extend_recipe_sysroot[vardepsexclude] += "MACHINE_ARCH PACKAGE_EXTRA_ARCHS SDK_ARCH BUILD_ARCH SDK_OS BB_TASKDEPDATA"
606
Brad Bishop19323692019-04-05 15:28:33 -0400607do_prepare_recipe_sysroot[deptask] = "do_populate_sysroot"
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500608python do_prepare_recipe_sysroot () {
609 bb.build.exec_func("extend_recipe_sysroot", d)
610}
611addtask do_prepare_recipe_sysroot before do_configure after do_fetch
612
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500613python staging_taskhandler() {
614 bbtasks = e.tasklist
615 for task in bbtasks:
616 deps = d.getVarFlag(task, "depends")
617 if deps and "populate_sysroot" in deps:
618 d.appendVarFlag(task, "prefuncs", " extend_recipe_sysroot")
619}
620staging_taskhandler[eventmask] = "bb.event.RecipeTaskPreProcess"
621addhandler staging_taskhandler