Add --debug-includes. (Anthony Roach)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 14 Jan 2003 23:43:59 +0000 (23:43 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 14 Jan 2003 23:43:59 +0000 (23:43 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@547 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/engine/SCons/Node/__init__.py
src/engine/SCons/Script/__init__.py
src/engine/SCons/Util.py
src/engine/SCons/UtilTests.py
test/option--debug.py

index 12e09f3a4898e94668789a5c9564b0ded09c526e..da362291a56a9ad5cdcc71f9d152f80ae5e8e19a 100644 (file)
@@ -396,6 +396,16 @@ executing each build command, the total build time, the total time spent
 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
index 621b865f6ebd2a5d0e62b954c1f0c4e8e41e6408..2eeae3011da375fb6aa8b2ae23b8f3ae6bf230d1 100644 (file)
@@ -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
index 14f99edcc230dd37fccc22c63d8bec27726199f7..ec337138ff82d4244555c54ff8b2b97d3e3d0bc1 100644 (file)
@@ -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
index a33e373e5231b8fc616597e759ae529899acdd60..034bf73a3af0433dea82f40c5921a4637409176f 100644 (file)
@@ -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)
index c89e8e6bd1f219256632a42439ef7d09ed427b55..408c4af64238187ea8de86ee3ec01d828c732cef 100644 (file)
@@ -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<len(children)-1)
-        retval = retval + render_tree(children[i], child_func, margin, visited
+        retval = retval + render_tree(children[i], child_func, prune, margin, visited
 )
         margin.pop()
 
index 2da792fa33262b40c1f85c5ea2ebbfd992e66fa6..1d827b092d08ff1a4cbcce0eb6443244da227fb2 100644 (file)
@@ -306,6 +306,22 @@ class UtilTestCase(unittest.TestCase):
 
         actual = render_tree(foo, get_children)
         assert expect == actual, (expect, actual)
+        
+        bar_h = Node('bar.h', [stdlib_h])
+        blat_h = Node('blat.h', [stdlib_h])
+        blat_c = Node('blat.c', [blat_h, bar_h])
+        blat_o = Node('blat.o', [blat_c])
+
+        expect = """\
++-blat.o
+  +-blat.c
+    +-blat.h
+    | +-stdlib.h
+    +-bar.h
+"""
+
+        actual = render_tree(blat_o, get_children, 1)
+        assert expect == actual, (expect, actual)        
 
     def test_is_Dict(self):
         assert is_Dict({})
index cf6c4e06d495c615f7adcaff0bf00a0b11504599..e85ca5c19ed41dd9a0e5267e20a898a2b8bf81fb 100644 (file)
@@ -94,6 +94,19 @@ tree = """
 test.run(arguments = "--debug=dtree foo.xxx")
 test.fail_test(string.find(test.stdout(), tree) == -1)
 
+tree = """
++-foo.c
+  +-foo.h
+    +-bar.h
+"""
+test.run(arguments = "--debug=includes foo.ooo")
+test.fail_test(string.find(test.stdout(), tree) == -1)
+
+# these shouldn't print out anything in particular, but
+# they shouldn't crash either:
+test.run(arguments = "--debug=includes .")
+test.run(arguments = "--debug=includes foo.c")
+
 tree = """scons: \".\" is up to date.
 
 +-.