Add configuration to build a stand-alone application
Though, nothing compiles yet
diff --git a/waf-tools/boost.py b/waf-tools/boost.py
new file mode 100644
index 0000000..2ca82e2
--- /dev/null
+++ b/waf-tools/boost.py
@@ -0,0 +1,278 @@
+#!/usr/bin/env python
+# encoding: utf-8
+#
+# partially based on boost.py written by Gernot Vormayr
+# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
+# modified by Bjoern Michaelsen, 2008
+# modified by Luca Fossati, 2008
+# rewritten for waf 1.5.1, Thomas Nagy, 2008
+# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
+
+'''
+To add the boost tool to the waf file:
+$ ./waf-light --tools=compat15,boost
+ or, if you have waf >= 1.6.2
+$ ./waf update --files=boost
+
+The wscript will look like:
+
+def options(opt):
+ opt.load('compiler_cxx boost')
+
+def configure(conf):
+ conf.load('compiler_cxx boost')
+ conf.check_boost(lib='system filesystem', mt=True, static=True)
+
+def build(bld):
+ bld(source='main.cpp', target='app', use='BOOST')
+'''
+
+import sys
+import re
+from waflib import Utils, Logs
+from waflib.Configure import conf
+from waflib.Errors import WafError
+
+BOOST_LIBS = ('/usr/lib', '/usr/local/lib',
+ '/opt/local/lib', '/sw/lib', '/lib')
+BOOST_INCLUDES = ('/usr/include', '/usr/local/include',
+ '/opt/local/include', '/sw/include')
+BOOST_VERSION_FILE = 'boost/version.hpp'
+BOOST_VERSION_CODE = '''
+#include <iostream>
+#include <boost/version.hpp>
+int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
+'''
+
+# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
+PLATFORM = Utils.unversioned_sys_platform()
+detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
+detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
+detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
+BOOST_TOOLSETS = {
+ 'borland': 'bcb',
+ 'clang': detect_clang,
+ 'como': 'como',
+ 'cw': 'cw',
+ 'darwin': 'xgcc',
+ 'edg': 'edg',
+ 'g++': detect_mingw,
+ 'gcc': detect_mingw,
+ 'icpc': detect_intel,
+ 'intel': detect_intel,
+ 'kcc': 'kcc',
+ 'kylix': 'bck',
+ 'mipspro': 'mp',
+ 'mingw': 'mgw',
+ 'msvc': 'vc',
+ 'qcc': 'qcc',
+ 'sun': 'sw',
+ 'sunc++': 'sw',
+ 'tru64cxx': 'tru',
+ 'vacpp': 'xlc'
+}
+
+
+def options(opt):
+ opt.add_option('--boost-includes', type='string',
+ default='', dest='boost_includes',
+ help='''path to the boost directory where the includes are
+ e.g. /boost_1_45_0/include''')
+ opt.add_option('--boost-libs', type='string',
+ default='', dest='boost_libs',
+ help='''path to the directory where the boost libs are
+ e.g. /boost_1_45_0/stage/lib''')
+ opt.add_option('--boost-static', action='store_true',
+ default=False, dest='boost_static',
+ help='link static libraries')
+ opt.add_option('--boost-mt', action='store_true',
+ default=False, dest='boost_mt',
+ help='select multi-threaded libraries')
+ opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
+ help='''select libraries with tags (dgsyp, d for debug),
+ see doc Boost, Getting Started, chapter 6.1''')
+ opt.add_option('--boost-toolset', type='string',
+ default='', dest='boost_toolset',
+ help='force a toolset e.g. msvc, vc90, \
+ gcc, mingw, mgw45 (default: auto)')
+ py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
+ opt.add_option('--boost-python', type='string',
+ default=py_version, dest='boost_python',
+ help='select the lib python with this version \
+ (default: %s)' % py_version)
+
+
+@conf
+def __boost_get_version_file(self, dir):
+ try:
+ return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
+ except:
+ return None
+
+
+@conf
+def boost_get_version(self, dir):
+ """silently retrieve the boost version number"""
+ re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M)
+ try:
+ val = re_but.search(self.__boost_get_version_file(dir).read()).group(1)
+ except:
+ val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir],
+ execute=True, define_ret=True)
+ return val
+
+
+@conf
+def boost_get_includes(self, *k, **kw):
+ includes = k and k[0] or kw.get('includes', None)
+ if includes and self.__boost_get_version_file(includes):
+ return includes
+ for dir in BOOST_INCLUDES:
+ if self.__boost_get_version_file(dir):
+ return dir
+ if includes:
+ self.fatal('headers not found in %s' % includes)
+ else:
+ self.fatal('headers not found, use --boost-includes=/path/to/boost')
+
+
+@conf
+def boost_get_toolset(self, cc):
+ toolset = cc
+ if not cc:
+ build_platform = Utils.unversioned_sys_platform()
+ if build_platform in BOOST_TOOLSETS:
+ cc = build_platform
+ else:
+ cc = self.env.CXX_NAME
+ if cc in BOOST_TOOLSETS:
+ toolset = BOOST_TOOLSETS[cc]
+ return isinstance(toolset, str) and toolset or toolset(self.env)
+
+
+@conf
+def __boost_get_libs_path(self, *k, **kw):
+ ''' return the lib path and all the files in it '''
+ if 'files' in kw:
+ return self.root.find_dir('.'), Utils.to_list(kw['files'])
+ libs = k and k[0] or kw.get('libs', None)
+ if libs:
+ path = self.root.find_dir(libs)
+ files = path.ant_glob('*boost_*')
+ if not libs or not files:
+ for dir in BOOST_LIBS:
+ try:
+ path = self.root.find_dir(dir)
+ files = path.ant_glob('*boost_*')
+ if files:
+ break
+ path = self.root.find_dir(dir + '64')
+ files = path.ant_glob('*boost_*')
+ if files:
+ break
+ except:
+ path = None
+ if not path:
+ if libs:
+ self.fatal('libs not found in %s' % libs)
+ else:
+ self.fatal('libs not found, \
+ use --boost-includes=/path/to/boost/lib')
+ return path, files
+
+
+@conf
+def boost_get_libs(self, *k, **kw):
+ '''
+ return the lib path and the required libs
+ according to the parameters
+ '''
+ path, files = self.__boost_get_libs_path(**kw)
+ t = []
+ if kw.get('mt', False):
+ t.append('mt')
+ if kw.get('abi', None):
+ t.append(kw['abi'])
+ tags = t and '(-%s)+' % '-'.join(t) or ''
+ toolset = '(-%s[0-9]{0,3})+' % self.boost_get_toolset(kw.get('toolset', ''))
+ version = '(-%s)+' % self.env.BOOST_VERSION
+
+ def find_lib(re_lib, files):
+ for file in files:
+ if re_lib.search(file.name):
+ return file
+ return None
+
+ def format_lib_name(name):
+ if name.startswith('lib'):
+ name = name[3:]
+ return name.split('.')[0]
+
+ libs = []
+ for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
+ py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
+ # Trying libraries, from most strict match to least one
+ for pattern in ['boost_%s%s%s%s%s' % (lib, toolset, tags, py, version),
+ 'boost_%s%s%s%s' % (lib, tags, py, version),
+ 'boost_%s%s%s' % (lib, tags, version),
+ # Give up trying to find the right version
+ 'boost_%s%s%s%s' % (lib, toolset, tags, py),
+ 'boost_%s%s%s' % (lib, tags, py),
+ 'boost_%s%s' % (lib, tags)]:
+ file = find_lib(re.compile(pattern), files)
+ if file:
+ libs.append(format_lib_name(file.name))
+ break
+ else:
+ self.fatal('lib %s not found in %s' % (lib, path))
+
+ return path.abspath(), libs
+
+
+@conf
+def check_boost(self, *k, **kw):
+ """
+ initialize boost
+
+ You can pass the same parameters as the command line (without "--boost-"),
+ but the command line has the priority.
+ """
+ if not self.env['CXX']:
+ self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+ params = {'lib': k and k[0] or kw.get('lib', None)}
+ for key, value in self.options.__dict__.items():
+ if not key.startswith('boost_'):
+ continue
+ key = key[len('boost_'):]
+ params[key] = value and value or kw.get(key, '')
+
+ var = kw.get('uselib_store', 'BOOST')
+
+ self.start_msg('Checking boost includes')
+ try:
+ self.env['INCLUDES_%s' % var] = self.boost_get_includes(**params)
+ self.env.BOOST_VERSION = self.boost_get_version(self.env['INCLUDES_%s' % var])
+ except WafError:
+ self.end_msg("not found", 'YELLOW')
+ raise
+ self.end_msg(self.env.BOOST_VERSION)
+ if Logs.verbose:
+ Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
+
+ if not params['lib']:
+ return
+ self.start_msg('Checking boost libs')
+ try:
+ suffix = params.get('static', 'ST') or ''
+ path, libs = self.boost_get_libs(**params)
+ except WafError:
+ self.end_msg("not found", 'YELLOW')
+ raise
+ self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
+ self.env['%sLIB_%s' % (suffix, var)] = libs
+ self.end_msg('ok')
+ if Logs.verbose:
+ Logs.pprint('CYAN', ' path : %s' % path)
+ Logs.pprint('CYAN', ' libs : %s' % libs)
+