sourceipk: fix race condition with compileconfigs/multi-kernel
[openembedded.git] / classes / srctree.bbclass
blob1457e5618d6f9e3145e3b6705e240684f5879a5b
1 # Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
2 # Released under the MIT license (see COPYING.MIT for the terms)
4 # srctree.bbclass enables operation inside of an existing source tree for a
5 # project, rather than using the fetch/unpack/patch idiom.
7 # By default, it expects that you're keeping the recipe(s) inside the
8 # aforementioned source tree, but you could override S to point at an external
9 # directory and place the recipes in a normal collection/overlay, if you so
10 # chose.
12 # It also provides some convenience python functions for assembling your
13 # do_clean, if you want to leverage things like 'git clean' to simplify the
14 # operation.
17 # Grab convenience methods & sane default for do_clean
18 inherit clean
20 # Build here
21 S = "${FILE_DIRNAME}"
22 SRC_URI = ""
24 def remove_tasks(deltasks, d):
25     for task in filter(lambda k: d.getVarFlag(k, "task"), d.keys()):
26         deps = d.getVarFlag(task, "deps")
27         for preptask in deltasks:
28             if preptask in deps:
29                 deps.remove(preptask)
30         d.setVarFlag(task, "deps", deps)
32 addtask configure after do_setscene
34 def merge_tasks(d):
35     """
36     Merges all of the operations that occur prior to do_populate_sysroot
37     into do_populate_sysroot.
39     This is necessary because of recipe variants (normal, native, cross,
40     sdk).  If a bitbake run happens to want to build more than one of
41     these variants in a single run, it's possible for them to step on one
42     another's toes, due to the shared ${S}.  Interleaved
43     configure/compile/install amongst variants will break things badly.
44     """
45     from itertools import chain
46     from bb import note
48     def __gather_taskdeps(task, seen):
49         for dep in d.getVarFlag(task, "deps"):
50             if not dep in seen:
51                 __gather_taskdeps(dep, seen)
52         if not task in seen:
53             seen.append(task)
55     def gather_taskdeps(task):
56         items = []
57         __gather_taskdeps(task, items)
58         return items
60     newtask = "do_populate_sysroot_post"
61     mergedtasks = gather_taskdeps(newtask)
62     mergedtasks.pop()
64     for task in (key for key in d.keys()
65                  if d.getVarFlag(key, "task") and
66                  not key in mergedtasks):
67         deps = d.getVarFlag(task, "deps")
68         for mergetask in mergedtasks:
69             if mergetask in (d.getVarFlag(task, "recrdeptask"),
70                              d.getVarFlag(task, "recdeptask"),
71                              d.getVarFlag(task, "deptask")):
72                 continue
74             if mergetask in deps:
75                 deps.remove(mergetask)
76                 #note("removing dep on %s from %s" % (mergetask, task))
78                 if not newtask in deps:
79                     #note("adding dep on %s to %s" % (newtask, task))
80                     deps.append(newtask)
81         d.setVarFlag(task, "deps", deps)
83     # Pull cross recipe task deps over
84     depends = []
85     deptask = []
86     for task in mergedtasks[:-1]:
87         depends.append(d.getVarFlag(task, "depends") or "")
88         deptask.append(d.getVarFlag(task, "deptask") or "")
90     d.setVarFlag("do_populate_sysroot_post", "depends", " ".join(depends))
91     d.setVarFlag("do_populate_sysroot_post", "deptask", " ".join(deptask))
93 python () {
94     remove_tasks(["do_patch", "do_unpack", "do_fetch"], d)
95     b = d.getVar("B", True)
96     if not b or b == d.getVar("S", True):
97         merge_tasks(d)
100 # Manually run do_install & all of its deps
101 python do_populate_sysroot_post () {
102     from os.path import exists
103     from bb.build import exec_func, make_stamp
104     from bb import note
106     stamp = d.getVar("STAMP", True)
108     def rec_exec_task(task, seen):
109         for dep in d.getVarFlag(task, "deps"):
110             if not dep in seen:
111                 rec_exec_task(dep, seen)
112         seen.add(task)
113         if not exists("%s.%s" % (stamp, task)):
114             note("%s: executing task %s" % (d.getVar("PF", True), task))
115             exec_func(task, d)
116             flags = d.getVarFlags(task)
117             if not flags.get('nostamp') and not flags.get('selfstamp'):
118                 make_stamp(task, d)
120     rec_exec_task("do_populate_sysroot", set())
122 addtask populate_sysroot_post after do_populate_sysroot
123 do_populate_sysroot_post[lockfiles] += "${S}/.lock"