wscript: build a subset of tools

refs: #2670

Change-Id: I85951dd7510e36b48a630eb96e28f3351a3dac4f
diff --git a/AUTHORS.md b/AUTHORS.md
index 28a16cd..3d40a6f 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -11,3 +11,4 @@
 * Davide Pesavento      <http://www.lip6.fr/actualite/personnes-fiche.php?ident=D1469>
 * Junxiao Shi           <http://www.cs.arizona.edu/people/shijunxiao/>
 * Eric Newberry         <http://ericnewberry.com/>
+* Xiaoke Jiang          <http://netarchlab.tsinghua.edu.cn/~shock/>
diff --git a/tests/wscript b/tests/wscript
index 6066890..c67d252 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -5,11 +5,9 @@
     if not bld.env['WITH_TESTS']:
         return
 
-    tools = bld.path.ant_glob('*', dir=True, src=False)
-
     bld(target='../unit-tests',
         features='cxx cxxprogram',
-        source=bld.path.ant_glob('**/*.cpp'),
-        use=['core-objects'] + ['%s-objects' % tool for tool in tools],
+        source=bld.path.ant_glob(['*.cpp'] + ['%s/**/*.cpp' % tool for tool in bld.env['BUILD_TOOLS']]),
+        use=['core-objects'] + ['%s-objects' % tool for tool in bld.env['BUILD_TOOLS']],
         headers='../common.hpp boost-test.hpp',
         )
diff --git a/tools/wscript b/tools/wscript
index dd7e3a3..12954aa 100644
--- a/tools/wscript
+++ b/tools/wscript
@@ -1,10 +1,54 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 top = '..'
 
+from waflib import Options, Logs, Errors
+
+def options(opt):
+    for subdir in opt.path.ant_glob(['*'], dir=True, src=False):
+        opt.add_option('--enable-%s' % subdir,
+                   help='Build tool %s, enabled by default' % subdir,
+                   action="store_true",
+                   dest='enable_%s' % subdir)
+
+        opt.add_option('--disable-%s' % subdir,
+                   help='Do not build tool %s',
+                   action="store_true",
+                   dest='disable_%s' % subdir)
+
+        opt.recurse(str(subdir), mandatory=False)
+
+
 def configure(conf):
+    all_tools = set() # all available tools
+    enabled_tools = set() # --enable-X
+    disabled_tools = set() # --disable-X
+
     for subdir in conf.path.ant_glob(['*'], dir=True, src=False):
-        conf.recurse(str(subdir), mandatory=False)
+        tool = str(subdir)
+        all_tools.add(tool)
+
+        is_enabled = getattr(Options.options, 'enable_%s' % tool)
+        is_disabled = getattr(Options.options, 'disable_%s' % tool)
+
+        if is_enabled and is_disabled:
+            raise Errors.WafError("--enable-%s and --disable-%s cannot be both specified" % (tool, tool))
+
+        if is_enabled:
+            enabled_tools.add(tool)
+
+        if is_disabled:
+            disabled_tools.add(tool)
+
+    if len(enabled_tools) == 0:
+        conf.env['BUILD_TOOLS'] = list(all_tools - disabled_tools)
+    else:
+        conf.env['BUILD_TOOLS'] = list(enabled_tools)
+
+    for tool in conf.env['BUILD_TOOLS']:
+        conf.recurse(tool, mandatory=False)
+
+    conf.msg("Tools to build", ", ".join(conf.env['BUILD_TOOLS']))
 
 def build(bld):
-    for subdir in bld.path.ant_glob(['*'], dir=True, src=False):
-        bld.recurse(str(subdir))
+    for tool in bld.env['BUILD_TOOLS']:
+        bld.recurse(tool)
diff --git a/wscript b/wscript
index e7dd99b..ef4989b 100644
--- a/wscript
+++ b/wscript
@@ -6,9 +6,11 @@
 
 def options(opt):
     opt.load(['compiler_cxx', 'gnu_dirs'])
+
     opt.load(['default-compiler-flags', 'sphinx_build', 'boost'], tooldir=['.waf-tools'])
     opt.add_option('--with-tests', action='store_true', default=False,
                    dest='with_tests', help='''Build unit tests''')
+    opt.recurse("tools")
 
 def configure(conf):
     conf.load(['compiler_cxx', 'gnu_dirs',