[bitbake-devel] [PATCH 1/2] data_smart.py and friends: Track file inclusions for bitbake -e
Peter Seebach
peter.seebach at windriver.com
Mon Oct 8 18:50:50 UTC 2012
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.
Signed-off-by: Peter Seebach <peter.seebach at windriver.com>
---
lib/bb/cooker.py | 5 +++++
lib/bb/data_smart.py | 44 ++++++++++++++++++++++++++++++++++++++++++++
lib/bb/parse/__init__.py | 3 ++-
3 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 7ca1ffd..0c7c4e0 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -332,6 +332,11 @@ class BBCooker:
parselog.exception("Unable to read %s", fn)
raise
+ # Display history
+ with closing(StringIO()) as env:
+ self.configuration.data.history.emit(env)
+ logger.plain(env.getvalue())
+
# emit variables and shell functions
data.update_data(envdata)
with closing(StringIO()) as env:
diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
index ec3c04e..864f527 100644
--- a/lib/bb/data_smart.py
+++ b/lib/bb/data_smart.py
@@ -114,6 +114,48 @@ class ExpansionError(Exception):
def __str__(self):
return self.msg
+class IncludeHistory(object):
+ def __init__(self, parent = None, filename = None):
+ self.parent = parent
+ if parent:
+ self.top = parent.top
+ else:
+ self.top = self
+ self.filename = filename or '[TOP LEVEL]'
+ self.children = []
+ self.current = self
+
+ def include(self, filename):
+ newfile = IncludeHistory(self.current, filename)
+ self.current.children.append(newfile)
+ self.current = newfile
+ return self
+
+ def __enter__(self):
+ pass
+
+ def __exit__(self, a, b, c):
+ if self.current.parent:
+ self.current = self.current.parent
+ else:
+ bb.warn("Include log: Tried to finish '%s' at top level." % filename)
+ return False
+
+ def emit(self, o, level = 0):
+ """Emit an include history file, and its children."""
+ if self != self.top:
+ spaces = " " * level
+ o.write("# %s%s" % (spaces, self.filename))
+ if len(self.children) > 0:
+ o.write(" includes:")
+ o.write("\n")
+ level = level + 1
+ else:
+ o.write("#\n# INCLUDE HISTORY:\n#\n")
+ for child in self.children:
+ child.emit(o, level)
+
+
class DataSmart(MutableMapping):
def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ):
self.dict = {}
@@ -121,6 +163,7 @@ class DataSmart(MutableMapping):
# cookie monster tribute
self._special_values = special
self._seen_overrides = seen
+ self.history = IncludeHistory()
self.expand_cache = {}
@@ -414,6 +457,7 @@ class DataSmart(MutableMapping):
# we really want this to be a DataSmart...
data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
data.dict["_data"] = self.dict
+ data.history = copy.deepcopy(self.history)
return data
diff --git a/lib/bb/parse/__init__.py b/lib/bb/parse/__init__.py
index 7b9c47e..b24673b 100644
--- a/lib/bb/parse/__init__.py
+++ b/lib/bb/parse/__init__.py
@@ -88,7 +88,8 @@ def handle(fn, data, include = 0):
"""Call the handler that is appropriate for this file"""
for h in handlers:
if h['supports'](fn, data):
- return h['handle'](fn, data, include)
+ with data.history.include(fn):
+ return h['handle'](fn, data, include)
raise ParseError("not a BitBake file", fn)
def init(fn, data):
--
1.7.0.4
More information about the bitbake-devel
mailing list