#!/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

'''

This is an extra tool, not bundled with the default waf binary.
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

When using this tool, 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')

	def build(bld):
		bld(source='main.cpp', target='app', use='BOOST')

Options are generated, in order to specify the location of boost includes/libraries.
The `check_boost` configuration function allows to specify the used boost libraries.
It can also provide default arguments to the --boost-mt command-line arguments.
Everything will be packaged together in a BOOST component that you can use.

When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
 - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
   Errors: C4530
 - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
   So before calling `conf.check_boost` you might want to disabling by adding
		conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
   Errors:
 - boost might also be compiled with /MT, which links the runtime statically.
   If you have problems with redefined symbols,
		self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
		self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.

'''

import sys
import re
from waflib import Utils, Logs, Errors
from waflib.Configure import conf
from waflib.TaskGen import feature, after_method

BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/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 << ":" << BOOST_VERSION << std::endl; }
'''

BOOST_ERROR_CODE = '''
#include <boost/system/error_code.hpp>
int main() { boost::system::error_code c; }
'''

PTHREAD_CODE = '''
#include <pthread.h>
static void* f(void*) { return 0; }
int main() {
	pthread_t th;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_create(&th, &attr, &f, 0);
	pthread_join(th, 0);
	pthread_cleanup_push(0, 0);
	pthread_cleanup_pop(0);
	pthread_attr_destroy(&attr);
}
'''

BOOST_THREAD_CODE = '''
#include <boost/thread.hpp>
int main() { boost::thread t; }
'''

BOOST_LOG_CODE = '''
#include <boost/log/trivial.hpp>
int main() { BOOST_LOG_TRIVIAL(info) << "boost_log is working"; }
'''

BOOST_LOG_SETUP_CODE = '''
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
int main() {
	using namespace boost::log;
	add_common_attributes();
	add_console_log(std::clog, keywords::format = "%Message%");
	BOOST_LOG_TRIVIAL(info) << "boost_log_setup is working";
}
'''

# 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 = opt.add_option_group('Boost Options')
	opt.add_option('--boost-includes', type='string',
				   default='', dest='boost_includes',
				   help='''path to the directory where the boost includes are,
				   e.g., /path/to/boost_1_55_0/stage/include''')
	opt.add_option('--boost-libs', type='string',
				   default='', dest='boost_libs',
				   help='''path to the directory where the boost libs are,
				   e.g., path/to/boost_1_55_0/stage/lib''')
	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 (gd for debug, static is automatically added),
				   see doc Boost, Getting Started, chapter 6.1''')
	opt.add_option('--boost-linkage_autodetect', action='store_true', dest='boost_linkage_autodetect',
				   help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
	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, d):
	if not d:
		return None
	dnode = self.root.find_dir(d)
	if dnode:
		return dnode.find_node(BOOST_VERSION_FILE)
	return None

@conf
def boost_get_version(self, d):
	"""silently retrieve the boost version number"""
	node = self.__boost_get_version_file(d)
	if node:
		try:
			txt = node.read()
		except EnvironmentError:
			Logs.error('Could not read the file %r' % node.abspath())
		else:
			re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
			m1 = re_but1.search(txt)
			re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
			m2 = re_but2.search(txt)
			if m1 and m2:
				return (m1.group(1), m2.group(1))
	return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(':')

@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 d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
		if self.__boost_get_version_file(d):
			return d
	if includes:
		self.end_msg('headers not found in %s' % includes, 'YELLOW')
		self.fatal('The configuration failed')
	else:
		self.end_msg('headers not found, please provide a --boost-includes argument (see help)', 'YELLOW')
		self.fatal('The configuration failed')


