build: update waf to version 2.0.6

Cleanup in most build scripts

Change-Id: Ib024e95fb6f80e72b0c00e1dc8bb9300d6c5f191
diff --git a/wscript b/wscript
index 132bd9d..502c1ee 100644
--- a/wscript
+++ b/wscript
@@ -1,13 +1,13 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-from waflib import Logs, Utils, Context
-import os
+from waflib import Context, Logs, Utils
+import os, subprocess
 
-VERSION = "0.6.1"
-APPNAME = "ndn-cxx"
-PACKAGE_BUGREPORT = "https://redmine.named-data.net/projects/ndn-cxx"
-PACKAGE_URL = "http://named-data.net/doc/ndn-cxx/"
-GIT_TAG_PREFIX = "ndn-cxx-"
+VERSION = '0.6.1'
+APPNAME = 'ndn-cxx'
+PACKAGE_BUGREPORT = 'https://redmine.named-data.net/projects/ndn-cxx'
+PACKAGE_URL = 'http://named-data.net/doc/ndn-cxx/'
+GIT_TAG_PREFIX = 'ndn-cxx-'
 
 def options(opt):
     opt.load(['compiler_cxx', 'gnu_dirs', 'c_osx'])
@@ -64,7 +64,7 @@
     conf.env.enable_shared = conf.options.enable_shared
 
     if not conf.options.enable_shared and not conf.options.enable_static:
