blob: 6b27bceed946bb2f3d24c3e3ec6925e5abf72733 [file] [log] [blame]
Alexander Afanasyev2aa39622014-01-22 11:51:11 -08001#!/usr/bin/env python
2# encoding: utf-8
3#
4# partially based on boost.py written by Gernot Vormayr
5# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
6# modified by Bjoern Michaelsen, 2008
7# modified by Luca Fossati, 2008
8# rewritten for waf 1.5.1, Thomas Nagy, 2008
9# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
10
11'''
12
13This is an extra tool, not bundled with the default waf binary.
14To add the boost tool to the waf file:
15$ ./waf-light --tools=compat15,boost
16 or, if you have waf >= 1.6.2
17$ ./waf update --files=boost
18
19When using this tool, the wscript will look like:
20
21 def options(opt):
22 opt.load('compiler_cxx boost')
23
24 def configure(conf):
25 conf.load('compiler_cxx boost')
26 conf.check_boost(lib='system filesystem')
27
28 def build(bld):
29 bld(source='main.cpp', target='app', use='BOOST')
30
31Options are generated, in order to specify the location of boost includes/libraries.
32The `check_boost` configuration function allows to specify the used boost libraries.
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080033It can also provide default arguments to the --boost-mt command-line arguments.
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080034Everything will be packaged together in a BOOST component that you can use.
35
36When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
37 - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
38 Errors: C4530
39 - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080040 So before calling `conf.check_boost` you might want to disabling by adding
41 conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
Alexander Afanasyeve1724c42014-02-26 22:00:54 -080042 Errors:
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080043 - boost might also be compiled with /MT, which links the runtime statically.
Alexander Afanasyeve1724c42014-02-26 22:00:54 -080044 If you have problems with redefined symbols,
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080045 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
46 self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
47Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.
48
49'''
50
51import sys
52import re
53from waflib import Utils, Logs, Errors
54from waflib.Configure import conf
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080055from waflib.TaskGen import feature, after_method
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080056
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080057BOOST_LIBS = ['/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu',
58 '/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
59BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080060BOOST_VERSION_FILE = 'boost/version.hpp'
61BOOST_VERSION_CODE = '''
62#include <iostream>
63#include <boost/version.hpp>
Alexander Afanasyeve1724c42014-02-26 22:00:54 -080064int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080065'''
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080066
67BOOST_ERROR_CODE = '''
Davide Pesavento1bdef282014-04-08 20:59:50 +020068#include <boost/system/error_code.hpp>
69int main() { boost::system::error_code c; }
70'''
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080071
Alexander Afanasyev85093982016-03-08 14:03:54 -080072PTHREAD_CODE = '''
73#include <pthread.h>
74int main() {
75 pthread_t th;
76 pthread_create(&th, 0, 0, 0);
77 pthread_join(th, 0);
78 pthread_attr_init(0); pthread_cleanup_push(0, 0);
79 pthread_create(0,0,0,0); pthread_cleanup_pop(0);
80}
81'''
82
Davide Pesavento1bdef282014-04-08 20:59:50 +020083BOOST_THREAD_CODE = '''
84#include <boost/thread.hpp>
85int main() { boost::thread t; }
86'''
Alexander Afanasyev2aa39622014-01-22 11:51:11 -080087
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -080088BOOST_LOG_CODE = '''
89#include <boost/log/trivial.hpp>
90#include <boost/log/utility/setup/console.hpp>
91#include <boost/log/utility/setup/common_attributes.hpp>
92int main() {
93 using namespace boost::log;
94 add_common_attributes();
95 add_console_log(std::clog, keywords::format = "%Message%");
96 BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
97}
98'''
99
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800100# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
101PLATFORM = Utils.unversioned_sys_platform()
102detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
103detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
104detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
105BOOST_TOOLSETS = {
106 'borland': 'bcb',
107 'clang': detect_clang,
108 'como': 'como',
109 'cw': 'cw',
110 'darwin': 'xgcc',
111 'edg': 'edg',
112 'g++': detect_mingw,
113 'gcc': detect_mingw,
114 'icpc': detect_intel,
115 'intel': detect_intel,
116 'kcc': 'kcc',
117 'kylix': 'bck',
118 'mipspro': 'mp',
119 'mingw': 'mgw',
120 'msvc': 'vc',
121 'qcc': 'qcc',
122 'sun': 'sw',
123 'sunc++': 'sw',
124 'tru64cxx': 'tru',
125 'vacpp': 'xlc'
126}
127
128
129def options(opt):
130 opt = opt.add_option_group('Boost Options')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800131 opt.add_option('--boost-includes', type='string',
132 default='', dest='boost_includes',
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800133 help='''path to the directory where the boost includes are,
134 e.g., /path/to/boost_1_55_0/stage/include''')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800135 opt.add_option('--boost-libs', type='string',
136 default='', dest='boost_libs',
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800137 help='''path to the directory where the boost libs are,
138 e.g., path/to/boost_1_55_0/stage/lib''')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800139 opt.add_option('--boost-mt', action='store_true',
140 default=False, dest='boost_mt',
141 help='select multi-threaded libraries')
142 opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800143 help='''select libraries with tags (gd for debug, static is automatically added),
144 see doc Boost, Getting Started, chapter 6.1''')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800145 opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
146 help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
147 opt.add_option('--boost-toolset', type='string',
148 default='', dest='boost_toolset',
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800149 help='force a toolset e.g. msvc, vc90, \
150 gcc, mingw, mgw45 (default: auto)')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800151 py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
152 opt.add_option('--boost-python', type='string',
153 default=py_version, dest='boost_python',
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800154 help='select the lib python with this version \
155 (default: %s)' % py_version)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800156
157
158@conf
159def __boost_get_version_file(self, d):
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800160 if not d:
161 return None
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800162 dnode = self.root.find_dir(d)
163 if dnode:
164 return dnode.find_node(BOOST_VERSION_FILE)
165 return None
166
167@conf
168def boost_get_version(self, d):
169 """silently retrieve the boost version number"""
170 node = self.__boost_get_version_file(d)
171 if node:
172 try:
173 txt = node.read()
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800174 except EnvironmentError:
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800175 Logs.error("Could not read the file %r" % node.abspath())
176 else:
Davide Pesavento1bdef282014-04-08 20:59:50 +0200177 re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800178 m1 = re_but1.search(txt)
Davide Pesavento1bdef282014-04-08 20:59:50 +0200179 re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800180 m2 = re_but2.search(txt)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800181 if m1 and m2:
182 return (m1.group(1), m2.group(1))
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800183 return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800184
185@conf
186def boost_get_includes(self, *k, **kw):
187 includes = k and k[0] or kw.get('includes', None)
188 if includes and self.__boost_get_version_file(includes):
189 return includes
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800190 for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800191 if self.__boost_get_version_file(d):
192 return d
193 if includes:
194 self.end_msg('headers not found in %s' % includes)
195 self.fatal('The configuration failed')
196 else:
197 self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
198 self.fatal('The configuration failed')
199
200
201@conf
202def boost_get_toolset(self, cc):
203 toolset = cc
204 if not cc:
205 build_platform = Utils.unversioned_sys_platform()
206 if build_platform in BOOST_TOOLSETS:
207 cc = build_platform
208 else:
209 cc = self.env.CXX_NAME
210 if cc in BOOST_TOOLSETS:
211 toolset = BOOST_TOOLSETS[cc]
212 return isinstance(toolset, str) and toolset or toolset(self.env)
213
214
215@conf
216def __boost_get_libs_path(self, *k, **kw):
217 ''' return the lib path and all the files in it '''
218 if 'files' in kw:
219 return self.root.find_dir('.'), Utils.to_list(kw['files'])
220 libs = k and k[0] or kw.get('libs', None)
221 if libs:
222 path = self.root.find_dir(libs)
223 files = path.ant_glob('*boost_*')
224 if not libs or not files:
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800225 for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
226 if not d:
227 continue
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800228 path = self.root.find_dir(d)
229 if path:
230 files = path.ant_glob('*boost_*')
231 if files:
232 break
233 path = self.root.find_dir(d + '64')
234 if path:
235 files = path.ant_glob('*boost_*')
236 if files:
237 break
238 if not path:
239 if libs:
240 self.end_msg('libs not found in %s' % libs)
241 self.fatal('The configuration failed')
242 else:
243 self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
244 self.fatal('The configuration failed')
245
246 self.to_log('Found the boost path in %r with the libraries:' % path)
247 for x in files:
248 self.to_log(' %r' % x)
249 return path, files
250
251@conf
252def boost_get_libs(self, *k, **kw):
253 '''
254 return the lib path and the required libs
255 according to the parameters
256 '''
257 path, files = self.__boost_get_libs_path(**kw)
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800258 files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800259 toolset = self.boost_get_toolset(kw.get('toolset', ''))
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800260 toolset_pat = '(-%s[0-9]{0,3})' % toolset
261 version = '-%s' % self.env.BOOST_VERSION
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800262
263 def find_lib(re_lib, files):
264 for file in files:
265 if re_lib.search(file.name):
266 self.to_log('Found boost lib %s' % file)
267 return file
268 return None
269
270 def format_lib_name(name):
271 if name.startswith('lib') and self.env.CC_NAME != 'msvc':
272 name = name[3:]
273 return name[:name.rfind('.')]
274
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800275 def match_libs(lib_names, is_static):
276 libs = []
277 lib_names = Utils.to_list(lib_names)
278 if not lib_names:
279 return libs
280 t = []
281 if kw.get('mt', False):
282 t.append('-mt')
283 if kw.get('abi', None):
284 t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
285 elif is_static:
286 t.append('-s')
287 tags_pat = t and ''.join(t) or ''
288 ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
289 ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800290
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800291 for lib in lib_names:
292 if lib == 'python':
293 # for instance, with python='27',
294 # accepts '-py27', '-py2', '27' and '2'
295 # but will reject '-py3', '-py26', '26' and '3'
296 tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
297 else:
298 tags = tags_pat
299 # Trying libraries, from most strict match to least one
300 for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
301 'boost_%s%s%s%s$' % (lib, tags, version, ext),
302 # Give up trying to find the right version
303 'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
304 'boost_%s%s%s$' % (lib, tags, ext),
305 'boost_%s%s$' % (lib, ext),
306 'boost_%s' % lib]:
307 self.to_log('Trying pattern %s' % pattern)
308 file = find_lib(re.compile(pattern), files)
309 if file:
310 libs.append(format_lib_name(file.name))
311 break
312 else:
313 self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
314 self.fatal('The configuration failed')
315 return libs
316
317 return path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800318
Alexander Afanasyev85093982016-03-08 14:03:54 -0800319@conf
320def _check_pthread_flag(self, *k, **kw):
321 '''
322 Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
323
324 Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
325 boost/thread.hpp will trigger a #error if -pthread isn't used:
326 boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
327 is not turned on. Please set the correct command line options for
328 threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
329
330 Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
331 '''
332
333 var = kw.get('uselib_store', 'BOOST')
334
335 self.start_msg('Checking the flags needed to use pthreads')
336
337 # The ordering *is* (sometimes) important. Some notes on the
338 # individual items follow:
339 # (none): in case threads are in libc; should be tried before -Kthread and
340 # other compiler flags to prevent continual compiler warnings
341 # -lpthreads: AIX (must check this before -lpthread)
342 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
343 # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
344 # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
345 # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
346 # -pthreads: Solaris/GCC
347 # -mthreads: MinGW32/GCC, Lynx/GCC
348 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
349 # doesn't hurt to check since this sometimes defines pthreads too;
350 # also defines -D_REENTRANT)
351 # ... -mt is also the pthreads flag for HP/aCC
352 # -lpthread: GNU Linux, etc.
353 # --thread-safe: KAI C++
354 if Utils.unversioned_sys_platform() == "sunos":
355 # On Solaris (at least, for some versions), libc contains stubbed
356 # (non-functional) versions of the pthreads routines, so link-based
357 # tests will erroneously succeed. (We need to link with -pthreads/-mt/
358 # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
359 # a function called by this macro, so we could check for that, but
360 # who knows whether they'll stub that too in a future libc.) So,
361 # we'll just look for -pthreads and -lpthread first:
362 boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
363 else:
364 boost_pthread_flags = ["-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
365 "-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
366
367 for boost_pthread_flag in boost_pthread_flags:
368 try:
369 self.env.stash()
370 self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
371 self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
372 self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
373
374 self.end_msg(boost_pthread_flag)
375 return
376 except self.errors.ConfigurationError:
377 self.env.revert()
378 self.end_msg('None')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800379
380@conf
381def check_boost(self, *k, **kw):
382 """
383 Initialize boost libraries to be used.
384
385 Keywords: you can pass the same parameters as with the command line (without "--boost-").
386 Note that the command line has the priority, and should preferably be used.
387 """
388 if not self.env['CXX']:
389 self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
390
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800391 params = {
392 'lib': k and k[0] or kw.get('lib', None),
393 'stlib': kw.get('stlib', None)
394 }
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800395 for key, value in self.options.__dict__.items():
396 if not key.startswith('boost_'):
397 continue
398 key = key[len('boost_'):]
399 params[key] = value and value or kw.get(key, '')
400
401 var = kw.get('uselib_store', 'BOOST')
402
403 self.start_msg('Checking boost includes')
404 self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
Alexander Afanasyeve1724c42014-02-26 22:00:54 -0800405 versions = self.boost_get_version(inc)
406 self.env.BOOST_VERSION = versions[0]
407 self.env.BOOST_VERSION_NUMBER = int(versions[1])
408 self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800409 int(versions[1]) / 100 % 1000,
410 int(versions[1]) % 100))
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800411 if Logs.verbose:
412 Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
413
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800414 if not params['lib'] and not params['stlib']:
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800415 return
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800416 if 'static' in kw or 'static' in params:
417 Logs.warn('boost: static parameter is deprecated, use stlib instead.')
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800418 self.start_msg('Checking boost libs')
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800419 path, libs, stlibs = self.boost_get_libs(**params)
420 self.env['LIBPATH_%s' % var] = [path]
421 self.env['STLIBPATH_%s' % var] = [path]
422 self.env['LIB_%s' % var] = libs
423 self.env['STLIB_%s' % var] = stlibs
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800424 self.end_msg('ok')
425 if Logs.verbose:
426 Logs.pprint('CYAN', ' path : %s' % path)
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800427 Logs.pprint('CYAN', ' shared libs : %s' % libs)
428 Logs.pprint('CYAN', ' static libs : %s' % stlibs)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800429
Alexander Afanasyev85093982016-03-08 14:03:54 -0800430 def has_shlib(lib):
431 return params['lib'] and lib in params['lib']
432 def has_stlib(lib):
433 return params['stlib'] and lib in params['stlib']
434 def has_lib(lib):
435 return has_shlib(lib) or has_stlib(lib)
436 if has_lib('thread'):
437 # not inside try_link to make check visible in the output
438 self._check_pthread_flag(k, kw)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800439
440 def try_link():
Alexander Afanasyev85093982016-03-08 14:03:54 -0800441 if has_lib('system'):
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800442 self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
Alexander Afanasyev85093982016-03-08 14:03:54 -0800443 if has_lib('thread'):
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800444 self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
Alexander Afanasyev85093982016-03-08 14:03:54 -0800445 if has_lib('log'):
446 if not has_lib('thread'):
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800447 self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
Alexander Afanasyev85093982016-03-08 14:03:54 -0800448 if has_shlib('log'):
449 self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800450 self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800451
452 if params.get('linkage_autodetect', False):
453 self.start_msg("Attempting to detect boost linkage flags")
454 toolset = self.boost_get_toolset(kw.get('toolset', ''))
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800455 if toolset in ('vc',):
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800456 # disable auto-linking feature, causing error LNK1181
457 # because the code wants to be linked against
458 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
459
460 # if no dlls are present, we guess the .lib files are not stubs
461 has_dlls = False
462 for x in Utils.listdir(path):
463 if x.endswith(self.env.cxxshlib_PATTERN % ''):
464 has_dlls = True
465 break
466 if not has_dlls:
467 self.env['STLIBPATH_%s' % var] = [path]
468 self.env['STLIB_%s' % var] = libs
469 del self.env['LIB_%s' % var]
470 del self.env['LIBPATH_%s' % var]
471
472 # we attempt to play with some known-to-work CXXFLAGS combinations
473 for cxxflags in (['/MD', '/EHsc'], []):
474 self.env.stash()
475 self.env["CXXFLAGS_%s" % var] += cxxflags
476 try:
477 try_link()
478 self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800479 exc = None
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800480 break
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800481 except Errors.ConfigurationError as e:
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800482 self.env.revert()
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800483 exc = e
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800484
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800485 if exc is not None:
486 self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
Alexander Afanasyev2aa39622014-01-22 11:51:11 -0800487 self.fatal('The configuration failed')
488 else:
489 self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
490 self.fatal('The configuration failed')
491 else:
492 self.start_msg('Checking for boost linkage')
493 try:
494 try_link()
495 except Errors.ConfigurationError as e:
496 self.end_msg("Could not link against boost libraries using supplied options")
497 self.fatal('The configuration failed')
498 self.end_msg('ok')
Alexander Afanasyeve6f0e912016-02-25 23:42:36 -0800499
500
501@feature('cxx')
502@after_method('apply_link')
503def install_boost(self):
504 if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
505 return
506 install_boost.done = True
507 inst_to = getattr(self, 'install_path', '${BINDIR}')
508 for lib in self.env.LIB_BOOST:
509 try:
510 file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
511 self.bld.install_files(inst_to, self.bld.root.find_node(file))
512 except:
513 continue
514install_boost.done = False