@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 d in self.environ.get('LIB', '').split(';') + BOOST_LIBS:
			if not d:
				continue
			path = self.root.find_dir(d)
			if path:
				files = path.ant_glob('*boost_*')
				if files:
					break
			path = self.root.find_dir(d + '64')
			if path:
				files = path.ant_glob('*boost_*')
				if files:
					break
	if not path:
		if libs:
			self.end_msg('libs not found in %s' % libs, 'YELLOW')
			self.fatal('The configuration failed')
		else:
			self.end_msg('libs not found, please provide a --boost-libs argument (see help)', 'YELLOW')
			self.fatal('The configuration failed')

	self.to_log('Found the boost path in %r with the libraries:' % path)
	for x in files:
		self.to_log('    %r' % x)
	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)
	files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
	toolset = self.boost_get_toolset(kw.get('toolset', ''))
	toolset_pat = '(-%s[0-9]{0,3})' % toolset
	version = '-%s' % self.env.BOOST_VERSION

	def find_lib(re_lib, files):
		for file in files:
			if re_lib.search(file.name):
				self.to_log('Found boost lib %s' % file)
				return file
		return None

	def format_lib_name(name):
		if name.startswith('lib') and self.env.CC_NAME != 'msvc':
			name = name[3:]
		return name[:name.rfind('.')]

	def match_libs(lib_names, is_static):
		libs = []
		lib_names = Utils.to_list(lib_names)
		if not lib_names:
			return libs
		t = []
		if kw.get('mt', False):
			t.append('-mt')
		if kw.get('abi', None):
			t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
		elif is_static:
			t.append('-s')
		tags_pat = t and ''.join(t) or ''
		ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
		ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN

		for lib in lib_names:
			if lib == 'python':
				# for instance, with python='27',
				# accepts '-py27', '-py2', '27' and '2'
				# but will reject '-py3', '-py26', '26' and '3'
				tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
			else:
				tags = tags_pat
			# Trying libraries, from most strict match to least one
			for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
							'boost_%s%s%s%s$' % (lib, tags, version, ext),
							# Give up trying to find the right version
							'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
							'boost_%s%s%s$' % (lib, tags, ext),
							'boost_%s%s$' % (lib, ext),
							'boost_%s' % lib]:
				self.to_log('Trying pattern %s' % pattern)
				file = find_lib(re.compile(pattern), files)
				if file:
					libs.append(format_lib_name(file.name))
					break
			else:
				self.end_msg('lib %s not found in %s' % (lib, path.abspath()), 'YELLOW')
				self.fatal('The configuration failed')
		return libs

	return  path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)

@conf
def _check_pthread_flag(self, *k, **kw):
	'''
	Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode

	Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
	boost/thread.hpp will trigger a #error if -pthread isn't used:
	  boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
	  is not turned on. Please set the correct command line options for
	  threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"

	Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
    '''

	var = kw.get('uselib_store', 'BOOST')

	self.start_msg('Checking the flags needed to use pthreads')

	# The ordering *is* (sometimes) important.  Some notes on the
	# individual items follow:
	# (none): in case threads are in libc; should be tried before -Kthread and
	#       other compiler flags to prevent continual compiler warnings
	# -lpthreads: AIX (must check this before -lpthread)
	# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
	# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
	# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
	# -pthreads: Solaris/GCC
	# -mthreads: MinGW32/GCC, Lynx/GCC
	# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
	#      doesn't hurt to check since this sometimes defines pthreads too;
	#      also defines -D_REENTRANT)
	#      ... -mt is also the pthreads flag for HP/aCC
	# -lpthread: GNU Linux, etc.
	# --thread-safe: KAI C++
	if Utils.unversioned_sys_platform() == 'sunos':
		# On Solaris (at least, for some versions), libc contains stubbed
		# (non-functional) versions of the pthreads routines, so link-based
		# tests will erroneously succeed.  (We need to link with -pthreads/-mt/
		# -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
		# a function called by this macro, so we could check for that, but
		# who knows whether they'll stub that too in a future libc.)  So,
		# we'll just look for -pthreads and -lpthread first:
		boost_pthread_flags = ['-pthreads', '-lpthread', '-mt', '-pthread']
	else:
		boost_pthread_flags = ['', '-lpthreads', '-Kthread', '-kthread', '-llthread', '-pthread',
							   '-pthreads', '-mthreads', '-lpthread', '--thread-safe', '-mt']

	for boost_pthread_flag in boost_pthread_flags:
		try:
			self.env.stash()
			self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
			self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
			self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False, quiet=True)
			self.end_msg(boost_pthread_flag)
			return
		except self.errors.ConfigurationError:
			self.env.revert()
	self.end_msg('none')

