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