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