diff options
-rw-r--r-- | meta/classes/staging.bbclass | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/meta/classes/staging.bbclass b/meta/classes/staging.bbclass index bd798ba9bc..0cb46bfd24 100644 --- a/meta/classes/staging.bbclass +++ b/meta/classes/staging.bbclass @@ -245,17 +245,9 @@ python do_populate_sysroot_setscene () { } addtask do_populate_sysroot_setscene -def staging_copyfile(c, target, fixme, postinsts, stagingdir, seendirs): +def staging_copyfile(c, target, dest, postinsts, seendirs): import errno - if c.endswith("/fixmepath"): - fixme.append(c) - return None - if c.endswith("/fixmepath.cmd"): - return None - #bb.warn(c) - dest = c.replace(stagingdir, "") - dest = target + "/" + "/".join(dest.split("/")[3:]) destdir = os.path.dirname(dest) if destdir not in seendirs: bb.utils.mkdirhier(destdir) @@ -282,9 +274,7 @@ def staging_copyfile(c, target, fixme, postinsts, stagingdir, seendirs): raise return dest -def staging_copydir(c, target, stagingdir, seendirs): - dest = c.replace(stagingdir, "") - dest = target + "/" + "/".join(dest.split("/")[3:]) +def staging_copydir(c, target, dest, seendirs): if dest not in seendirs: bb.utils.mkdirhier(dest) seendirs.add(dest) @@ -338,11 +328,18 @@ def staging_populate_sysroot_dir(targetsysroot, nativesysroot, native, d): 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, stagingdir, seendirs) + staging_copydir(l, targetdir, dest, seendirs) continue try: - staging_copyfile(l, targetdir, fixme, postinsts, stagingdir, seendirs) + staging_copyfile(l, targetdir, dest, postinsts, seendirs) except FileExistsError: continue @@ -365,6 +362,8 @@ def staging_populate_sysroot_dir(targetsysroot, nativesysroot, native, d): python extend_recipe_sysroot() { import copy import subprocess + import errno + import collections taskdepdata = d.getVar("BB_TASKDEPDATA", False) mytaskname = d.getVar("BB_RUNTASK") @@ -574,43 +573,54 @@ python extend_recipe_sysroot() { if not os.path.exists(manifest): bb.warn("Manifest %s not found?" % manifest) else: - with open(manifest, "r") as f, open(taskmanifest, 'w') as m: + newmanifest = collections.OrderedDict() + if native: + fm = fixme['native'] + targetdir = recipesysrootnative + else: + fm = fixme[''] + targetdir = destsysroot + with open(manifest, "r") as f: manifests[dep] = manifest for l in f: l = l.strip() - if l.endswith("/"): - if native: - dest = staging_copydir(l, recipesysrootnative, stagingdir, seendirs) - else: - dest = staging_copydir(l, destsysroot, stagingdir, seendirs) + if l.endswith("/fixmepath"): + fm.append(l) + continue + if l.endswith("/fixmepath.cmd"): continue - if native: - dest = staging_copyfile(l, recipesysrootnative, fixme['native'], postinsts, stagingdir, seendirs) - else: - dest = staging_copyfile(l, destsysroot, fixme[''], postinsts, stagingdir, seendirs) - if dest: - m.write(dest.replace(workdir + "/", "") + "\n") + dest = l.replace(stagingdir, "") + dest = targetdir + "/" + "/".join(dest.split("/")[3:]) + newmanifest[l] = dest # Having multiple identical manifests in each sysroot eats diskspace so - # create a shared pool of them. + # 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. - try: - if not os.path.exists(sharedm): - os.rename(taskmanifest, sharedm) - except OSError: - pass + 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) - if os.path.exists(sharedm): - # If we're crossing mount points we'll not reach here. - if os.path.exists(taskmanifest): - if os.path.getsize(sharedm) != os.path.getsize(taskmanifest): - # Order of entries can differ, overall size shouldn't - raise Exception("Manifests %s and %s differ in size and shouldn't?" % (sharedm, taskmanifest)) - os.unlink(taskmanifest) + 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 + staging_copyfile(l, targetdir, dest, postinsts, seendirs) for f in fixme: if f == '': |