build: added WHYNEEDED=TARGET:DEPENDENCY
authorAndrew Tridgell <tridge@samba.org>
Mon, 21 Feb 2011 23:59:44 +0000 (10:59 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 22 Feb 2011 02:35:58 +0000 (03:35 +0100)
you can now do:

  make WHYNEEDED=smbd/smbd:gensec

and it will print:

 Checking why smbd/smbd needs to link to gensec
 target 'smbd/smbd' uses symbols set(['open_schannel_session_store']) from 'gensec'

Autobuild-User: Andrew Tridgell <tridge@samba.org>
Autobuild-Date: Tue Feb 22 03:35:58 CET 2011 on sn-devel-104

buildtools/wafsamba/symbols.py
buildtools/wafsamba/wscript

index 942748507792a17be0e46da55ff5acfb1303143a..4f4b30382b3a376748b2e7e9faad3c8aeb0e460e 100644 (file)
@@ -97,10 +97,12 @@ def find_syslib_path(bld, libname, deps):
 def build_symbol_sets(bld, tgt_list):
     '''build the public_symbols and undefined_symbols attributes for each target'''
 
+    if bld.env.public_symbols:
+        return
+
     objlist = []  # list of object file
     objmap = {}   # map from object filename to target (subsystem) name
 
-
     for t in tgt_list:
         t.public_symbols = set()
         t.undefined_symbols = set()
@@ -161,6 +163,9 @@ def build_symbol_sets(bld, tgt_list):
 def build_syslib_sets(bld, tgt_list):
     '''build the public_symbols for all syslibs'''
 
+    if bld.env.syslib_symbols:
+        return
+
     # work out what syslibs we depend on, and what targets those are used in
     syslibs = {}
     objmap = {}
@@ -209,6 +214,7 @@ def build_syslib_sets(bld, tgt_list):
     for lib in bld.env.syslib_symbols:
         bld.env.public_symbols[objmap[lib]] = bld.env.syslib_symbols[lib]
 
+
 def build_autodeps(bld, t):
     '''build the set of dependencies for a target'''
     deps = set()
@@ -246,6 +252,10 @@ def build_autodeps(bld, t):
 
 def build_library_names(bld, tgt_list):
     '''add a in_library attribute to all targets that are part of a library'''
+
+    if bld.env.done_build_library_names:
+        return
+
     for t in tgt_list:
         t.in_library = []
 
@@ -256,6 +266,7 @@ def build_library_names(bld, tgt_list):
                 if t2 and t2.samba_type in [ 'SUBSYSTEM', 'ASN1' ]:
                     if not t.sname in t2.in_library:
                         t2.in_library.append(t.sname)
+    bld.env.done_build_library_names = True
 
 
 def check_library_deps(bld, t):
@@ -403,20 +414,33 @@ def symbols_syslibcheck(task):
         check_syslib_dependencies(bld, t)
 
 
-def check_why_needed(bld, target, subsystem):
+def symbols_whyneeded(task):
     """check why 'target' needs to link to 'subsystem'"""
+    bld = task.env.bld
+    tgt_list = get_tgt_list(bld)
+
+    why = Options.options.WHYNEEDED.split(":")
+    if len(why) != 2:
+        raise Utils.WafError("usage: WHYNEEDED=TARGET:DEPENDENCY")
+    target = why[0]
+    subsystem = why[1]
+
+    build_symbol_sets(bld, tgt_list)
+    build_library_names(bld, tgt_list)
+    build_syslib_sets(bld, tgt_list)
+
     Logs.info("Checking why %s needs to link to %s" % (target, subsystem))
     if not target in bld.env.used_symbols:
-        Logs.warn("unable to find target %s in used_symbols dict" % target)
+        Logs.warn("unable to find target '%s' in used_symbols dict" % target)
         return
     if not subsystem in bld.env.public_symbols:
-        Logs.warn("unable to find subsystem %s in public_symbols dict" % subsystem)
+        Logs.warn("unable to find subsystem '%s' in public_symbols dict" % subsystem)
         return
     overlap = bld.env.used_symbols[target].intersection(bld.env.public_symbols[subsystem])
     if not overlap:
-        Logs.info("target %s doesn't use any public symbols from %s" % (target, subsystem))
+        Logs.info("target '%s' doesn't use any public symbols from '%s'" % (target, subsystem))
     else:
-        Logs.info("target %s uses %s from %s" % (target, overlap, subsystem))
+        Logs.info("target '%s' uses symbols %s from '%s'" % (target, overlap, subsystem))
 
 
 
@@ -432,9 +456,6 @@ def symbols_dupcheck(task):
             continue
         Logs.info("symbol %s appears in %s" % (sym, subsystems))
 
-    # use this type of call to find why a library is needed
-    check_why_needed(bld, 'smbd/smbd', 'gensec')
-
 
 def SYMBOL_CHECK(bld):
     '''check our dependency lists'''
@@ -451,4 +472,10 @@ def SYMBOL_CHECK(bld):
         task = bld(rule=symbols_dupcheck, always=True, name='symbol duplicate checking')
         task.env.bld = bld
 
+    if Options.options.WHYNEEDED:
+        bld.SET_BUILD_GROUP('syslibcheck')
+        task = bld(rule=symbols_whyneeded, always=True, name='check why a dependency is needed')
+        task.env.bld = bld
+
+
 Build.BuildContext.SYMBOL_CHECK = SYMBOL_CHECK
index 4f93bb17932c89b7a292ea0c440d9c37a450c873..ecc2ae51f69ac4e21db530aa8112d9c02dc16f74 100755 (executable)
@@ -121,6 +121,10 @@ def set_options(opt):
                   help=("check symbols in object files against project rules"),
                   action='store_true', dest='SYMBOLCHECK', default=False)
 
+    gr.add_option('--why-needed',
+                  help=("TARGET:DEPENDENCY check why TARGET needs DEPENDENCY"),
+                  action='store', type='str', dest='WHYNEEDED', default=None)
+
     gr.add_option('--show-duplicates',
                   help=("Show objects which are included in multiple binaries or libraries"),
                   action='store_true', dest='SHOW_DUPLICATES', default=False)