blob: d7e0107c77b5500cae03945e66a04e9894c221c3 [file] [log] [blame]
Junxiao Shi2222a612015-06-06 08:01:38 -07001#!/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
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050016 or, if you have waf >= 1.6.2
Junxiao Shi2222a612015-06-06 08:01:38 -070017$ ./waf update --files=boost
18
19When using this tool, the wscript will look like:
20
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050021 def options(opt):
22 opt.load('compiler_cxx boost')
Junxiao Shi2222a612015-06-06 08:01:38 -070023
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050024 def configure(conf):
25 conf.load('compiler_cxx boost')
26 conf.check_boost(lib='system filesystem')
Junxiao Shi2222a612015-06-06 08:01:38 -070027
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050028 def build(bld):
29 bld(source='main.cpp', target='app', use='BOOST')
Junxiao Shi2222a612015-06-06 08:01:38 -070030
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 Afanasyev20c85cb2018-03-09 17:50:14 -050033It can also provide default arguments to the --boost-mt command-line arguments.
Junxiao Shi2222a612015-06-06 08:01:38 -070034Everything 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 Afanasyev20c85cb2018-03-09 17:50:14 -050040 So before calling `conf.check_boost` you might want to disabling by adding
41 conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
Junxiao Shi2222a612015-06-06 08:01:38 -070042 Errors:
43 - boost might also be compiled with /MT, which links the runtime statically.
44 If you have problems with redefined symbols,
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050045 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
46 self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
Junxiao Shi2222a612015-06-06 08:01:38 -070047Passing `--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 Afanasyev20c85cb2018-03-09 17:50:14 -050055from waflib.TaskGen import feature, after_method
Junxiao Shi2222a612015-06-06 08:01:38 -070056
Eric Newberry5820ed32018-04-05 21:59:52 -070057BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050058BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
Junxiao Shi2222a612015-06-06 08:01:38 -070059BOOST_VERSION_FILE = 'boost/version.hpp'
60BOOST_VERSION_CODE = '''
61#include <iostream>
62#include <boost/version.hpp>
63int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
64'''
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050065
66BOOST_ERROR_CODE = '''
Junxiao Shi2222a612015-06-06 08:01:38 -070067#include <boost/system/error_code.hpp>
68int main() { boost::system::error_code c; }
69'''
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050070
71PTHREAD_CODE = '''
72#include <pthread.h>
73static void* f(void*) { return 0; }
74int main() {
75 pthread_t th;
76 pthread_attr_t attr;
77 pthread_attr_init(&attr);
78 pthread_create(&th, &attr, &f, 0);
79 pthread_join(th, 0);
80 pthread_cleanup_push(0, 0);
81 pthread_cleanup_pop(0);
82 pthread_attr_destroy(&attr);
83}
84'''
85
Junxiao Shi2222a612015-06-06 08:01:38 -070086BOOST_THREAD_CODE = '''
87#include <boost/thread.hpp>
88int main() { boost::thread t; }
89'''
90
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -050091BOOST_LOG_CODE = '''
92#include <boost/log/trivial.hpp>
93#include <boost/log/utility/setup/console.hpp>
94#include <boost/log/utility/setup/common_attributes.hpp>
95int main() {
96 using namespace boost::log;
97 add_common_attributes();
98 add_console_log(std::clog, keywords::format = "%Message%");
99 BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl;
100}
101'''
102
Junxiao Shi2222a612015-06-06 08:01:38 -0700103# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
104PLATFORM = Utils.unversioned_sys_platform()
105detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
106detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
107detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
108BOOST_TOOLSETS = {
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500109 'borland': 'bcb',
110 'clang': detect_clang,
111 'como': 'como',
112 'cw': 'cw',
113 'darwin': 'xgcc',
114 'edg': 'edg',
115 'g++': detect_mingw,
116 'gcc': detect_mingw,
117 'icpc': detect_intel,
118 'intel': detect_intel,
119 'kcc': 'kcc',
120 'kylix': 'bck',
121 'mipspro': 'mp',
122 'mingw': 'mgw',
123 'msvc': 'vc',
124 'qcc': 'qcc',
125 'sun': 'sw',
126 'sunc++': 'sw',
127 'tru64cxx': 'tru',
128 'vacpp': 'xlc'
Junxiao Shi2222a612015-06-06 08:01:38 -0700129}
130
131
132def options(opt):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500133 opt = opt.add_option_group('Boost Options')
134 opt.add_option('--boost-includes', type='string',
135 default='', dest='boost_includes',
136 help='''path to the directory where the boost includes are,
137 e.g., /path/to/boost_1_55_0/stage/include''')
138 opt.add_option('--boost-libs', type='string',
139 default='', dest='boost_libs',
140 help='''path to the directory where the boost libs are,
141 e.g., path/to/boost_1_55_0/stage/lib''')
142 opt.add_option('--boost-mt', action='store_true',
143 default=False, dest='boost_mt',
144 help='select multi-threaded libraries')
145 opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
146 help='''select libraries with tags (gd for debug, static is automatically added),
147 see doc Boost, Getting Started, chapter 6.1''')
148 opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
149 help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
150 opt.add_option('--boost-toolset', type='string',
151 default='', dest='boost_toolset',
152 help='force a toolset e.g. msvc, vc90, \
153 gcc, mingw, mgw45 (default: auto)')
154 py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
155 opt.add_option('--boost-python', type='string',
156 default=py_version, dest='boost_python',
157 help='select the lib python with this version \
158 (default: %s)' % py_version)
Junxiao Shi2222a612015-06-06 08:01:38 -0700159
160
161@conf
162def __boost_get_version_file(self, d):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500163 if not d:
164 return None
165 dnode = self.root.find_dir(d)
166 if dnode:
167 return dnode.find_node(BOOST_VERSION_FILE)
168 return None
Junxiao Shi2222a612015-06-06 08:01:38 -0700169
170@conf
171def boost_get_version(self, d):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500172 """silently retrieve the boost version number"""
173 node = self.__boost_get_version_file(d)
174 if node:
175 try:
176 txt = node.read()
177 except EnvironmentError:
178 Logs.error("Could not read the file %r" % node.abspath())
179 else:
180 re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
181 m1 = re_but1.search(txt)
182 re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
183 m2 = re_but2.search(txt)
184 if m1 and m2:
185 return (m1.group(1), m2.group(1))
186 return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
Junxiao Shi2222a612015-06-06 08:01:38 -0700187
188@conf
189def boost_get_includes(self, *k, **kw):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500190 includes = k and k[0] or kw.get('includes', None)
191 if includes and self.__boost_get_version_file(includes):
192 return includes
193 for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
194 if self.__boost_get_version_file(d):
195 return d
196 if includes:
197 self.end_msg('headers not found in %s' % includes)
198 self.fatal('The configuration failed')
199 else:
200 self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
201 self.fatal('The configuration failed')
Junxiao Shi2222a612015-06-06 08:01:38 -0700202
203
204@conf
205def boost_get_toolset(self, cc):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500206 toolset = cc
207 if not cc:
208 build_platform = Utils.unversioned_sys_platform()
209 if build_platform in BOOST_TOOLSETS:
210 cc = build_platform
211 else:
212 cc = self.env.CXX_NAME
213 if cc in BOOST_TOOLSETS:
214 toolset = BOOST_TOOLSETS[cc]
215 return isinstance(toolset, str) and toolset or toolset(self.env)
Junxiao Shi2222a612015-06-06 08:01:38 -0700216
217
218@conf
219def __boost_get_libs_path(self, *k, **kw):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500220 ''' return the lib path and all the files in it '''
221 if 'files' in kw:
222 return self.root.find_dir('.'), Utils.to_list(kw['files'])
223 libs = k and k[0] or kw.get('libs', None)
224 if libs:
225 path = self.root.find_dir(libs)
226 files = path.ant_glob('*boost_*')
227 if not libs or not files:
228 for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
229 if not d:
230 continue
231 path = self.root.find_dir(d)
232 if path:
233 files = path.ant_glob('*boost_*')
234 if files:
235 break
236 path = self.root.find_dir(d + '64')
237 if path:
238 files = path.ant_glob('*boost_*')
239 if files:
240 break
241 if not path:
242 if libs:
243 self.end_msg('libs not found in %s' % libs)
244 self.fatal('The configuration failed')
245 else:
246 self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
247 self.fatal('The configuration failed')
Junxiao Shi2222a612015-06-06 08:01:38 -0700248
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500249 self.to_log('Found the boost path in %r with the libraries:' % path)
250 for x in files:
251 self.to_log(' %r' % x)
252 return path, files
Junxiao Shi2222a612015-06-06 08:01:38 -0700253
254@conf
255def boost_get_libs(self, *k, **kw):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500256 '''
257 return the lib path and the required libs
258 according to the parameters
259 '''
260 path, files = self.__boost_get_libs_path(**kw)
261 files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
262 toolset = self.boost_get_toolset(kw.get('toolset', ''))
263 toolset_pat = '(-%s[0-9]{0,3})' % toolset
264 version = '-%s' % self.env.BOOST_VERSION
265
266 def find_lib(re_lib, files):
267 for file in files:
268 if re_lib.search(file.name):
269 self.to_log('Found boost lib %s' % file)
270 return file
271 return None
272
273 def format_lib_name(name):
274 if name.startswith('lib') and self.env.CC_NAME != 'msvc':
275 name = name[3:]
276 return name[:name.rfind('.')]
277
278 def match_libs(lib_names, is_static):
279 libs = []
280 lib_names = Utils.to_list(lib_names)
281 if not lib_names:
282 return libs
283 t = []
284 if kw.get('mt', False):
285 t.append('-mt')
286 if kw.get('abi', None):
287 t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
288 elif is_static:
289 t.append('-s')
290 tags_pat = t and ''.join(t) or ''
291 ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
292 ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
293
294 for lib in lib_names:
295 if lib == 'python':
296 # for instance, with python='27',
297 # accepts '-py27', '-py2', '27' and '2'
298 # but will reject '-py3', '-py26', '26' and '3'
299 tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
300 else:
301 tags = tags_pat
302 # Trying libraries, from most strict match to least one
303 for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
304 'boost_%s%s%s%s$' % (lib, tags, version, ext),
305 # Give up trying to find the right version
306 'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
307 'boost_%s%s%s$' % (lib, tags, ext),
308 'boost_%s%s$' % (lib, ext),
309 'boost_%s' % lib]:
310 self.to_log('Trying pattern %s' % pattern)
311 file = find_lib(re.compile(pattern), files)
312 if file:
313 libs.append(format_lib_name(file.name))
314 break
315 else:
316 self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
317 self.fatal('The configuration failed')
318 return libs
319
320 return path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
321
322@conf
323def _check_pthread_flag(self, *k, **kw):
324 '''
325 Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
326
327 Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
328 boost/thread.hpp will trigger a #error if -pthread isn't used:
329 boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
330 is not turned on. Please set the correct command line options for
331 threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
332
333 Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
Junxiao Shi2222a612015-06-06 08:01:38 -0700334 '''
Junxiao Shi2222a612015-06-06 08:01:38 -0700335
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500336 var = kw.get('uselib_store', 'BOOST')
Junxiao Shi2222a612015-06-06 08:01:38 -0700337
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500338 self.start_msg('Checking the flags needed to use pthreads')
Junxiao Shi2222a612015-06-06 08:01:38 -0700339
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500340 # The ordering *is* (sometimes) important. Some notes on the
341 # individual items follow:
342 # (none): in case threads are in libc; should be tried before -Kthread and
343 # other compiler flags to prevent continual compiler warnings
344 # -lpthreads: AIX (must check this before -lpthread)
345 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
346 # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
347 # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
348 # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
349 # -pthreads: Solaris/GCC
350 # -mthreads: MinGW32/GCC, Lynx/GCC
351 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
352 # doesn't hurt to check since this sometimes defines pthreads too;
353 # also defines -D_REENTRANT)
354 # ... -mt is also the pthreads flag for HP/aCC
355 # -lpthread: GNU Linux, etc.
356 # --thread-safe: KAI C++
357 if Utils.unversioned_sys_platform() == "sunos":
358 # On Solaris (at least, for some versions), libc contains stubbed
359 # (non-functional) versions of the pthreads routines, so link-based
360 # tests will erroneously succeed. (We need to link with -pthreads/-mt/
361 # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
362 # a function called by this macro, so we could check for that, but
363 # who knows whether they'll stub that too in a future libc.) So,
364 # we'll just look for -pthreads and -lpthread first:
365 boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
366 else:
367 boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
368 "-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
Junxiao Shi2222a612015-06-06 08:01:38 -0700369
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500370 for boost_pthread_flag in boost_pthread_flags:
371 try:
372 self.env.stash()
373 self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
374 self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
375 self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
Junxiao Shi2222a612015-06-06 08:01:38 -0700376
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500377 self.end_msg(boost_pthread_flag)
378 return
379 except self.errors.ConfigurationError:
380 self.env.revert()
381 self.end_msg('None')
Junxiao Shi2222a612015-06-06 08:01:38 -0700382
383@conf
384def check_boost(self, *k, **kw):
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500385 """
386 Initialize boost libraries to be used.
Junxiao Shi2222a612015-06-06 08:01:38 -0700387
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500388 Keywords: you can pass the same parameters as with the command line (without "--boost-").
389 Note that the command line has the priority, and should preferably be used.
390 """
391 if not self.env['CXX']:
392 self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
Junxiao Shi2222a612015-06-06 08:01:38 -0700393
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500394 params = {
395 'lib': k and k[0] or kw.get('lib', None),
396 'stlib': kw.get('stlib', None)
397 }
398 for key, value in self.options.__dict__.items():
399 if not key.startswith('boost_'):
400 continue
401 key = key[len('boost_'):]
402 params[key] = value and value or kw.get(key, '')
Junxiao Shi2222a612015-06-06 08:01:38 -0700403
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500404 var = kw.get('uselib_store', 'BOOST')
Junxiao Shi2222a612015-06-06 08:01:38 -0700405
Eric Newberry5820ed32018-04-05 21:59:52 -0700406 self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
407 if self.env.DPKG_ARCHITECTURE:
408 deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
409 BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
410
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500411 self.start_msg('Checking boost includes')
412 self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
413 versions = self.boost_get_version(inc)
414 self.env.BOOST_VERSION = versions[0]
415 self.env.BOOST_VERSION_NUMBER = int(versions[1])
416 self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
417 int(versions[1]) / 100 % 1000,
418 int(versions[1]) % 100))
419 if Logs.verbose:
420 Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
Junxiao Shi2222a612015-06-06 08:01:38 -0700421
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500422 if not params['lib'] and not params['stlib']:
423 return
424 if 'static' in kw or 'static' in params:
425 Logs.warn('boost: static parameter is deprecated, use stlib instead.')
426 self.start_msg('Checking boost libs')
427 path, libs, stlibs = self.boost_get_libs(**params)
428 self.env['LIBPATH_%s' % var] = [path]
429 self.env['STLIBPATH_%s' % var] = [path]
430 self.env['LIB_%s' % var] = libs
431 self.env['STLIB_%s' % var] = stlibs
432 self.end_msg('ok')
433 if Logs.verbose:
434 Logs.pprint('CYAN', ' path : %s' % path)
435 Logs.pprint('CYAN', ' shared libs : %s' % libs)
436 Logs.pprint('CYAN', ' static libs : %s' % stlibs)
437
438 def has_shlib(lib):
439 return params['lib'] and lib in params['lib']
440 def has_stlib(lib):
441 return params['stlib'] and lib in params['stlib']
442 def has_lib(lib):
443 return has_shlib(lib) or has_stlib(lib)
444 if has_lib('thread'):
445 # not inside try_link to make check visible in the output
446 self._check_pthread_flag(k, kw)
447
448 def try_link():
449 if has_lib('system'):
450 self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
451 if has_lib('thread'):
452 self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
453 if has_lib('log'):
454 if not has_lib('thread'):
455 self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
456 if has_shlib('log'):
457 self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
458 self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)
459
460 if params.get('linkage_autodetect', False):
461 self.start_msg("Attempting to detect boost linkage flags")
462 toolset = self.boost_get_toolset(kw.get('toolset', ''))
463 if toolset in ('vc',):
464 # disable auto-linking feature, causing error LNK1181
465 # because the code wants to be linked against
466 self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
467
468 # if no dlls are present, we guess the .lib files are not stubs
469 has_dlls = False
470 for x in Utils.listdir(path):
471 if x.endswith(self.env.cxxshlib_PATTERN % ''):
472 has_dlls = True
473 break
474 if not has_dlls:
475 self.env['STLIBPATH_%s' % var] = [path]
476 self.env['STLIB_%s' % var] = libs
477 del self.env['LIB_%s' % var]
478 del self.env['LIBPATH_%s' % var]
479
480 # we attempt to play with some known-to-work CXXFLAGS combinations
481 for cxxflags in (['/MD', '/EHsc'], []):
482 self.env.stash()
483 self.env["CXXFLAGS_%s" % var] += cxxflags
484 try:
485 try_link()
486 self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
487 exc = None
488 break
489 except Errors.ConfigurationError as e:
490 self.env.revert()
491 exc = e
492
493 if exc is not None:
494 self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc)
495 self.fatal('The configuration failed')
496 else:
497 self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
498 self.fatal('The configuration failed')
499 else:
500 self.start_msg('Checking for boost linkage')
501 try:
502 try_link()
503 except Errors.ConfigurationError as e:
504 self.end_msg("Could not link against boost libraries using supplied options")
505 self.fatal('The configuration failed')
506 self.end_msg('ok')
Junxiao Shi2222a612015-06-06 08:01:38 -0700507
508
Alexander Afanasyev20c85cb2018-03-09 17:50:14 -0500509@feature('cxx')
510@after_method('apply_link')
511def install_boost(self):
512 if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
513 return
514 install_boost.done = True
515 inst_to = getattr(self, 'install_path', '${BINDIR}')
516 for lib in self.env.LIB_BOOST:
517 try:
518 file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
519 self.bld.install_files(inst_to, self.bld.root.find_node(file))
520 except:
521 continue
522install_boost.done = False