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