# These directories will be staged in the sysroot
|
SYSROOT_DIRS = " \
|
${includedir} \
|
${libdir} \
|
${base_libdir} \
|
${nonarch_base_libdir} \
|
${datadir} \
|
/sysroot-only \
|
"
|
|
# These directories are also staged in the sysroot when they contain files that
|
# are usable on the build system
|
SYSROOT_DIRS_NATIVE = " \
|
${bindir} \
|
${sbindir} \
|
${base_bindir} \
|
${base_sbindir} \
|
${libexecdir} \
|
${sysconfdir} \
|
${localstatedir} \
|
"
|
SYSROOT_DIRS:append:class-native = " ${SYSROOT_DIRS_NATIVE}"
|
SYSROOT_DIRS:append:class-cross = " ${SYSROOT_DIRS_NATIVE}"
|
SYSROOT_DIRS:append:class-crosssdk = " ${SYSROOT_DIRS_NATIVE}"
|
|
# These directories will not be staged in the sysroot
|
SYSROOT_DIRS_BLACKLIST = " \
|
${mandir} \
|
${docdir} \
|
${infodir} \
|
${datadir}/X11/locale \
|
${datadir}/applications \
|
${datadir}/bash-completion \
|
${datadir}/fonts \
|
${datadir}/gtk-doc/html \
|
${datadir}/installed-tests \
|
${datadir}/locale \
|
${datadir}/pixmaps \
|
${datadir}/terminfo \
|
${libdir}/${BPN}/ptest \
|
"
|
|
sysroot_stage_dir() {
|
src="$1"
|
dest="$2"
|
# if the src doesn't exist don't do anything
|
if [ ! -d "$src" ]; then
|
return
|
fi
|
|
mkdir -p "$dest"
|
(
|
cd $src
|
find . -print0 | cpio --null -pdlu $dest
|
)
|
}
|
|
sysroot_stage_dirs() {
|
from="$1"
|
to="$2"
|
|
for dir in ${SYSROOT_DIRS}; do
|
sysroot_stage_dir "$from$dir" "$to$dir"
|
done
|
|
# Remove directories we do not care about
|
for dir in ${SYSROOT_DIRS_BLACKLIST}; do
|
rm -rf "$to$dir"
|
done
|
}
|
|
sysroot_stage_all() {
|
sysroot_stage_dirs ${D} ${SYSROOT_DESTDIR}
|
}
|
|
python sysroot_strip () {
|
inhibit_sysroot = d.getVar('INHIBIT_SYSROOT_STRIP')
|
if inhibit_sysroot and oe.types.boolean(inhibit_sysroot):
|
return
|
|
dstdir = d.getVar('SYSROOT_DESTDIR')
|
pn = d.getVar('PN')
|
libdir = d.getVar("libdir")
|
base_libdir = d.getVar("base_libdir")
|
qa_already_stripped = 'already-stripped' in (d.getVar('INSANE_SKIP:' + pn) or "").split()
|
strip_cmd = d.getVar("STRIP")
|
|
oe.package.strip_execs(pn, dstdir, strip_cmd, libdir, base_libdir, d,
|
qa_already_stripped=qa_already_stripped)
|
}
|
|
do_populate_sysroot[dirs] = "${SYSROOT_DESTDIR}"
|
|
addtask populate_sysroot after do_install
|
|
SYSROOT_PREPROCESS_FUNCS ?= ""
|
SYSROOT_DESTDIR = "${WORKDIR}/sysroot-destdir"
|
|
python do_populate_sysroot () {
|
# SYSROOT 'version' 2
|
bb.build.exec_func("sysroot_stage_all", d)
|
bb.build.exec_func("sysroot_strip", d)
|
for f in (d.getVar('SYSROOT_PREPROCESS_FUNCS') or '').split():
|
bb.build.exec_func(f, d)
|
pn = d.getVar("PN")
|
multiprov = d.getVar("MULTI_PROVIDER_WHITELIST").split()
|
provdir = d.expand("${SYSROOT_DESTDIR}${base_prefix}/sysroot-providers/")
|
bb.utils.mkdirhier(provdir)
|
for p in d.getVar("PROVIDES").split():
|
if p in multiprov:
|
continue
|
p = p.replace("/", "_")
|
with open(provdir + p, "w") as f:
|
f.write(pn)
|
}
|
|
do_populate_sysroot[vardeps] += "${SYSROOT_PREPROCESS_FUNCS}"
|
do_populate_sysroot[vardepsexclude] += "MULTI_PROVIDER_WHITELIST"
|
|
POPULATESYSROOTDEPS = ""
|
POPULATESYSROOTDEPS:class-target = "virtual/${MLPREFIX}${TARGET_PREFIX}binutils:do_populate_sysroot"
|
POPULATESYSROOTDEPS:class-nativesdk = "virtual/${TARGET_PREFIX}binutils-crosssdk:do_populate_sysroot"
|
do_populate_sysroot[depends] += "${POPULATESYSROOTDEPS}"
|
|
SSTATETASKS += "do_populate_sysroot"
|
do_populate_sysroot[cleandirs] = "${SYSROOT_DESTDIR}"
|
do_populate_sysroot[sstate-inputdirs] = "${SYSROOT_DESTDIR}"
|
do_populate_sysroot[sstate-outputdirs] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
|
do_populate_sysroot[sstate-fixmedir] = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/${PN}"
|
|
python do_populate_sysroot_setscene () {
|
sstate_setscene(d)
|
}
|
addtask do_populate_sysroot_setscene
|
|
def staging_copyfile(c, target, dest, postinsts, seendirs):
|
import errno
|
|
destdir = os.path.dirname(dest)
|
if destdir not in seendirs:
|
bb.utils.mkdirhier(destdir)
|
seendirs.add(destdir)
|
if "/usr/bin/postinst-" in c:
|
postinsts.append(dest)
|
if os.path.islink(c):
|
linkto = os.readlink(c)
|
if os.path.lexists(dest):
|
if not os.path.islink(dest):
|
raise OSError(errno.EEXIST, "Link %s already exists as a file" % dest, dest)
|
if os.readlink(dest) == linkto:
|
return dest
|
raise OSError(errno.EEXIST, "Link %s already exists to a different location? (%s vs %s)" % (dest, os.readlink(dest), linkto), dest)
|
os.symlink(linkto, dest)
|
#bb.warn(c)
|
else:
|
try:
|
os.link(c, dest)
|
except OSError as err:
|
if err.errno == errno.EXDEV:
|
bb.utils.copyfile(c, dest)
|
else:
|
raise
|
return dest
|
|
def staging_copydir(c, target, dest, seendirs):
|
if dest not in seendirs:
|
bb.utils.mkdirhier(dest)
|
seendirs.add(dest)
|
|
def staging_processfixme(fixme, target, recipesysroot, recipesysrootnative, d):
|
import subprocess
|
|
if not fixme:
|
return
|
cmd = "sed -e 's:^[^/]*/:%s/:g' %s | xargs sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (target, " ".join(fixme), recipesysroot, recipesysrootnative)
|
for fixmevar in ['PSEUDO_SYSROOT', 'HOSTTOOLS_DIR', 'PKGDATA_DIR', 'PSEUDO_LOCALSTATEDIR', 'LOGFIFO']:
|
fixme_path = d.getVar(fixmevar)
|
cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
|
bb.debug(2, cmd)
|
subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
|
|
|
def staging_populate_sysroot_dir(targetsysroot, nativesysroot, native, d):
|
import glob
|
import subprocess
|
import errno
|
|
fixme = []
|
postinsts = []
|
seendirs = set()
|
stagingdir = d.getVar("STAGING_DIR")
|
if native:
|
pkgarchs = ['${BUILD_ARCH}', '${BUILD_ARCH}_*']
|
targetdir = nativesysroot
|
else:
|
pkgarchs = ['${MACHINE_ARCH}']
|
pkgarchs = pkgarchs + list(reversed(d.getVar("PACKAGE_EXTRA_ARCHS").split()))
|
pkgarchs.append('allarch')
|
targetdir = targetsysroot
|
|
bb.utils.mkdirhier(targetdir)
|
for pkgarch in pkgarchs:
|
for manifest in glob.glob(d.expand("${SSTATE_MANIFESTS}/manifest-%s-*.populate_sysroot" % pkgarch)):
|
if manifest.endswith("-initial.populate_sysroot"):
|
# skip libgcc-initial due to file overlap
|
continue
|
if not native and (manifest.endswith("-native.populate_sysroot") or "nativesdk-" in manifest):
|
continue
|
if native and not (manifest.endswith("-native.populate_sysroot") or manifest.endswith("-cross.populate_sysroot") or "-cross-" in manifest):
|
continue
|
tmanifest = targetdir + "/" + os.path.basename(manifest)
|
if os.path.exists(tmanifest):
|
continue
|
try:
|
os.link(manifest, tmanifest)
|
except OSError as err:
|
if err.errno == errno.EXDEV:
|
bb.utils.copyfile(manifest, tmanifest)
|
else:
|
raise
|
with open(manifest, "r") as f:
|
for l in f:
|
l = l.strip()
|
if l.endswith("/fixmepath"):
|
fixme.append(l)
|
continue
|
if l.endswith("/fixmepath.cmd"):
|
continue
|
dest = l.replace(stagingdir, "")
|
dest = targetdir + "/" + "/".join(dest.split("/")[3:])
|
if l.endswith("/"):
|
staging_copydir(l, targetdir, dest, seendirs)
|
continue
|
try:
|
staging_copyfile(l, targetdir, dest, postinsts, seendirs)
|
except FileExistsError:
|
continue
|
|
staging_processfixme(fixme, targetdir, targetsysroot, nativesysroot, d)
|
for p in postinsts:
|
subprocess.check_output(p, shell=True, stderr=subprocess.STDOUT)
|
|
#
|
# Manifests here are complicated. The main sysroot area has the unpacked sstate
|
# which us unrelocated and tracked by the main sstate manifests. Each recipe
|
# specific sysroot has manifests for each dependency that is installed there.
|
# The task hash is used to tell whether the data needs to be reinstalled. We
|
# use a symlink to point to the currently installed hash. There is also a
|
# "complete" stamp file which is used to mark if installation completed. If
|
# something fails (e.g. a postinst), this won't get written and we would
|
# remove and reinstall the dependency. This also means partially installed
|
# dependencies should get cleaned up correctly.
|
#
|
|
python extend_recipe_sysroot() {
|
import copy
|
import subprocess
|
import errno
|
import collections
|
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")
|
#bb.warn(str(taskdepdata))
|
pn = d.getVar("PN")
|
stagingdir = d.getVar("STAGING_DIR")
|
sharedmanifests = d.getVar("COMPONENTS_DIR") + "/manifests"
|
recipesysroot = d.getVar("RECIPE_SYSROOT")
|
recipesysrootnative = d.getVar("RECIPE_SYSROOT_NATIVE")
|
|
# Detect bitbake -b usage
|
nodeps = d.getVar("BB_LIMITEDDEPS") or False
|
if nodeps:
|
lock = bb.utils.lockfile(recipesysroot + "/sysroot.lock")
|
staging_populate_sysroot_dir(recipesysroot, recipesysrootnative, True, d)
|
staging_populate_sysroot_dir(recipesysroot, recipesysrootnative, False, d)
|
bb.utils.unlockfile(lock)
|
return
|
|
start = None
|
configuredeps = []
|
owntaskdeps = []
|
for dep in taskdepdata:
|
data = taskdepdata[dep]
|
if data[1] == mytaskname and data[0] == pn:
|
start = dep
|
elif data[0] == pn:
|
owntaskdeps.append(data[1])
|
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")
|
sstatetasks.append("do_deploy")
|
|
def print_dep_tree(deptree):
|
data = ""
|
for dep in deptree:
|
deps = " " + "\n ".join(deptree[dep][3]) + "\n"
|
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])
|
return data
|
|
#bb.note("Full dep tree is:\n%s" % print_dep_tree(taskdepdata))
|
|
#bb.note(" start2 is %s" % str(start))
|
|
# 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)
|
|
#bb.note(" start3 is %s" % str(start))
|
|
# 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)
|
|
#bb.note("Computed dep tree is:\n%s" % print_dep_tree(setscenedeps))
|
#bb.note(" start is %s" % str(start))
|
|
# Direct dependencies should be present and can be depended upon
|
for dep in set(start):
|
if setscenedeps[dep][1] == "do_populate_sysroot":
|
if dep not in configuredeps:
|
configuredeps.append(dep)
|
bb.note("Direct dependencies are %s" % str(configuredeps))
|
#bb.note(" or %s" % str(start))
|
|
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)
|
if retval:
|
msgbuf.append("Skipping setscene dependency %s for installation into the sysroot" % datadep)
|
continue
|
done.append(datadep)
|
new.append(datadep)
|
if datadep not in configuredeps and setscenedeps[datadep][1] == "do_populate_sysroot":
|
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))
|
|
depdir = recipesysrootnative + "/installeddeps"
|
bb.utils.mkdirhier(depdir)
|
bb.utils.mkdirhier(sharedmanifests)
|
|
lock = bb.utils.lockfile(recipesysroot + "/sysroot.lock")
|
|
fixme = {}
|
seendirs = set()
|
postinsts = []
|
multilibs = {}
|
manifests = {}
|
# All files that we're going to be installing, to find conflicts.
|
fileset = {}
|
|
for f in os.listdir(depdir):
|
if not f.endswith(".complete"):
|
continue
|
f = depdir + "/" + f
|
if os.path.islink(f) and not os.path.exists(f):
|
bb.note("%s no longer exists, removing from sysroot" % f)
|
lnk = os.readlink(f.replace(".complete", ""))
|
sstate_clean_manifest(depdir + "/" + lnk, d, canrace=True, prefix=workdir)
|
os.unlink(f)
|
os.unlink(f.replace(".complete", ""))
|
|
installed = []
|
for dep in configuredeps:
|
c = setscenedeps[dep][0]
|
if mytaskname in ["do_sdk_depends", "do_populate_sdk_ext"] and c.endswith("-initial"):
|
bb.note("Skipping initial setscene dependency %s for installation into the sysroot" % c)
|
continue
|
installed.append(c)
|
|
# We want to remove anything which this task previously installed but is no longer a dependency
|
taskindex = depdir + "/" + "index." + mytaskname
|
if os.path.exists(taskindex):
|
potential = []
|
with open(taskindex, "r") as f:
|
for l in f:
|
l = l.strip()
|
if l not in installed:
|
fl = depdir + "/" + l
|
if not os.path.exists(fl):
|
# Was likely already uninstalled
|
continue
|
potential.append(l)
|
# We need to ensure no other task needs this dependency. We hold the sysroot
|
# lock so we ca search the indexes to check
|
if potential:
|
for i in glob.glob(depdir + "/index.*"):
|
if i.endswith("." + mytaskname):
|
continue
|
with open(i, "r") as f:
|
for l in f:
|
if l.startswith("TaskDeps:"):
|
prevtasks = l.split()[1:]
|
if mytaskname in prevtasks:
|
# We're a dependency of this task so we can clear items out the sysroot
|
break
|
l = l.strip()
|
if l in potential:
|
potential.remove(l)
|
for l in potential:
|
fl = depdir + "/" + l
|
bb.note("Task %s no longer depends on %s, removing from sysroot" % (mytaskname, l))
|
lnk = os.readlink(fl)
|
sstate_clean_manifest(depdir + "/" + lnk, d, canrace=True, prefix=workdir)
|
os.unlink(fl)
|
os.unlink(fl + ".complete")
|
|
msg_exists = []
|
msg_adding = []
|
|
# Handle all removals first since files may move between recipes
|
for dep in configuredeps:
|
c = setscenedeps[dep][0]
|
if c not in installed:
|
continue
|
taskhash = setscenedeps[dep][5]
|
taskmanifest = depdir + "/" + c + "." + taskhash
|
|
if os.path.exists(depdir + "/" + c):
|
lnk = os.readlink(depdir + "/" + c)
|
if lnk == c + "." + taskhash and os.path.exists(depdir + "/" + c + ".complete"):
|
continue
|
else:
|
bb.note("%s exists in sysroot, but is stale (%s vs. %s), removing." % (c, lnk, c + "." + taskhash))
|
sstate_clean_manifest(depdir + "/" + lnk, d, canrace=True, prefix=workdir)
|
os.unlink(depdir + "/" + c)
|
if os.path.lexists(depdir + "/" + c + ".complete"):
|
os.unlink(depdir + "/" + c + ".complete")
|
elif os.path.lexists(depdir + "/" + c):
|
os.unlink(depdir + "/" + c)
|
|
binfiles = {}
|
# Now handle installs
|
for dep in configuredeps:
|
c = setscenedeps[dep][0]
|
if c not in installed:
|
continue
|
taskhash = setscenedeps[dep][5]
|
taskmanifest = depdir + "/" + c + "." + taskhash
|
|
if os.path.exists(depdir + "/" + c):
|
lnk = os.readlink(depdir + "/" + c)
|
if lnk == c + "." + taskhash and os.path.exists(depdir + "/" + c + ".complete"):
|
msg_exists.append(c)
|
continue
|
|
msg_adding.append(c)
|
|
os.symlink(c + "." + taskhash, depdir + "/" + c)
|
|
manifest, d2 = oe.sstatesig.find_sstate_manifest(c, setscenedeps[dep][2], "populate_sysroot", d, multilibs)
|
if d2 is not d:
|
# If we don't do this, the recipe sysroot will be placed in the wrong WORKDIR for multilibs
|
# We need a consistent WORKDIR for the image
|
d2.setVar("WORKDIR", d.getVar("WORKDIR"))
|
destsysroot = d2.getVar("RECIPE_SYSROOT")
|
# We put allarch recipes into the default sysroot
|
if manifest and "allarch" in manifest:
|
destsysroot = d.getVar("RECIPE_SYSROOT")
|
|
native = False
|
if c.endswith("-native") or "-cross-" in c or "-crosssdk" in c:
|
native = True
|
|
if manifest:
|
newmanifest = collections.OrderedDict()
|
targetdir = destsysroot
|
if native:
|
targetdir = recipesysrootnative
|
if targetdir not in fixme:
|
fixme[targetdir] = []
|
fm = fixme[targetdir]
|
|
with open(manifest, "r") as f:
|
manifests[dep] = manifest
|
for l in f:
|
l = l.strip()
|
if l.endswith("/fixmepath"):
|
fm.append(l)
|
continue
|
if l.endswith("/fixmepath.cmd"):
|
continue
|
dest = l.replace(stagingdir, "")
|
dest = "/" + "/".join(dest.split("/")[3:])
|
newmanifest[l] = targetdir + dest
|
|
# Check if files have already been installed by another
|
# recipe and abort if they have, explaining what recipes are
|
# conflicting.
|
hashname = targetdir + dest
|
if not hashname.endswith("/"):
|
if hashname in fileset:
|
bb.fatal("The file %s is installed by both %s and %s, aborting" % (dest, c, fileset[hashname]))
|
else:
|
fileset[hashname] = c
|
|
# Having multiple identical manifests in each sysroot eats diskspace so
|
# create a shared pool of them and hardlink if we can.
|
# We create the manifest in advance so that if something fails during installation,
|
# or the build is interrupted, subsequent exeuction can cleanup.
|
sharedm = sharedmanifests + "/" + os.path.basename(taskmanifest)
|
if not os.path.exists(sharedm):
|
smlock = bb.utils.lockfile(sharedm + ".lock")
|
# Can race here. You'd think it just means we may not end up with all copies hardlinked to each other
|
# but python can lose file handles so we need to do this under a lock.
|
if not os.path.exists(sharedm):
|
with open(sharedm, 'w') as m:
|
for l in newmanifest:
|
dest = newmanifest[l]
|
m.write(dest.replace(workdir + "/", "") + "\n")
|
bb.utils.unlockfile(smlock)
|
try:
|
os.link(sharedm, taskmanifest)
|
except OSError as err:
|
if err.errno == errno.EXDEV:
|
bb.utils.copyfile(sharedm, taskmanifest)
|
else:
|
raise
|
# Finally actually install the files
|
for l in newmanifest:
|
dest = newmanifest[l]
|
if l.endswith("/"):
|
staging_copydir(l, targetdir, dest, seendirs)
|
continue
|
if "/bin/" in l or "/sbin/" in l:
|
# defer /*bin/* files until last in case they need libs
|
binfiles[l] = (targetdir, dest)
|
else:
|
staging_copyfile(l, targetdir, dest, postinsts, seendirs)
|
|
# Handle deferred binfiles
|
for l in binfiles:
|
(targetdir, dest) = binfiles[l]
|
staging_copyfile(l, targetdir, dest, postinsts, seendirs)
|
|
bb.note("Installed into sysroot: %s" % str(msg_adding))
|
bb.note("Skipping as already exists in sysroot: %s" % str(msg_exists))
|
|
for f in fixme:
|
staging_processfixme(fixme[f], f, recipesysroot, recipesysrootnative, d)
|
|
for p in postinsts:
|
subprocess.check_output(p, shell=True, stderr=subprocess.STDOUT)
|
|
for dep in manifests:
|
c = setscenedeps[dep][0]
|
os.symlink(manifests[dep], depdir + "/" + c + ".complete")
|
|
with open(taskindex, "w") as f:
|
f.write("TaskDeps: " + " ".join(owntaskdeps) + "\n")
|
for l in sorted(installed):
|
f.write(l + "\n")
|
|
bb.utils.unlockfile(lock)
|
}
|
extend_recipe_sysroot[vardepsexclude] += "MACHINE_ARCH PACKAGE_EXTRA_ARCHS SDK_ARCH BUILD_ARCH SDK_OS BB_TASKDEPDATA"
|
|
do_prepare_recipe_sysroot[deptask] = "do_populate_sysroot"
|
python do_prepare_recipe_sysroot () {
|
bb.build.exec_func("extend_recipe_sysroot", d)
|
}
|
addtask do_prepare_recipe_sysroot before do_configure after do_fetch
|
|
python staging_taskhandler() {
|
bbtasks = e.tasklist
|
for task in bbtasks:
|
deps = d.getVarFlag(task, "depends")
|
if task == "do_configure" or (deps and "populate_sysroot" in deps):
|
d.prependVarFlag(task, "prefuncs", "extend_recipe_sysroot ")
|
}
|
staging_taskhandler[eventmask] = "bb.event.RecipeTaskPreProcess"
|
addhandler staging_taskhandler
|