summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2013-01-18 11:45:22 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-01-18 12:35:19 +0000
commit4dd6d9139cb77f2b0ff7ab9482e853108efad5aa (patch)
treef7fa2af68009e261946b767f2b3d6fc5f0258c5e /bitbake
parent9753283a3fe417ba827e4cee153184b6a25699de (diff)
downloadpoky-4dd6d9139cb77f2b0ff7ab9482e853108efad5aa.tar.gz
bitbake: bitbake: data_smart.py and friends: Track file inclusions for bitbake -e
This code adds inclusion history to bitbake -e output, showing which files were included, in what order. This doesn't completely resolve timing questions, because it doesn't show you which lines of a file were processed before or after a given include, but it does let you figure out what the path was by which a particular file ended up in your build at all. How it works: data_smart acquires a .history member, which is an IncludeHistory; this represents the inclusion of a file and all its inclusions, recursively. It provides methods for including files, for finishing inclusion (done as an __exit__), and for dumping the whole tree. The parser is modified to run includes inside a with() to push and pop the include filename. RP Modifications: a) Split Include and Variable tracking b) Replace deepcopy usage with dedicated copy function c) Simplify some variable and usage (Bitbake rev: b2dda721262da8abb7dc32d019e18fbc32ed8860) Signed-off-by: Peter Seebach <peter.seebach@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/cooker.py5
-rw-r--r--bitbake/lib/bb/data_smart.py46
-rw-r--r--bitbake/lib/bb/parse/__init__.py3
3 files changed, 53 insertions, 1 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 1d38164f56..f06b71c42c 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -338,6 +338,11 @@ class BBCooker:
338 parselog.exception("Unable to read %s", fn) 338 parselog.exception("Unable to read %s", fn)
339 raise 339 raise
340 340
341 # Display history
342 with closing(StringIO()) as env:
343 self.configuration.data.inchistory.emit(env)
344 logger.plain(env.getvalue())
345
341 # emit variables and shell functions 346 # emit variables and shell functions
342 data.update_data(envdata) 347 data.update_data(envdata)
343 with closing(StringIO()) as env: 348 with closing(StringIO()) as env:
diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py
index d328400903..5fdfeee2c7 100644
--- a/bitbake/lib/bb/data_smart.py
+++ b/bitbake/lib/bb/data_smart.py
@@ -114,10 +114,55 @@ class ExpansionError(Exception):
114 def __str__(self): 114 def __str__(self):
115 return self.msg 115 return self.msg
116 116
117class IncludeHistory(object):
118 def __init__(self, parent = None, filename = '[TOP LEVEL]'):
119 self.parent = parent
120 self.filename = filename
121 self.children = []
122 self.current = self
123
124 def copy(self):
125 new = IncludeHistory(self.parent, self.filename)
126 for c in self.children:
127 new.children.append(c)
128 return new
129
130 def include(self, filename):
131 newfile = IncludeHistory(self.current, filename)
132 self.current.children.append(newfile)
133 self.current = newfile
134 return self
135
136 def __enter__(self):
137 pass
138
139 def __exit__(self, a, b, c):
140 if self.current.parent:
141 self.current = self.current.parent
142 else:
143 bb.warn("Include log: Tried to finish '%s' at top level." % filename)
144 return False
145
146 def emit(self, o, level = 0):
147 """Emit an include history file, and its children."""
148 if level:
149 spaces = " " * (level - 1)
150 o.write("# %s%s" % (spaces, self.filename))
151 if len(self.children) > 0:
152 o.write(" includes:")
153 else:
154 o.write("#\n# INCLUDE HISTORY:\n#")
155 level = level + 1
156 for child in self.children:
157 o.write("\n")
158 child.emit(o, level)
159
117class DataSmart(MutableMapping): 160class DataSmart(MutableMapping):
118 def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ): 161 def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ):
119 self.dict = {} 162 self.dict = {}
120 163
164 self.inchistory = IncludeHistory()
165
121 # cookie monster tribute 166 # cookie monster tribute
122 self._special_values = special 167 self._special_values = special
123 self._seen_overrides = seen 168 self._seen_overrides = seen
@@ -416,6 +461,7 @@ class DataSmart(MutableMapping):
416 # we really want this to be a DataSmart... 461 # we really want this to be a DataSmart...
417 data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy()) 462 data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
418 data.dict["_data"] = self.dict 463 data.dict["_data"] = self.dict
464 data.inchistory = self.inchistory.copy()
419 465
420 return data 466 return data
421 467
diff --git a/bitbake/lib/bb/parse/__init__.py b/bitbake/lib/bb/parse/__init__.py
index 4293d09c7a..3f93ad2e6a 100644
--- a/bitbake/lib/bb/parse/__init__.py
+++ b/bitbake/lib/bb/parse/__init__.py
@@ -87,7 +87,8 @@ def handle(fn, data, include = 0):
87 """Call the handler that is appropriate for this file""" 87 """Call the handler that is appropriate for this file"""
88 for h in handlers: 88 for h in handlers:
89 if h['supports'](fn, data): 89 if h['supports'](fn, data):
90 return h['handle'](fn, data, include) 90 with data.inchistory.include(fn):
91 return h['handle'](fn, data, include)
91 raise ParseError("not a BitBake file", fn) 92 raise ParseError("not a BitBake file", fn)
92 93
93def init(fn, data): 94def init(fn, data):