From 6bc341a516112626e301004808205731f4bc4c9e Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Tue, 14 Jan 2003 23:43:59 +0000 Subject: Add --debug-includes. (Anthony Roach) --- doc/man/scons.1 | 10 ++++++++++ src/CHANGES.txt | 2 ++ src/engine/SCons/Node/__init__.py | 14 ++++++++++++++ src/engine/SCons/Script/__init__.py | 13 +++++++++++-- src/engine/SCons/Util.py | 11 +++++++---- src/engine/SCons/UtilTests.py | 16 ++++++++++++++++ test/option--debug.py | 13 +++++++++++++ 7 files changed, 73 insertions(+), 6 deletions(-) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 12e09f3..da36229 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -397,6 +397,16 @@ executing build commands, the total time spent executing SConstruct and SConscript files, and the total time spent executing SCons itself. .TP +.RI --debug=includes +Print the include tree after each top-level target is built. +This is generally used to find out what files are included by the sources +of a given derived file: + +.ES +$ scons --debug=includes foo.o +.EE + +.TP -e, --environment-overrides Variables from the execution environment override construction variables from the SConscript files. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 621b865..2eeae30 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -85,6 +85,8 @@ RELEASE 0.10 - XXX - Added support for the MinGW tool chain. + - Added a --debug=inclues option. + RELEASE 0.09 - Thu, 5 Dec 2002 04:48:25 -0600 diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 14f99ed..ec33713 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -470,6 +470,20 @@ class Node: the command interpreter literally.""" return 1 + def render_include_tree(self): + """ + Return a text representation, suitable for displaying to the + user, of the include tree for the sources of this node. + """ + if self.has_builder() and self.env: + env = self.generate_build_env() + for s in self.sources: + def f(node, env=env, scanner=s.source_scanner, target=self): + return node.get_found_includes(env, scanner, target) + return SCons.Util.render_tree(s, f, 1) + else: + return None + def get_children(node, parent): return node.children() def ignore_cycle(node, stack): pass def do_nothing(node, parent): pass diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index a33e373..034bf73 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -120,6 +120,12 @@ class BuildTask(SCons.Taskmaster.Task): if print_dtree and self.top: print print SCons.Util.render_tree(self.targets[0], get_derived_children) + if print_includes and self.top: + t = self.targets[0] + tree = t.render_include_tree() + if tree: + print + print tree def failed(self): e = sys.exc_value @@ -191,6 +197,7 @@ keep_going_on_error = 0 print_tree = 0 print_dtree = 0 print_time = 0 +print_includes = 0 ignore_errors = 0 sconscript_time = 0 command_time = 0 @@ -353,7 +360,7 @@ def _SConstruct_exists(dirname=''): def _set_globals(options): global repositories, keep_going_on_error, print_tree, print_dtree - global print_time, ignore_errors + global print_time, ignore_errors, print_includes if options.repository: repositories.extend(options.repository) @@ -366,6 +373,8 @@ def _set_globals(options): print_dtree = 1 elif options.debug == "time": print_time = 1 + elif options.debug == "includes": + print_includes = 1 except AttributeError: pass ignore_errors = options.ignore_errors @@ -442,7 +451,7 @@ class OptParser(OptionParser): "python" + sys.version[0:3], "pdb.py") os.execvpe(args[0], args, os.environ) - elif value in ["tree", "dtree", "time"]: + elif value in ["tree", "dtree", "time", "includes"]: setattr(parser.values, 'debug', value) else: raise OptionValueError("Warning: %s is not a valid debug type" % value) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index c89e8e6..408c4af 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -464,14 +464,16 @@ def scons_subst(strSubst, globals, locals, remove=None): # strip out redundant white-space return string.strip(_space_sep.sub(' ', strSubst)) -def render_tree(root, child_func, margin=[0], visited={}): +def render_tree(root, child_func, prune=0, margin=[0], visited={}): """ Render a tree of nodes into an ASCII tree view. root - the root node of the tree child_func - the function called to get the children of a node + prune - don't visit the same node twice margin - the format of the left margin to use for children of root. 1 results in a pipe, and 0 results in no pipe. - visited - a dictionart of visited nodes in the current branch + visited - a dictionary of visited nodes in the current branch if not prune, + or in the whole tree if prune. """ if visited.has_key(root): @@ -486,12 +488,13 @@ def render_tree(root, child_func, margin=[0], visited={}): retval = retval + " " retval = retval + "+-" + str(root) + "\n" - visited = copy.copy(visited) + if not prune: + visited = copy.copy(visited) visited[root] = 1 for i in range(len(children)): margin.append(i