build: allow use of target names as commands in waf
authorAndrew Tridgell <tridge@samba.org>
Tue, 4 May 2010 08:08:43 +0000 (10:08 +0200)
committerAndrew Tridgell <tridge@samba.org>
Tue, 4 May 2010 09:45:43 +0000 (11:45 +0200)
This allows for the following types of commands:

 waf smbd/samba
 waf smbd/server.c
 waf ../lib/util/util_file.c
 waf ../lib/util/util_file_*.o

this will be used as part of an updated minimal_includes.pl script

buildtools/wafsamba/samba_wildcard.py [new file with mode: 0644]
buildtools/wafsamba/wafsamba.py
source4/wscript

diff --git a/buildtools/wafsamba/samba_wildcard.py b/buildtools/wafsamba/samba_wildcard.py
new file mode 100644 (file)
index 0000000..bcacb4f
--- /dev/null
@@ -0,0 +1,114 @@
+#! /usr/bin/env python
+
+# based on playground/evil in the waf svn tree
+
+import os, datetime
+import Scripting, Utils, Options, Logs, Environment, fnmatch
+from Constants import *
+
+def run_task(t, k):
+       '''run a single build task'''
+       ret = t.run()
+       if ret:
+               raise Utils.WafError("Failed to build %s: %u" % (k, ret))
+
+
+def run_named_build_task(cmd):
+       '''run a named build task, matching the cmd name using fnmatch
+       wildcards against inputs and outputs of all build tasks'''
+       bld = fake_build_environment()
+       found = False
+       cwd_node = bld.root.find_dir(os.getcwd())
+       cmd = os.path.normpath(cmd)
+       for g in bld.task_manager.groups:
+               for attr in ['outputs', 'inputs']:
+                       for t in g.tasks:
+                               s = getattr(t, attr, [])
+                               for k in s:
+                                       relpath = k.relpath_gen(cwd_node)
+                                       if fnmatch.fnmatch(relpath, cmd):
+                                               t.position= [0,0]
+                                               print t.display()
+                                               run_task(t, k)
+                                               return
+
+       if not found:
+               raise Utils.WafError("Unable to find build target matching %s" % cmd)
+
+
+
+def wildcard_main(missing_cmd_fn):
+       '''this replaces main from Scripting, allowing us to override the
+          behaviour for unknown commands
+
+          If a unknown command is found, then missing_cmd_fn() is called with
+          the name of the requested command
+          '''
+       Scripting.commands = Options.arg_line[:]
+
+       while Scripting.commands:
+               x = Scripting.commands.pop(0)
+
+               ini = datetime.datetime.now()
+               if x == 'configure':
+                       fun = Scripting.configure
+               elif x == 'build':
+                       fun = Scripting.build
+               else:
+                       fun = getattr(Utils.g_module, x, None)
+
+               # this is the new addition on top of main from Scripting.py
+               if not fun:
+                       missing_cmd_fn(x)
+                       break
+
+               ctx = getattr(Utils.g_module, x + '_context', Utils.Context)()
+
+               if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']:
+                       try:
+                               fun(ctx)
+                       except TypeError:
+                               fun()
+               else:
+                       fun(ctx)
+
+               ela = ''
+               if not Options.options.progress_bar:
+                       ela = ' (%s)' % Utils.get_elapsed_time(ini)
+
+               if x != 'init' and x != 'shutdown':
+                       Logs.info('%r finished successfully%s' % (x, ela))
+
+               if not Scripting.commands and x != 'shutdown':
+                       Scripting.commands.append('shutdown')
+
+
+
+
+def fake_build_environment():
+       """create all the tasks for the project, but do not run the build
+       return the build context in use"""
+       bld = getattr(Utils.g_module, 'build_context', Utils.Context)()
+       bld = Scripting.check_configured(bld)
+
+       Options.commands['install'] = False
+       Options.commands['uninstall'] = False
+       Options.is_install = False
+
+       bld.is_install = 0 # False
+
+       try:
+               proj = Environment.Environment(Options.lockfile)
+       except IOError:
+               raise Utils.WafError("Project not configured (run 'waf configure' first)")
+
+       bld.load_dirs(proj[SRCDIR], proj[BLDDIR])
+       bld.load_envs()
+
+       Logs.info("Waf: Entering directory `%s'" % bld.bldnode.abspath())
+       bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]])
+
+       bld.pre_build()
+       bld.flush()
+       return bld
+
index d4766b099d018670499772b4cd278f75c27eaa39..2b53a9ceb64bb6383dbfcf13b7dd7ccfb8314638 100644 (file)
@@ -25,6 +25,7 @@ import tru64cc
 import irixcc
 import generic_cc
 import samba_dist
+import samba_wildcard
 
 O644 = 420
 
index e5c8d230921c34854e4cbc75c26d8cea15899eeb..880069ed0e248833d528ca17346254d5c0d86643 100644 (file)
@@ -8,7 +8,7 @@ VERSION='4.0.0-alpha13'
 
 import sys, os
 sys.path.insert(0, srcdir+"/buildtools/wafsamba")
-import wafsamba, Options, samba_dist
+import wafsamba, Options, samba_dist, Scripting
 
 samba_dist.DIST_DIRS('.')
 
@@ -147,4 +147,13 @@ def distcheck():
     d = Scripting.distcheck
     d(subdir='source4')
 
+def wildcard_cmd(cmd):
+    '''called on a unknown command'''
+    from samba_wildcard import run_named_build_task
+    run_named_build_task(cmd)
+
+def main():
+    from samba_wildcard import wildcard_main
+    wildcard_main(wildcard_cmd)
+Scripting.main = main