aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml2
-rw-r--r--docs/markdown/Dependencies.md15
-rw-r--r--docs/markdown/Release-notes-for-0.43.0/001-boost-platform-improvement.md10
-rw-r--r--mesonbuild/dependencies/misc.py413
-rw-r--r--test cases/frameworks/1 boost/meson.build5
-rw-r--r--test cases/frameworks/1 boost/nolinkexe.cc12
-rwxr-xr-xtools/boost_names.py180
7 files changed, 502 insertions, 135 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 60a6fd3..4dc3f50 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -59,8 +59,6 @@ init:
install:
- cmd: set "ORIG_PATH=%PATH%"
- # Boost 1.56.0: https://www.appveyor.com/docs/build-environment/#boost
- #- cmd: set "BOOST_ROOT=C:\Libraries\boost"
# Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219
- cmd: set "MESON_FIXED_NINJA=1"
- ps: (new-object net.webclient).DownloadFile('http://nirbheek.in/files/binaries/ninja/win32/ninja.exe', 'C:\projects\meson\ninja.exe')
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index 187c4fe..c46334c 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -50,8 +50,16 @@ pkg-config files. Meson has autodetection support for some of these.
## Boost ##
Boost is not a single dependency but rather a group of different
-libraries. To use Boost with Meson, simply list which Boost modules
-you would like to use.
+libraries. To use Boost headers-only libraries, simply add Boost as a
+dependency.
+
+```meson
+boost_dep = dependency('boost')
+exe = executable('myprog', 'file.cc', dependencies : boost_dep)
+```
+
+To link against boost with Meson, simply list which libraries you would like to
+use.
```meson
boost_dep = dependency('boost', modules : ['thread', 'utility'])
@@ -65,6 +73,9 @@ If your boost headers or libraries are in non-standard locations you
can set the BOOST_ROOT, BOOST_INCLUDEDIR, and/or BOOST_LIBRARYDIR
environment variables.
+You can set the argument `threading` to `single` to use boost libraries that
+has been compiled for single-threaded use instead.
+
## GTest and GMock ##
GTest and GMock come as sources that must be compiled as part of your
diff --git a/docs/markdown/Release-notes-for-0.43.0/001-boost-platform-improvement.md b/docs/markdown/Release-notes-for-0.43.0/001-boost-platform-improvement.md
new file mode 100644
index 0000000..2cd44ce
--- /dev/null
+++ b/docs/markdown/Release-notes-for-0.43.0/001-boost-platform-improvement.md
@@ -0,0 +1,10 @@
+## Portability improvements to Boost Dependency
+
+The Boost dependency has been improved to better detect the various ways to
+install boost on multiple platforms. At the same time the `modules` semantics
+for the dependency has been changed. Previously it was allowed to specify
+header directories as `modules` but it wasn't required. Now, modules are only
+used to specify libraries that require linking.
+
+This is a breaking change and the fix is to remove all modules that aren't
+found.
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 61d0d77..a0d5e47 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -18,7 +18,6 @@ import glob
import os
import re
import shlex
-import stat
import shutil
import sysconfig
@@ -30,77 +29,153 @@ from ..environment import detect_cpu_family
from .base import DependencyException, DependencyMethods
from .base import ExternalDependency, ExternalProgram, ExtraFrameworkDependency, PkgConfigDependency
+# On windows 3 directory layouts are supported:
+# * The default layout (versioned) installed:
+# - $BOOST_ROOT/include/boost-x_x/boost/*.hpp
+# - $BOOST_ROOT/lib/*.lib
+# * The non-default layout (system) installed:
+# - $BOOST_ROOT/include/boost/*.hpp
+# - $BOOST_ROOT/lib/*.lib
+# * The pre-built binaries from sf.net:
+# - $BOOST_ROOT/boost/*.hpp
+# - $BOOST_ROOT/lib<arch>-<compiler>/*.lib where arch=32/64 and compiler=msvc-14.1
+#
+# Library names supported:
+# - libboost_<module>-<compiler>-mt-gd-x_x.lib (static)
+# - boost_<module>-<compiler>-mt-gd-x_x.lib|.dll (shared)
+# - libboost_<module>.lib (static)
+# - boost_<module>.lib|.dll (shared)
+# where compiler is vc141 for example.
+#
+# NOTE: -gb means runtime and build time debugging is on
+# -mt means threading=multi
+#
+# The `modules` argument accept library names. This is because every module that
+# has libraries to link against also has multiple options regarding how to
+# link. See for example:
+# * http://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/boost_test/usage_variants.html
+# * http://www.boost.org/doc/libs/1_65_1/doc/html/stacktrace/configuration_and_build.html
+# * http://www.boost.org/doc/libs/1_65_1/libs/math/doc/html/math_toolkit/main_tr1.html
class BoostDependency(ExternalDependency):
- # Some boost libraries have different names for
- # their sources and libraries. This dict maps
- # between the two.
- name2lib = {'test': 'unit_test_framework'}
-
def __init__(self, environment, kwargs):
super().__init__('boost', environment, 'cpp', kwargs)
+ self.need_static_link = ['boost_exception', 'boost_test_exec_monitor']
+ self.is_debug = environment.cmd_line_options.buildtype.startswith('debug')
+ threading = kwargs.get("threading", "multi")
+ self.is_multithreading = threading == "multi"
+
+ self.requested_modules = self.get_requested(kwargs)
+
+ self.boost_root = None
+ self.boost_roots = []
+ self.incdir = None
self.libdir = None
- try:
+
+ if 'BOOST_ROOT' in os.environ:
self.boost_root = os.environ['BOOST_ROOT']
+ self.boost_roots = [self.boost_root]
if not os.path.isabs(self.boost_root):
raise DependencyException('BOOST_ROOT must be an absolute path.')
- except KeyError:
- self.boost_root = None
+ if 'BOOST_INCLUDEDIR' in os.environ:
+ self.incdir = os.environ['BOOST_INCLUDEDIR']
+ if 'BOOST_LIBRARYDIR' in os.environ:
+ self.libdir = os.environ['BOOST_LIBRARYDIR']
+
+ if self.want_cross and self.boost_root is None and self.incdir is None:
+ raise DependencyException('BOOST_ROOT or BOOST_INCLUDEDIR is needed while cross-compiling')
+
if self.boost_root is None:
- if self.want_cross:
- if 'BOOST_INCLUDEDIR' in os.environ:
- self.incdir = os.environ['BOOST_INCLUDEDIR']
- else:
- raise DependencyException('BOOST_ROOT or BOOST_INCLUDEDIR is needed while cross-compiling')
if mesonlib.is_windows():
- self.boost_root = self.detect_win_root()
- self.incdir = self.boost_root
+ self.boost_roots = self.detect_win_roots()
else:
- if 'BOOST_INCLUDEDIR' in os.environ:
- self.incdir = os.environ['BOOST_INCLUDEDIR']
- else:
- self.incdir = '/usr/include'
+ self.boost_roots = self.detect_nix_roots()
+
+ if self.boost_root is None and not self.boost_roots:
+ self.log_fail()
+ return
+
+ if self.incdir is None:
+ if mesonlib.is_windows():
+ self.incdir = self.detect_win_incdir()
+ else:
+ self.incdir = self.detect_nix_incdir()
+
+ if self.incdir is None:
+ self.log_fail()
+ return
+
+ mlog.debug('Boost library root dir is', mlog.bold(self.boost_root))
+ mlog.debug('Boost include directory is', mlog.bold(self.incdir))
- if 'BOOST_LIBRARYDIR' in os.environ:
- self.libdir = os.environ['BOOST_LIBRARYDIR']
- else:
- self.incdir = os.path.join(self.boost_root, 'include')
- self.boost_inc_subdir = os.path.join(self.incdir, 'boost')
- mlog.debug('Boost library root dir is', self.boost_root)
- self.src_modules = {}
self.lib_modules = {}
- self.lib_modules_mt = {}
self.detect_version()
- self.requested_modules = self.get_requested(kwargs)
- module_str = ', '.join(self.requested_modules)
if self.is_found:
- self.detect_src_modules()
self.detect_lib_modules()
+ mlog.debug('Boost library directory is', mlog.bold(self.libdir))
self.validate_requested()
- if self.boost_root is not None:
- info = self.version + ', ' + self.boost_root
- else:
- info = self.version
- mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), info)
+ self.log_success()
+ else:
+ self.log_fail()
+
+ def log_fail(self):
+ module_str = ', '.join(self.requested_modules)
+ mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
+
+ def log_success(self):
+ module_str = ', '.join(self.requested_modules)
+ if self.boost_root:
+ info = self.version + ', ' + self.boost_root
else:
- mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
+ info = self.version
+ mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), info)
+
+ def detect_nix_roots(self):
+ return ['/usr/local', '/usr']
- def detect_win_root(self):
- globtext = 'c:\\local\\boost_*'
+ def detect_win_roots(self):
+ res = []
+ # Where boost documentation says it should be
+ globtext = 'C:\\Program Files\\boost\\boost_*'
files = glob.glob(globtext)
- if len(files) > 0:
- return files[0]
- return 'C:\\'
+ res.extend(files)
+
+ # Where boost built from source actually installs it
+ if os.path.isdir('C:\\Boost'):
+ res.append('C:\\Boost')
+
+ # Where boost prebuilt binaries are
+ globtext = 'C:\\local\\boost_*'
+ files = glob.glob(globtext)
+ res.extend(files)
+ return res
+
+ def detect_nix_incdir(self):
+ for root in self.boost_roots:
+ incdir = os.path.join(root, 'include', 'boost')
+ if os.path.isdir(incdir):
+ return os.path.join(root, 'include')
+ return None
+
+ # FIXME: Should pick a version that matches the requested version
+ # Returns the folder that contains the boost folder.
+ def detect_win_incdir(self):
+ for root in self.boost_roots:
+ globtext = os.path.join(root, 'include', 'boost-*')
+ incdirs = glob.glob(globtext)
+ if len(incdirs) > 0:
+ return incdirs[0]
+ incboostdir = os.path.join(root, 'include', 'boost')
+ if os.path.isdir(incboostdir):
+ return os.path.join(root, 'include')
+ incboostdir = os.path.join(root, 'boost')
+ if os.path.isdir(incboostdir):
+ return root
+ return None
def get_compile_args(self):
args = []
- if self.boost_root is not None:
- if mesonlib.is_windows():
- include_dir = self.boost_root
- else:
- include_dir = os.path.join(self.boost_root, 'include')
- else:
- include_dir = self.incdir
+ include_dir = self.incdir
# Use "-isystem" when including boost headers instead of "-I"
# to avoid compiler warnings/failures when "-Werror" is used
@@ -125,19 +200,23 @@ class BoostDependency(ExternalDependency):
for c in candidates:
if not isinstance(c, str):
raise DependencyException('Boost module argument is not a string.')
+ if 'boost_' + c not in BOOST_LIBS:
+ raise DependencyException('Dependency {} not found. It is not a valid boost library.'.format(c))
return candidates
def validate_requested(self):
for m in self.requested_modules:
- if m not in self.src_modules and m not in self.lib_modules and m + '-mt' not in self.lib_modules_mt:
- msg = 'Requested Boost module {!r} not found'
+ if 'boost_' + m not in self.lib_modules:
+ msg = 'Requested Boost library {!r} not found'
raise DependencyException(msg.format(m))
def detect_version(self):
try:
- ifile = open(os.path.join(self.boost_inc_subdir, 'version.hpp'))
+ ifile = open(os.path.join(self.incdir, 'boost', 'version.hpp'))
except FileNotFoundError:
return
+ except TypeError:
+ return
with ifile:
for line in ifile:
if line.startswith("#define") and 'BOOST_LIB_VERSION' in line:
@@ -147,12 +226,6 @@ class BoostDependency(ExternalDependency):
self.is_found = True
return
- def detect_src_modules(self):
- for entry in os.listdir(self.boost_inc_subdir):
- entry = os.path.join(self.boost_inc_subdir, entry)
- if stat.S_ISDIR(os.stat(entry).st_mode):
- self.src_modules[os.path.split(entry)[-1]] = True
-
def detect_lib_modules(self):
if mesonlib.is_windows():
return self.detect_lib_modules_win()
@@ -160,32 +233,79 @@ class BoostDependency(ExternalDependency):
def detect_lib_modules_win(self):
arch = detect_cpu_family(self.env.coredata.compilers)
- # Guess the libdir
- if arch == 'x86':
- gl = 'lib32*'
- elif arch == 'x86_64':
- gl = 'lib64*'
- else:
- # Does anyone do Boost cross-compiling to other archs on Windows?
- gl = None
- # See if the libdir is valid
- if gl:
- libdir = glob.glob(os.path.join(self.boost_root, gl))
- else:
- libdir = []
- # Can't find libdir, bail
- if not libdir:
+ compiler_ts = self.env.detect_cpp_compiler(self.want_cross).get_toolset_version().split('.')
+ compiler = 'vc{}{}'.format(compiler_ts[0], compiler_ts[1])
+ if not self.libdir:
+ # The libdirs in the distributed binaries
+ if arch == 'x86':
+ gl = 'lib32*'
+ elif arch == 'x86_64':
+ gl = 'lib64*'
+ else:
+ # Does anyone do Boost cross-compiling to other archs on Windows?
+ gl = None
+ if self.boost_root:
+ roots = [self.boost_root]
+ else:
+ roots = self.boost_roots
+ for root in roots:
+ # The default libdir when building
+ libdir = os.path.join(root, 'lib')
+ if os.path.isdir(libdir):
+ self.libdir = libdir
+ break
+ if gl:
+ tmp = glob.glob(os.path.join(root, gl))
+ if len(tmp) > 0:
+ # FIXME: Should pick the correct version
+ self.libdir = tmp[0]
+ break
+
+ if not self.libdir:
return
- libdir = libdir[0]
- # Don't override what was set in the environment
- if self.libdir:
- self.libdir = libdir
- globber = 'libboost_*-gd-*.lib' if self.static else 'boost_*-gd-*.lib' # FIXME
- for entry in glob.glob(os.path.join(libdir, globber)):
+
+ for name in self.need_static_link:
+ libname = "lib{}".format(name) + '-' + compiler
+ if self.is_multithreading:
+ libname = libname + '-mt'
+ if self.is_debug:
+ libname = libname + '-gd'
+ libname = libname + "-{}.lib".format(self.version.replace('.', '_'))
+ if os.path.isfile(os.path.join(self.libdir, libname)):
+ modname = libname.split('-', 1)[0][3:]
+ self.lib_modules[modname] = libname
+ else:
+ libname = "lib{}.lib".format(name)
+ if os.path.isfile(os.path.join(self.libdir, libname)):
+ self.lib_modules[name[3:]] = libname
+
+ # globber1 applies to a layout=system installation
+ # globber2 applies to a layout=versioned installation
+ globber1 = 'libboost_*' if self.static else 'boost_*'
+ globber2 = globber1 + '-' + compiler
+ if self.is_multithreading:
+ globber2 = globber2 + '-mt'
+ if self.is_debug:
+ globber2 = globber2 + '-gd'
+ globber2 = globber2 + '-{}'.format(self.version.replace('.', '_'))
+ globber2_matches = glob.glob(os.path.join(self.libdir, globber2 + '.lib'))
+ for entry in globber2_matches:
(_, fname) = os.path.split(entry)
- base = fname.split('_', 1)[1]
- modname = base.split('-', 1)[0]
- self.lib_modules_mt[modname] = fname
+ modname = fname.split('-', 1)
+ if len(modname) > 1:
+ modname = modname[0]
+ else:
+ modname = modname.split('.', 1)[0]
+ if self.static:
+ modname = modname[3:]
+ self.lib_modules[modname] = fname
+ if len(globber2_matches) == 0:
+ for entry in glob.glob(os.path.join(self.libdir, globber1 + '.lib')):
+ (_, fname) = os.path.split(entry)
+ modname = fname.split('.', 1)[0]
+ if self.static:
+ modname = modname[3:]
+ self.lib_modules[modname] = fname
def detect_lib_modules_nix(self):
if self.static:
@@ -203,25 +323,32 @@ class BoostDependency(ExternalDependency):
else:
libdirs = [os.path.join(self.boost_root, 'lib')]
for libdir in libdirs:
+ for name in self.need_static_link:
+ libname = 'lib{}.a'.format(name)
+ if os.path.isfile(os.path.join(libdir, libname)):
+ self.lib_modules[name] = libname
for entry in glob.glob(os.path.join(libdir, globber)):
lib = os.path.basename(entry)
- name = lib.split('.')[0].split('_', 1)[-1]
+ name = lib.split('.')[0][3:]
# I'm not 100% sure what to do here. Some distros
# have modules such as thread only as -mt versions.
- if entry.endswith('-mt.{}'.format(libsuffix)):
- self.lib_modules_mt[name] = True
- else:
- self.lib_modules[name] = True
+ # On debian all packages are built threading=multi
+ # but not suffixed with -mt.
+ # FIXME: implement detect_lib_modules_{debian, redhat, ...}
+ if self.is_multithreading and mesonlib.is_debianlike():
+ self.lib_modules[name] = lib
+ elif self.is_multithreading and entry.endswith('-mt.{}'.format(libsuffix)):
+ self.lib_modules[name] = lib
+ elif not entry.endswith('-mt.{}'.format(libsuffix)):
+ self.lib_modules[name] = lib
def get_win_link_args(self):
args = []
# TODO: should this check self.libdir?
- if self.boost_root:
+ if self.libdir:
args.append('-L' + self.libdir)
- for module in self.requested_modules:
- module = BoostDependency.name2lib.get(module, module)
- if module in self.lib_modules_mt:
- args.append(self.lib_modules_mt[module])
+ for lib in self.requested_modules:
+ args.append(self.lib_modules['boost_' + lib])
return args
def get_link_args(self):
@@ -232,33 +359,14 @@ class BoostDependency(ExternalDependency):
args.append('-L' + os.path.join(self.boost_root, 'lib'))
elif self.libdir:
args.append('-L' + self.libdir)
- for module in self.requested_modules:
- module = BoostDependency.name2lib.get(module, module)
- libname = 'boost_' + module
+ for lib in self.requested_modules:
# The compiler's library detector is the most reliable so use that first.
- default_detect = self.compiler.find_library(libname, self.env, [])
+ default_detect = self.compiler.find_library('boost_' + lib, self.env, [])
if default_detect is not None:
- if module == 'unit_testing_framework':
- emon_args = self.compiler.find_library('boost_test_exec_monitor')
- else:
- emon_args = None
args += default_detect
- if emon_args is not None:
- args += emon_args
- elif module in self.lib_modules or module in self.lib_modules_mt:
- linkcmd = '-l' + libname
- args.append(linkcmd)
- # FIXME a hack, but Boost's testing framework has a lot of
- # different options and it's hard to determine what to do
- # without feedback from actual users. Update this
- # as we get more bug reports.
- if module == 'unit_testing_framework':
- args.append('-lboost_test_exec_monitor')
- elif module + '-mt' in self.lib_modules_mt:
- linkcmd = '-lboost_' + module + '-mt'
+ elif lib in self.lib_modules:
+ linkcmd = '-l' + lib
args.append(linkcmd)
- if module == 'unit_testing_framework':
- args.append('-lboost_test_exec_monitor-mt')
return args
def get_sources(self):
@@ -653,3 +761,78 @@ class CupsDependency(ExternalDependency):
return [DependencyMethods.PKGCONFIG, DependencyMethods.CUPSCONFIG, DependencyMethods.EXTRAFRAMEWORK]
else:
return [DependencyMethods.PKGCONFIG, DependencyMethods.CUPSCONFIG]
+
+# Generated with boost_names.py
+BOOST_LIBS = [
+ 'boost_atomic',
+ 'boost_chrono',
+ 'boost_chrono',
+ 'boost_container',
+ 'boost_context',
+ 'boost_coroutine',
+ 'boost_date_time',
+ 'boost_exception',
+ 'boost_fiber',
+ 'boost_filesystem',
+ 'boost_graph',
+ 'boost_iostreams',
+ 'boost_locale',
+ 'boost_log',
+ 'boost_log_setup',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_math_tr1',
+ 'boost_math_tr1f',
+ 'boost_math_tr1l',
+ 'boost_math_c99',
+ 'boost_math_c99f',
+ 'boost_math_c99l',
+ 'boost_mpi',
+ 'boost_random',
+ 'boost_regex',
+ 'boost_serialization',
+ 'boost_wserialization',
+ 'boost_signals',
+ 'boost_stacktrace_noop',
+ 'boost_stacktrace_backtrace',
+ 'boost_stacktrace_addr2line',
+ 'boost_stacktrace_basic',
+ 'boost_stacktrace_windbg',
+ 'boost_stacktrace_windbg_cached',
+ 'boost_system',
+ 'boost_prg_exec_monitor',
+ 'boost_test_exec_monitor',
+ 'boost_unit_test_framework',
+ 'boost_thread',
+ 'boost_timer',
+ 'boost_type_erasure',
+ 'boost_wave'
+]
diff --git a/test cases/frameworks/1 boost/meson.build b/test cases/frameworks/1 boost/meson.build
index 6f25f8b..b73f93a 100644
--- a/test cases/frameworks/1 boost/meson.build
+++ b/test cases/frameworks/1 boost/meson.build
@@ -9,21 +9,18 @@ add_project_arguments(['-DBOOST_LOG_DYN_LINK'],
# within one project. The need to be independent of each other.
# Use one without a library dependency and one with it.
-nolinkdep = dependency('boost', modules: 'utility')
linkdep = dependency('boost', modules : ['thread', 'system'])
staticdep = dependency('boost', modules : ['thread', 'system'], static : true)
-testdep = dependency('boost', modules : 'test')
+testdep = dependency('boost', modules : ['unit_test_framework'])
nomoddep = dependency('boost')
extralibdep = dependency('boost', modules : ['thread', 'system', 'log_setup', 'log'])
-nolinkexe = executable('nolinkedexe', 'nolinkexe.cc', dependencies : nolinkdep)
linkexe = executable('linkedexe', 'linkexe.cc', dependencies : linkdep)
staticexe = executable('staticlinkedexe', 'linkexe.cc', dependencies : staticdep)
unitexe = executable('utf', 'unit_test.cpp', dependencies: testdep)
nomodexe = executable('nomod', 'nomod.cpp', dependencies : nomoddep)
extralibexe = executable('extralibexe', 'extralib.cpp', dependencies : extralibdep)
-test('Boost nolinktest', nolinkexe)
test('Boost linktest', linkexe)
test('Boost statictest', staticexe)
test('Boost UTF test', unitexe)
diff --git a/test cases/frameworks/1 boost/nolinkexe.cc b/test cases/frameworks/1 boost/nolinkexe.cc
deleted file mode 100644
index 7b6c6d9..0000000
--- a/test cases/frameworks/1 boost/nolinkexe.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-#include<boost/utility.hpp>
-
-class MyClass : boost::noncopyable {
-public:
- MyClass() {};
- ~MyClass() {};
-};
-
-int main(int argc, char **argv) {
- MyClass obj;
- return 0;
-}
diff --git a/tools/boost_names.py b/tools/boost_names.py
new file mode 100755
index 0000000..9ac16bb
--- /dev/null
+++ b/tools/boost_names.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+
+# Copyright 2017 Niklas Claesson
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""This is two implementations for how to get module names from the boost
+sources. One relies on json metadata files in the sources, the other relies on
+the folder names.
+
+Run the tool in the boost directory and append the stdout to the misc.py:
+
+boost/$ path/to/meson/tools/boost_names.py >> path/to/meson/dependencies/misc.py
+"""
+
+import sys
+import os
+import collections
+import pprint
+import json
+import re
+
+Module = collections.namedtuple('Module', ['dirname', 'name', 'libnames'])
+Module.__repr__ = lambda self: str((self.dirname, self.name, self.libnames))
+
+LIBS = 'libs'
+
+manual_map = {
+ 'callable_traits': 'Call Traits',
+ 'crc': 'CRC',
+ 'dll': 'DLL',
+ 'gil': 'GIL',
+ 'graph_parallel': 'GraphParallel',
+ 'icl': 'ICL',
+ 'io': 'IO State Savers',
+ 'msm': 'Meta State Machine',
+ 'mpi': 'MPI',
+ 'mpl': 'MPL',
+ 'multi_array': 'Multi-Array',
+ 'multi_index': 'Multi-Index',
+ 'numeric': 'Numeric Conversion',
+ 'ptr_container': 'Pointer Container',
+ 'poly_collection': 'PolyCollection',
+ 'qvm': 'QVM',
+ 'throw_exception': 'ThrowException',
+ 'tti': 'TTI',
+ 'vmd': 'VMD',
+}
+
+extra = [
+ Module('utility', 'Compressed Pair', []),
+ Module('core', 'Enable If', []),
+ Module('functional', 'Functional/Factory', []),
+ Module('functional', 'Functional/Forward', []),
+ Module('functional', 'Functional/Hash', []),
+ Module('functional', 'Functional/Overloaded Function', []),
+ Module('utility', 'Identity Type', []),
+ Module('utility', 'In Place Factory, Typed In Place Factory', []),
+ Module('numeric', 'Interval', []),
+ Module('math', 'Math Common Factor', []),
+ Module('math', 'Math Octonion', []),
+ Module('math', 'Math Quaternion', []),
+ Module('math', 'Math/Special Functions', []),
+ Module('math', 'Math/Statistical Distributions', []),
+ Module('bind', 'Member Function', []),
+ Module('algorithm', 'Min-Max', []),
+ Module('numeric', 'Odeint', []),
+ Module('utility', 'Operators', []),
+ Module('core', 'Ref', []),
+ Module('utility', 'Result Of', []),
+ Module('algorithm', 'String Algo', []),
+ Module('core', 'Swap', []),
+ Module('', 'Tribool', []),
+ Module('numeric', 'uBLAS', []),
+ Module('utility', 'Value Initialized', []),
+]
+
+# Cannot find the following modules in the documentation of boost
+not_modules = ['beast', 'logic', 'mp11', 'winapi']
+
+def eprint(message):
+ print(message, file=sys.stderr)
+
+def get_library_names(jamfile):
+ libs = []
+ with open(jamfile) as jamfh:
+ jam = jamfh.read()
+ res = re.finditer(r'^lib[\s]+([A-Za-z0-9_]+)([^;]*);', jam, re.MULTILINE | re.DOTALL)
+ for matches in res:
+ if ':' in matches.group(2):
+ libs.append(matches.group(1))
+ return libs
+
+def exists(modules, module):
+ return len([x for x in modules if x.dirname == module.dirname]) != 0
+
+def get_modules(init=extra):
+ modules = init
+ for directory in os.listdir(LIBS):
+ if not os.path.isdir(os.path.join(LIBS, directory)):
+ continue
+ if directory in not_modules:
+ continue
+ jamfile = os.path.join(LIBS, directory, 'build', 'Jamfile.v2')
+ if os.path.isfile(jamfile):
+ libs = get_library_names(jamfile)
+ else:
+ libs = []
+ if directory in manual_map.keys():
+ modname = manual_map[directory]
+ else:
+ modname = directory.replace('_', ' ').title()
+ modules.append(Module(directory, modname, libs))
+ return modules
+
+def get_modules_2():
+ modules = []
+ for (root, dirs, files) in os.walk(LIBS):
+ for f in files:
+ if f == "libraries.json":
+ projectdir = os.path.dirname(root)
+
+ jamfile = os.path.join(projectdir, 'build', 'Jamfile.v2')
+ if os.path.isfile(jamfile):
+ libs = get_library_names(jamfile)
+ else:
+ libs = []
+
+ # Get metadata for module
+ jsonfile = os.path.join(root, f)
+ with open(jsonfile) as jsonfh:
+ boost_modules = json.loads(jsonfh.read())
+ if(isinstance(boost_modules, dict)):
+ boost_modules = [boost_modules]
+ for boost_module in boost_modules:
+ modules.append(Module(boost_module['key'], boost_module['name'], libs))
+
+ # Some subprojects do not have meta directory with json file. Find those
+ jsonless_modules = [x for x in get_modules([]) if not exists(modules, x)]
+ for module in jsonless_modules:
+ eprint("WARNING: {} does not have meta/libraries.json. Will guess pretty name '{}'".format(module.dirname, module.name))
+ modules.extend(jsonless_modules)
+
+ return modules
+
+def main(args):
+ if not os.path.isdir(LIBS):
+ eprint("ERROR: script must be run in boost source directory")
+
+ # It will pick jsonless algorithm if 1 is given as argument
+ impl = 0
+ if len(args) > 1:
+ if args[1] == '1':
+ impl = 1
+
+ if impl == 1:
+ modules = get_modules()
+ else:
+ modules = get_modules_2()
+
+ sorted_modules = sorted(modules, key=lambda module: module.name.lower())
+ sorted_modules = [x[2] for x in sorted_modules if x[2]]
+ sorted_modules = sum(sorted_modules, [])
+ sorted_modules = [x for x in sorted_modules if x.startswith('boost')]
+
+ pp = pprint.PrettyPrinter()
+ pp.pprint(sorted_modules)
+
+if __name__ == '__main__':
+ main(sys.argv)