diff --git a/.waf-tools/boost.py b/.waf-tools/boost.py
index bb65d7c..d7e0107 100644
--- a/.waf-tools/boost.py
+++ b/.waf-tools/boost.py
@@ -405,8 +405,8 @@
 
 	self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
 	if self.env.DPKG_ARCHITECTURE:
-		deb_host_multiarch = Utils.subprocess.check_output([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH']).strip()
-		BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch)
+		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)
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index e690290..9e045c3 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -20,9 +20,9 @@
                       'The minimum supported gcc version is 5.3.0.')
         conf.flags = GccFlags()
     elif cxx == 'clang':
-        if ccver < (3, 5, 0):
+        if ccver < (3, 6, 0):
             errmsg = ('The version of clang you are using is too old.\n'
-                      'The minimum supported clang version is 3.5.0.')
+                      'The minimum supported clang version is 3.6.0.')
         conf.flags = ClangFlags()
     else:
         warnmsg = 'Note: %s compiler is unsupported' % cxx
@@ -129,6 +129,10 @@
     def getGeneralFlags(self, conf):
         flags = super(GccBasicFlags, self).getGeneralFlags(conf)
         flags['CXXFLAGS'] += ['-std=c++14']
+        if Utils.unversioned_sys_platform() == 'linux':
+            flags['LINKFLAGS'] += ['-fuse-ld=gold']
+        elif Utils.unversioned_sys_platform() == 'freebsd':
+            flags['LINKFLAGS'] += ['-fuse-ld=lld']
         return flags
 
     def getDebugFlags(self, conf):
@@ -145,7 +149,7 @@
                               '-Wno-error=maybe-uninitialized', # Bug #1615
                               '-Wno-unused-parameter',
                               ]
-        flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
+        flags['LINKFLAGS'] += ['-Wl,-O1']
         return flags
 
     def getOptimizedFlags(self, conf):
@@ -158,7 +162,7 @@
                               '-Wnon-virtual-dtor',
                               '-Wno-unused-parameter',
                               ]
-        flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
+        flags['LINKFLAGS'] += ['-Wl,-O1']
         return flags
 
 class GccFlags(GccBasicFlags):
@@ -179,6 +183,8 @@
             # Bug #4296
             flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
                                   ['-isystem', '/opt/local/include']] # for MacPorts
+        if Utils.unversioned_sys_platform() == 'freebsd':
+            flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']] # Bug #4790
         return flags
 
     def getDebugFlags(self, conf):
