waf: added --show-deps and --show-duplicates
authorAndrew Tridgell <tridge@samba.org>
Wed, 20 Oct 2010 07:09:45 +0000 (18:09 +1100)
committerAndrew Tridgell <tridge@samba.org>
Thu, 21 Oct 2010 08:03:23 +0000 (19:03 +1100)
these options make it easier to examine our depenency tree, by showing
any objects linked into more than one library, and by showing the
dependency tree for a chosen target

buildtools/wafsamba/samba_deps.py
buildtools/wafsamba/wscript

index 933a18b36911aebd4977620ccb9ce5c6fcef8876..2492a4c2338cb377f8eb57728d02dedce52fbd17 100644 (file)
@@ -792,6 +792,61 @@ def calculate_final_deps(bld, tgt_list, loops):
     debug('deps: removed duplicate dependencies')
 
 
+def show_dependencies(bld, target, seen):
+    '''recursively show the dependencies of target'''
+
+    if target in seen:
+        return
+
+    t = bld.name_to_obj(target, bld.env)
+    if t is None:
+        Logs.error("ERROR: Unable to find target '%s'" % target)
+        sys.exit(1)
+
+    Logs.info('%s(OBJECTS): %s' % (target, t.direct_objects))
+    Logs.info('%s(LIBS): %s' % (target, t.direct_libs))
+    Logs.info('%s(SYSLIBS): %s' % (target, t.direct_syslibs))
+
+    seen.add(target)
+
+    for t2 in t.direct_objects:
+        show_dependencies(bld, t2, seen)
+
+
+def show_object_duplicates(bld, tgt_list):
+    '''show a list of object files that are included in more than
+    one library or binary'''
+
+    targets = LOCAL_CACHE(bld, 'TARGET_TYPE')
+
+    used_by = {}
+
+    Logs.info("showing duplicate objects")
+
+    for t in tgt_list:
+        if not targets[t.sname] in [ 'LIBRARY' ]:
+            continue
+        for n in getattr(t, 'final_objects', set()):
+            t2 = bld.name_to_obj(n, bld.env)
+            if not n in used_by:
+                used_by[n] = set()
+            used_by[n].add(t.sname)
+
+    for n in used_by:
+        if len(used_by[n]) > 1:
+            Logs.info("target '%s' is used by %s" % (n, used_by[n]))
+
+    Logs.info("showing indirect dependency counts (sorted by count)")
+
+    def indirect_count(t1, t2):
+        return len(t2.indirect_objects) - len(t1.indirect_objects)
+
+    sorted_list = sorted(tgt_list, cmp=indirect_count)
+    for t in sorted_list:
+        if len(t.indirect_objects) > 1:
+            Logs.info("%s depends on %u indirect objects" % (t.sname, len(t.indirect_objects)))
+
+
 ######################################################################
 # this provides a way to save our dependency calculations between runs
 savedeps_version = 3
@@ -943,7 +998,10 @@ def check_project_rules(bld):
 
     add_samba_attributes(bld, tgt_list)
 
-    if load_samba_deps(bld, tgt_list):
+    force_project_rules = (Options.options.SHOWDEPS or
+                           Options.options.SHOW_DUPLICATES)
+
+    if not force_project_rules and load_samba_deps(bld, tgt_list):
         return
 
     bld.new_rules = True    
@@ -953,9 +1011,16 @@ def check_project_rules(bld):
 
     expand_subsystem_deps(bld)
     build_direct_deps(bld, tgt_list)
+
     break_dependency_loops(bld, tgt_list)
     calculate_final_deps(bld, tgt_list, loops)
 
+    if Options.options.SHOWDEPS:
+            show_dependencies(bld, Options.options.SHOWDEPS, set())
+
+    if Options.options.SHOW_DUPLICATES:
+            show_object_duplicates(bld, tgt_list)
+
     # run the various attribute generators
     for f in [ build_dependencies, build_includes, add_init_functions ]:
         debug('deps: project rules checking %s', f)
index c46c486c129d28fba3e208c70d8bf509b42f7fb2..9dc6910fdadc0ee0ffbc7b2c37779371513de8d9 100644 (file)
@@ -100,6 +100,14 @@ def set_options(opt):
                   help=("Update ABI signature files for libraries"),
                   action='store_true', dest='ABI_UPDATE', default=False)
 
+    gr.add_option('--show-deps',
+                  help=("Show dependency tree for the given target"),
+                  dest='SHOWDEPS', default='')
+
+    gr.add_option('--show-duplicates',
+                  help=("Show objects which are included in multiple binaries or libraries"),
+                  action='store_true', dest='SHOW_DUPLICATES', default=False)
+
     gr = opt.add_option_group('cross compilation options')
 
     gr.add_option('--cross-compile',