-        conf.fatal("Either static library or shared library must be enabled")
+        conf.fatal('Either static library or shared library must be enabled')
 
     conf.load(['compiler_cxx', 'gnu_dirs', 'c_osx',
                'default-compiler-flags', 'compiler-features', 'type_traits',
@@ -79,7 +79,10 @@
 
     conf.check_cxx(lib='pthread', uselib_store='PTHREAD', define_name='HAVE_PTHREAD', mandatory=False)
     conf.check_cxx(lib='rt', uselib_store='RT', define_name='HAVE_RT', mandatory=False)
-    conf.check_cxx(function_name='getpass', header_name='unistd.h', mandatory=False)
+    conf.check_cxx(msg='Checking for getpass function', mandatory=False,
+                   define_name='HAVE_GETPASS',
+                   fragment='''#include <unistd.h>
+                               int main() { getpass("Enter password"); }''')
 
     if conf.check_cxx(msg='Checking for rtnetlink', define_name='HAVE_RTNETLINK', mandatory=False,
                       header_name=['linux/if_addr.h', 'linux/if_link.h',
@@ -106,10 +109,9 @@
 
     conf.check_boost(lib=USED_BOOST_LIBS, mandatory=True, mt=True)
     if conf.env.BOOST_VERSION_NUMBER < 105400:
-        Logs.error("Minimum required boost version is 1.54.0")
-        Logs.error("Please upgrade your distribution or install custom boost libraries" +
-                   " (https://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)")
-        return
+        conf.fatal('Minimum required Boost version is 1.54.0\n'
+                   'Please upgrade your distribution or manually install a newer version of Boost'
+                   ' (https://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)')
 
     if conf.env['CXX_NAME'] == 'clang' and conf.env.BOOST_VERSION_NUMBER < 105800:
         conf.env.append_value('DEFINES', 'BOOST_ASIO_HAS_STD_ARRAY=1') # Bug #4096
@@ -126,7 +128,7 @@
 
     conf.check_compiler_flags()
 
-    # Loading "late" to prevent tests to be compiled with profiling flags
+    # Loading "late" to prevent tests from being compiled with profiling flags
     conf.load('coverage')
 
     conf.load('sanitizers')
@@ -147,8 +149,8 @@
 def build(bld):
     version(bld)
 
-    bld(features="subst",
-        name='version',
+    bld(features='subst',
+        name='version.hpp',
         source='src/version.hpp.in',
         target='src/version.hpp',
         install_path=None,
@@ -164,28 +166,28 @@
     if bld.env['HAVE_OSX_FRAMEWORKS']:
         # Need to disable precompiled headers for Objective-C++ code
         bld(features=['cxx'],
-            target="ndn-cxx-mm",
-            name="ndn-cxx-mm",
+            target='ndn-cxx-mm',
+            name='ndn-cxx-mm',
             source=bld.path.ant_glob(['src/**/*-osx.mm']),
             use='version BOOST OPENSSL SQLITE3 RT PTHREAD OSX_COREFOUNDATION OSX_CORESERVICES OSX_SECURITY OSX_SYSTEMCONFIGURATION OSX_FOUNDATION OSX_COREWLAN',
-            includes=". src")
+            includes='src')
 
     libndn_cxx = dict(
-        target="ndn-cxx",
-        name="ndn-cxx",
+        target='ndn-cxx',
         source=bld.path.ant_glob('src/**/*.cpp',
                                  excl=['src/**/*-osx.cpp',
                                        'src/**/*-rtnl.cpp',
                                        'src/**/*-sqlite3.cpp']),
+        features='pch',
         headers='src/common-pch.hpp',
         use='version ndn-cxx-mm BOOST OPENSSL SQLITE3 RT PTHREAD',
-        includes=". src",
-        export_includes="src",
+        includes='. src',
+        export_includes='src',
         install_path='${LIBDIR}')
 
     if bld.env['HAVE_OSX_FRAMEWORKS']:
         libndn_cxx['source'] += bld.path.ant_glob('src/**/*-osx.cpp')
-        libndn_cxx['use'] += " OSX_COREFOUNDATION OSX_CORESERVICES OSX_SECURITY OSX_SYSTEMCONFIGURATION OSX_FOUNDATION OSX_COREWLAN"
+        libndn_cxx['use'] += ' OSX_COREFOUNDATION OSX_CORESERVICES OSX_SECURITY OSX_SYSTEMCONFIGURATION OSX_FOUNDATION OSX_COREWLAN'
 
     if bld.env['HAVE_RTNETLINK']:
         libndn_cxx['source'] += bld.path.ant_glob('src/**/*-rtnl.cpp')
@@ -194,14 +196,14 @@
     libndn_cxx['source'] += bld.path.ant_glob('src/**/*-sqlite3.cpp')
 
     if bld.env.enable_shared:
-        bld(features=['pch', 'cxx', 'cxxshlib'],
-            vnum=VERSION_BASE,
-            cnum=VERSION_BASE,
-            **libndn_cxx)
+        bld.shlib(name='ndn-cxx',
+                  vnum=VERSION_BASE,
+                  cnum=VERSION_BASE,
+                  **libndn_cxx)
 
     if bld.env.enable_static:
-        bld(features=['pch', 'cxx', 'cxxstlib'],
-            **libndn_cxx)
+        bld.stlib(name='ndn-cxx-static' if bld.env.enable_shared else 'ndn-cxx',
+                  **libndn_cxx)
 
     # Prepare flags that should go to pkgconfig file
     pkgconfig_libs = []
@@ -221,37 +223,37 @@
         if bld.env['CXXFLAGS_%s' % lib]:
             pkgconfig_cxxflags += Utils.to_list(bld.env['CXXFLAGS_%s' % lib])
 
-    EXTRA_FRAMEWORKS = ""
+    EXTRA_FRAMEWORKS = ''
     if bld.env['HAVE_OSX_FRAMEWORKS']:
-        EXTRA_FRAMEWORKS = "-framework CoreFoundation -framework CoreServices -framework Security -framework SystemConfiguration -framework Foundation -framework CoreWLAN"
+        EXTRA_FRAMEWORKS = '-framework CoreFoundation -framework CoreServices -framework Security -framework SystemConfiguration -framework Foundation -framework CoreWLAN'
 
     def uniq(alist):
         seen = set()
         return [x for x in alist if x not in seen and not seen.add(x)]
 
-    pkconfig = bld(features="subst",
-         source="libndn-cxx.pc.in",
-         target="libndn-cxx.pc",
-         install_path="${LIBDIR}/pkgconfig",
+    pkconfig = bld(features='subst',
+         source='libndn-cxx.pc.in',
+         target='libndn-cxx.pc',
+         install_path='${LIBDIR}/pkgconfig',
          VERSION=VERSION_BASE,
 
          # This probably not the right thing to do, but to simplify life of apps
          # that use the library
-         EXTRA_LIBS=" ".join([('-l%s' % i) for i in uniq(pkgconfig_libs)]),
-         EXTRA_LDFLAGS=" ".join([('-L%s' % i) for i in uniq(pkgconfig_ldflags)]),
-         EXTRA_LINKFLAGS=" ".join(uniq(pkgconfig_linkflags)),
-         EXTRA_INCLUDES=" ".join([('-I%s' % i) for i in uniq(pkgconfig_includes)]),
-         EXTRA_CXXFLAGS=" ".join(uniq(pkgconfig_cxxflags)),
+         EXTRA_LIBS=' '.join([('-l%s' % i) for i in uniq(pkgconfig_libs)]),
+         EXTRA_LDFLAGS=' '.join([('-L%s' % i) for i in uniq(pkgconfig_ldflags)]),
+         EXTRA_LINKFLAGS=' '.join(uniq(pkgconfig_linkflags)),
+         EXTRA_INCLUDES=' '.join([('-I%s' % i) for i in uniq(pkgconfig_includes)]),
+         EXTRA_CXXFLAGS=' '.join(uniq(pkgconfig_cxxflags)),
          EXTRA_FRAMEWORKS=EXTRA_FRAMEWORKS)
 
     if bld.env['WITH_TESTS']:
         bld.recurse('tests')
 
     if bld.env['WITH_TOOLS']:
-        bld.recurse("tools")
+        bld.recurse('tools')
 
     if bld.env['WITH_EXAMPLES']:
-        bld.recurse("examples")
+        bld.recurse('examples')
 
     headers = bld.path.ant_glob('src/**/*.hpp',
                                 excl=['src/**/*-osx.hpp',
@@ -267,24 +269,25 @@
     # In case we want to make it optional later
     headers += bld.path.ant_glob('src/**/*-sqlite3.hpp', excl='src/**/detail/**/*')
 
-    bld.install_files("%s/ndn-cxx" % bld.env['INCLUDEDIR'], headers,
+    bld.install_files('%s/ndn-cxx' % bld.env['INCLUDEDIR'], headers,
                       relative_trick=True, cwd=bld.path.find_node('src'))
 
-    bld.install_files("%s/ndn-cxx" % bld.env['INCLUDEDIR'],
+    bld.install_files('%s/ndn-cxx' % bld.env['INCLUDEDIR'],
                       bld.path.find_resource('src/ndn-cxx-config.hpp'))
 
-    bld.install_files("%s/ndn-cxx" % bld.env['INCLUDEDIR'],
+    bld.install_files('%s/ndn-cxx' % bld.env['INCLUDEDIR'],
                       bld.path.find_resource('src/version.hpp'))
 
-    bld.install_files("${SYSCONFDIR}/ndn", "client.conf.sample")
+    bld.install_files('${SYSCONFDIR}/ndn', 'client.conf.sample')
 
-    if bld.env['SPHINX_BUILD']:
-        bld(features="sphinx",
-            builder="man",
-            outdir="docs/manpages",
-            config="docs/conf.py",
+    if bld.env.SPHINX_BUILD:
+        bld(features='sphinx',
+            name='manpages',
+            builder='man',
+            outdir='docs/manpages',
+            config='docs/conf.py',
             source=bld.path.ant_glob('docs/manpages/**/*.rst'),
-            install_path="${MANDIR}/",
+            install_path='${MANDIR}',
             VERSION=VERSION)
 
 def docs(bld):
@@ -295,85 +298,82 @@
     version(bld)
 
     if not bld.env.DOXYGEN:
-        Logs.error("ERROR: cannot build documentation (`doxygen' not found in $PATH)")
-    else:
-        bld(features="subst",
-            name="doxygen-conf",
-            source=["docs/doxygen.conf.in",
-                    "docs/named_data_theme/named_data_footer-with-analytics.html.in"],
-            target=["docs/doxygen.conf",
-                    "docs/named_data_theme/named_data_footer-with-analytics.html"],
-            VERSION=VERSION,
-            HTML_FOOTER="../build/docs/named_data_theme/named_data_footer-with-analytics.html" \
-                          if os.getenv('GOOGLE_ANALYTICS', None) \
-                          else "../docs/named_data_theme/named_data_footer.html",
-            GOOGLE_ANALYTICS=os.getenv('GOOGLE_ANALYTICS', ""))
+        bld.fatal('Cannot build documentation ("doxygen" not found in PATH)')
 
-        bld(features="doxygen",
-            doxyfile="docs/doxygen.conf",
-            use="doxygen-conf")
+    bld(features='subst',
+        name='doxygen.conf',
+        source=['docs/doxygen.conf.in',
+                'docs/named_data_theme/named_data_footer-with-analytics.html.in'],
+        target=['docs/doxygen.conf',
+                'docs/named_data_theme/named_data_footer-with-analytics.html'],
+        VERSION=VERSION,
+        HTML_FOOTER='../build/docs/named_data_theme/named_data_footer-with-analytics.html' \
+                        if os.getenv('GOOGLE_ANALYTICS', None) \
+                        else '../docs/named_data_theme/named_data_footer.html',
+        GOOGLE_ANALYTICS=os.getenv('GOOGLE_ANALYTICS', ''))
+
+    bld(features='doxygen',
+        doxyfile='docs/doxygen.conf',
+        use='doxygen.conf')
 
 def sphinx(bld):
     version(bld)
 
     if not bld.env.SPHINX_BUILD:
-        bld.fatal("ERROR: cannot build documentation (`sphinx-build' not found in $PATH)")
-    else:
-        bld(features="sphinx",
-            outdir="docs",
-            source=bld.path.ant_glob("docs/**/*.rst"),
-            config="docs/conf.py",
-            VERSION=VERSION)
+        bld.fatal('Cannot build documentation ("sphinx-build" not found in PATH)')
+
+    bld(features='sphinx',
+        config='docs/conf.py',
+        outdir='docs',
+        source=bld.path.ant_glob('docs/**/*.rst'),
+        VERSION=VERSION)
 
 def version(ctx):
+    # don't execute more than once
     if getattr(Context.g_module, 'VERSION_BASE', None):
         return
 
     Context.g_module.VERSION_BASE = Context.g_module.VERSION
-    Context.g_module.VERSION_SPLIT = [v for v in VERSION_BASE.split('.')]
+    Context.g_module.VERSION_SPLIT = VERSION_BASE.split('.')
 
-    didGetVersion = False
+    # first, try to get a version string from git
+    gotVersionFromGit = False
     try:
         cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
-        p = Utils.subprocess.Popen(cmd, stdout=Utils.subprocess.PIPE,
-                                   stderr=None, stdin=None)
-        out = str(p.communicate()[0].strip())
-        didGetVersion = (p.returncode == 0 and out != "")
-        if didGetVersion:
+        out = subprocess.check_output(cmd, universal_newlines=True).strip()
+        if out:
+            gotVersionFromGit = True
             if out.startswith(GIT_TAG_PREFIX):
-                Context.g_module.VERSION = out[len(GIT_TAG_PREFIX):]
+                Context.g_module.VERSION = out.lstrip(GIT_TAG_PREFIX)
             else:
-                Context.g_module.VERSION = "%s-commit-%s" % (Context.g_module.VERSION_BASE, out)
-    except OSError:
+                # no tags matched
+                Context.g_module.VERSION = '%s-commit-%s' % (VERSION_BASE, out)
+    except subprocess.CalledProcessError:
         pass
 
     versionFile = ctx.path.find_node('VERSION')
-
-    if not didGetVersion and versionFile is not None:
+    if not gotVersionFromGit and versionFile is not None:
         try:
             Context.g_module.VERSION = versionFile.read()
             return
-        except (OSError, IOError):
+        except EnvironmentError:
             pass
 
     # version was obtained from git, update VERSION file if necessary
     if versionFile is not None:
         try:
-            version = versionFile.read()
-            if version == Context.g_module.VERSION:
-                return # no need to update
-        except (OSError, IOError):
-            Logs.warn("VERSION file exists, but not readable")
+            if versionFile.read() == Context.g_module.VERSION:
+                # already up-to-date
+                return
+        except EnvironmentError as e:
+            Logs.warn('%s exists but is not readable (%s)' % (versionFile, e.strerror))
     else:
         versionFile = ctx.path.make_node('VERSION')
 
-    if versionFile is None:
-        return
-
     try:
         versionFile.write(Context.g_module.VERSION)
-    except (OSError, IOError):
-        Logs.warn("VERSION file is not writeable")
+    except EnvironmentError as e:
+        Logs.warn('%s is not writable (%s)' % (versionFile, e.strerror))
 
 def dist(ctx):
     version(ctx)