@@ -186,15 +192,13 @@
         flags['CXXFLAGS'] += ['-fcolor-diagnostics',
                               '-Wextra-semi',
                               '-Wundefined-func-template',
-                              '-Wno-error=deprecated-register',
-                              '-Wno-error=infinite-recursion', # Bug #3358
-                              '-Wno-error=keyword-macro', # Bug #3235
-                              '-Wno-error=unneeded-internal-declaration', # Bug #1588
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
         version = self.getCompilerVersion(conf)
         if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
             flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
+        if version < (6, 0, 0):
+            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
 
     def getOptimizedFlags(self, conf):
@@ -207,4 +211,6 @@
         version = self.getCompilerVersion(conf)
         if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
             flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
+        if version < (6, 0, 0):
+            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
diff --git a/.waf-tools/doxygen.py b/.waf-tools/doxygen.py
deleted file mode 100644
index 6d8066b..0000000
--- a/.waf-tools/doxygen.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#! /usr/bin/env python
-# encoding: UTF-8
-# Thomas Nagy 2008-2010 (ita)
-
-"""
-
-Doxygen support
-
-Variables passed to bld():
-* doxyfile -- the Doxyfile to use
-
-When using this tool, the wscript will look like:
-
-	def options(opt):
-		opt.load('doxygen')
-
-	def configure(conf):
-		conf.load('doxygen')
-		# check conf.env.DOXYGEN, if it is mandatory
-
-	def build(bld):
-		if bld.env.DOXYGEN:
-			bld(features="doxygen", doxyfile='Doxyfile', ...)
-
-        def doxygen(bld):
-		if bld.env.DOXYGEN:
-			bld(features="doxygen", doxyfile='Doxyfile', ...)
-"""
-
-from fnmatch import fnmatchcase
-import os, os.path, re, stat
-from waflib import Task, Utils, Node, Logs, Errors, Build
-from waflib.TaskGen import feature
-
-DOXY_STR = '"${DOXYGEN}" - '
-DOXY_FMTS = 'html latex man rft xml'.split()
-DOXY_FILE_PATTERNS = '*.' + ' *.'.join('''
-c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3
-inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx
-'''.split())
-
-re_rl = re.compile('\\\\\r*\n', re.MULTILINE)
-re_nl = re.compile('\r*\n', re.M)
-def parse_doxy(txt):
-	tbl = {}
-	txt   = re_rl.sub('', txt)
-	lines = re_nl.split(txt)
-	for x in lines:
-		x = x.strip()
-		if not x or x.startswith('#') or x.find('=') < 0:
-			continue
-		if x.find('+=') >= 0:
-			tmp = x.split('+=')
-			key = tmp[0].strip()
-			if key in tbl:
-				tbl[key] += ' ' + '+='.join(tmp[1:]).strip()
-			else:
-				tbl[key] = '+='.join(tmp[1:]).strip()
-		else:
-			tmp = x.split('=')
-			tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip()
-	return tbl
-
-class doxygen(Task.Task):
-	vars  = ['DOXYGEN', 'DOXYFLAGS']
-	color = 'BLUE'
-
-	def runnable_status(self):
-		'''
-		self.pars are populated in runnable_status - because this function is being
-		run *before* both self.pars "consumers" - scan() and run()
-
-		set output_dir (node) for the output
-		'''
-
-		for x in self.run_after:
-			if not x.hasrun:
-				return Task.ASK_LATER
-
-		if not getattr(self, 'pars', None):
-			txt = self.inputs[0].read()
-			self.pars = parse_doxy(txt)
-			if not self.pars.get('OUTPUT_DIRECTORY'):
-				self.pars['OUTPUT_DIRECTORY'] = self.inputs[0].parent.get_bld().abspath()
-
-			# Override with any parameters passed to the task generator
-			if getattr(self.generator, 'pars', None):
-				for k, v in self.generator.pars.items():
-					self.pars[k] = v
-
-			self.doxy_inputs = getattr(self, 'doxy_inputs', [])
-			if not self.pars.get('INPUT'):
-				self.doxy_inputs.append(self.inputs[0].parent)
-			else:
-				for i in self.pars.get('INPUT').split():
-					if os.path.isabs(i):
-						node = self.generator.bld.root.find_node(i)
-					else:
-						node = self.generator.path.find_node(i)
-					if not node:
-						self.generator.bld.fatal('Could not find the doxygen input %r' % i)
-					self.doxy_inputs.append(node)
-
-		if not getattr(self, 'output_dir', None):
-			bld = self.generator.bld
-			# First try to find an absolute path, then find or declare a relative path
-			self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY'])
-			if not self.output_dir:
-				self.output_dir = bld.path.find_or_declare(self.pars['OUTPUT_DIRECTORY'])
-
-		self.signature()
-		return Task.Task.runnable_status(self)
-
-	def scan(self):
-		exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split()
-		file_patterns = self.pars.get('FILE_PATTERNS','').split()
-		if not file_patterns:
-			file_patterns = DOXY_FILE_PATTERNS
-		if self.pars.get('RECURSIVE') == 'YES':
-			file_patterns = ["**/%s" % pattern for pattern in file_patterns]
-		nodes = []
-		names = []
-		for node in self.doxy_inputs:
-			if os.path.isdir(node.abspath()):
-				for m in node.ant_glob(incl=file_patterns, excl=exclude_patterns):
-					nodes.append(m)
-			else:
-				nodes.append(node)
-		return (nodes, names)
-
-	def run(self):
-		dct = self.pars.copy()
-		dct['INPUT'] = ' '.join(['"%s"' % x.abspath() for x in self.doxy_inputs])
-		code = '\n'.join(['%s = %s' % (x, dct[x]) for x in self.pars])
-		code = code.encode() # for python 3
-		#fmt = DOXY_STR % (self.inputs[0].parent.abspath())
-		cmd = Utils.subst_vars(DOXY_STR, self.env)
-		env = self.env.env or None
-		proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env, cwd=self.generator.bld.path.get_bld().abspath())
-		proc.communicate(code)
-		return proc.returncode
-
-	def post_run(self):
-		nodes = self.output_dir.ant_glob('**/*', quiet=True)
-		for x in nodes:
-			x.sig = Utils.h_file(x.abspath())
-		self.outputs += nodes
-		return Task.Task.post_run(self)
-
-class tar(Task.Task):
-	"quick tar creation"
-	run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}'
-	color   = 'RED'
-	after   = ['doxygen']
-	def runnable_status(self):
-		for x in getattr(self, 'input_tasks', []):
-			if not x.hasrun:
-				return Task.ASK_LATER
-
-		if not getattr(self, 'tar_done_adding', None):
-			# execute this only once
-			self.tar_done_adding = True
-			for x in getattr(self, 'input_tasks', []):
-				self.set_inputs(x.outputs)
-			if not self.inputs:
-				return Task.SKIP_ME
-		return Task.Task.runnable_status(self)
-
-	def __str__(self):
-		tgt_str = ' '.join([a.nice_path(self.env) for a in self.outputs])
-		return '%s: %s\n' % (self.__class__.__name__, tgt_str)
-
-@feature('doxygen')
-def process_doxy(self):
-	if not getattr(self, 'doxyfile', None):
-		self.generator.bld.fatal('no doxyfile??')
-
-	node = self.doxyfile
-	if not isinstance(node, Node.Node):
-		node = self.path.find_resource(node)
-	if not node:
-		raise ValueError('doxygen file not found')
-
-	# the task instance
-	dsk = self.create_task('doxygen', node)
-
-	if getattr(self, 'doxy_tar', None):
-		tsk = self.create_task('tar')
-		tsk.input_tasks = [dsk]
-		tsk.set_outputs(self.path.find_or_declare(self.doxy_tar))
-		if self.doxy_tar.endswith('bz2'):
-			tsk.env['TAROPTS'] = ['cjf']
-		elif self.doxy_tar.endswith('gz'):
-			tsk.env['TAROPTS'] = ['czf']
-		else:
-			tsk.env['TAROPTS'] = ['cf']
-
-def configure(conf):
-	'''
-	Check if doxygen and tar commands are present in the system
-
-	If the commands are present, then conf.env.DOXYGEN and conf.env.TAR
-	variables will be set. Detection can be controlled by setting DOXYGEN and
-	TAR environmental variables.
-	'''
-
-	conf.find_program('doxygen', var='DOXYGEN', mandatory=False)
-	conf.find_program('tar', var='TAR', mandatory=False)
-
-# doxygen docs
-from waflib.Build import BuildContext
-class doxy(BuildContext):
-    cmd = "doxygen"
-    fun = "doxygen"