@conf
def check_boost(self, *k, **kw):
	"""
	Initialize boost libraries to be used.

	Keywords: you can pass the same parameters as with the command line (without "--boost-").
	Note that the command line has the priority, and should preferably be used.
	"""
	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),
		'stlib': kw.get('stlib', 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')

	if not self.env.DONE_FIND_BOOST_COMMON:
		self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
		if self.env.DPKG_ARCHITECTURE:
			deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
			BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())

		self.start_msg('Checking boost includes')
		self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
		versions = self.boost_get_version(inc)
		self.env.BOOST_VERSION = versions[0]
		self.env.BOOST_VERSION_NUMBER = int(versions[1])
		self.end_msg('%d.%d.%d' % (int(versions[1]) / 100000,
								   int(versions[1]) / 100 % 1000,
								   int(versions[1]) % 100))
		if Logs.verbose:
			Logs.pprint('CYAN', '	path : %s' % self.env['INCLUDES_%s' % var])

		self.env.DONE_FIND_BOOST_COMMON = True

	if not params['lib'] and not params['stlib']:
		return
	if 'static' in kw or 'static' in params:
		Logs.warn('boost: static parameter is deprecated, use stlib instead.')
	self.start_msg('Checking boost libs')
	path, libs, stlibs = self.boost_get_libs(**params)
	self.env['LIBPATH_%s' % var] = [path]
	self.env['STLIBPATH_%s' % var] = [path]
	self.env['LIB_%s' % var] = libs
	self.env['STLIB_%s' % var] = stlibs
	self.end_msg(' '.join(libs + stlibs))
	if Logs.verbose:
		Logs.pprint('CYAN', '	path : %s' % path)
		Logs.pprint('CYAN', '	shared libs : %s' % libs)
		Logs.pprint('CYAN', '	static libs : %s' % stlibs)

	def has_shlib(lib):
		return params['lib'] and lib in params['lib']
	def has_stlib(lib):
		return params['stlib'] and lib in params['stlib']
	def has_lib(lib):
		return has_shlib(lib) or has_stlib(lib)
	if has_lib('thread'):
		# not inside try_link to make check visible in the output
		self._check_pthread_flag(k, kw)

	def try_link():
		if has_lib('system'):
			self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
		if has_lib('thread'):
			self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
		if has_lib('log') or has_lib('log_setup'):
			if not has_lib('thread'):
				self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
			if has_shlib('log') or has_shlib('log_setup'):
				self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
			if has_lib('log_setup'):
				self.check_cxx(fragment=BOOST_LOG_SETUP_CODE, use=var, execute=False)
			else:
				self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False)

	if params.get('linkage_autodetect', False):
		self.start_msg('Attempting to detect boost linkage flags')
		toolset = self.boost_get_toolset(kw.get('toolset', ''))
		if toolset in ('vc',):
			# disable auto-linking feature, causing error LNK1181
			# because the code wants to be linked against
			self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']

			# if no dlls are present, we guess the .lib files are not stubs
			has_dlls = False
			for x in Utils.listdir(path):
				if x.endswith(self.env.cxxshlib_PATTERN % ''):
					has_dlls = True
					break
			if not has_dlls:
				self.env['STLIBPATH_%s' % var] = [path]
				self.env['STLIB_%s' % var] = libs
				del self.env['LIB_%s' % var]
				del self.env['LIBPATH_%s' % var]

			# we attempt to play with some known-to-work CXXFLAGS combinations
			for cxxflags in (['/MD', '/EHsc'], []):
				self.env.stash()
				self.env['CXXFLAGS_%s' % var] += cxxflags
				try:
					try_link()
					self.end_msg('ok: winning cxxflags combination: %s' % (self.env['CXXFLAGS_%s' % var]))
					exc = None
					break
				except Errors.ConfigurationError as e:
					self.env.revert()
					exc = e

			if exc is not None:
				self.end_msg('Could not auto-detect boost linking flags combination, you may report it to boost.py author', ex=exc)
				self.fatal('The configuration failed')
		else:
			self.end_msg('Boost linkage flags auto-detection not implemented (needed ?) for this toolchain')
			self.fatal('The configuration failed')
	else:
		self.start_msg('Checking for boost linkage')
		try:
			try_link()
		except Errors.ConfigurationError as e:
			self.end_msg('Could not link against boost libraries using supplied options', 'YELLOW')
			self.fatal('The configuration failed')
		self.end_msg('ok')


@feature('cxx')
@after_method('apply_link')
def install_boost(self):
	if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
		return
	install_boost.done = True
	inst_to = getattr(self, 'install_path', '${BINDIR}')
	for lib in self.env.LIB_BOOST:
		try:
			file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
			self.bld.install_files(inst_to, self.bld.root.find_node(file))
		except:
			continue
install_boost.done = False
