[SCM] mpv/master: Update waf to 1.9.8

jcowgill at users.alioth.debian.org jcowgill at users.alioth.debian.org
Wed Jul 19 14:24:30 UTC 2017


The following commit has been merged in the master branch:
commit d874f294199b4b2fff266aeffa139d25e7ec5f8a
Author: James Cowgill <jcowgill at debian.org>
Date:   Wed Jul 19 11:19:52 2017 +0100

    Update waf to 1.9.8

diff --git a/debian/patches/03_waf.patch b/debian/patches/03_waf.patch
index 3141ba4..fe1e8de 100644
--- a/debian/patches/03_waf.patch
+++ b/debian/patches/03_waf.patch
@@ -4,15 +4,16 @@ Description: Provide waf and related scripts
 Origin: vendor
 Forwarded: not-needed
 Author: Alessandro Ghedini <ghedo at debian.org>
-Last-Update: 2014-11-28
+Author: James Cowgill <jcowgill at debian.org>
+Last-Update: 2017-07-19
 
 --- /dev/null
 +++ b/waf
 @@ -0,0 +1,166 @@
 +#!/usr/bin/env python
 +# encoding: ISO8859-1
-+# Thomas Nagy, 2005-2015
-+
++# Thomas Nagy, 2005-2016
++#
 +"""
 +Redistribution and use in source and binary forms, with or without
 +modification, are permitted provided that the following conditions
@@ -43,12 +44,12 @@ Last-Update: 2014-11-28
 +
 +import os, sys, inspect
 +
-+VERSION="1.8.12"
-+REVISION="f00e5b53f6bbeab1384a38c9cc5d51f7"
-+GIT="1427497785a594dedeaac09013db635791f068c4"
++VERSION="1.9.8"
++REVISION="17756245c4cc550633dacf3b08eec42a"
++GIT="a6109383bfb9e70f32efc3a9d189bf5a088140bf"
 +INSTALL=''
-+C1='#+'
-+C2='#)'
++C1='#/'
++C2='#-'
 +C3='#%'
 +cwd = os.getcwd()
 +join = os.path.join
@@ -177,7 +178,7 @@ Last-Update: 2014-11-28
 +
 --- /dev/null
 +++ b/waflib/Build.py
-@@ -0,0 +1,759 @@
+@@ -0,0 +1,785 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -187,17 +188,18 @@ Last-Update: 2014-11-28
 +	import cPickle
 +except ImportError:
 +	import pickle as cPickle
-+from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
-+import waflib.Node
++from waflib import Node,Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
 +CACHE_DIR='c4che'
 +CACHE_SUFFIX='_cache.py'
 +INSTALL=1337
 +UNINSTALL=-1337
-+SAVED_ATTRS='root node_deps raw_deps task_sigs'.split()
++SAVED_ATTRS='root node_sigs task_sigs imp_sigs raw_deps node_deps'.split()
 +CFG_FILES='cfg_files'
 +POST_AT_ONCE=0
 +POST_LAZY=1
-+POST_BOTH=2
++PROTOCOL=-1
++if sys.platform=='cli':
++	PROTOCOL=0
 +class BuildContext(Context.Context):
 +	'''executes the build'''
 +	cmd='build'
@@ -206,19 +208,20 @@ Last-Update: 2014-11-28
 +		super(BuildContext,self).__init__(**kw)
 +		self.is_install=0
 +		self.top_dir=kw.get('top_dir',Context.top_dir)
-+		self.run_dir=kw.get('run_dir',Context.run_dir)
-+		self.post_mode=POST_AT_ONCE
 +		self.out_dir=kw.get('out_dir',Context.out_dir)
-+		self.cache_dir=kw.get('cache_dir',None)
++		self.run_dir=kw.get('run_dir',Context.run_dir)
++		self.launch_dir=Context.launch_dir
++		self.post_mode=POST_LAZY
++		self.cache_dir=kw.get('cache_dir')
 +		if not self.cache_dir:
 +			self.cache_dir=os.path.join(self.out_dir,CACHE_DIR)
 +		self.all_envs={}
++		self.node_sigs={}
 +		self.task_sigs={}
++		self.imp_sigs={}
 +		self.node_deps={}
 +		self.raw_deps={}
-+		self.cache_dir_contents={}
 +		self.task_gen_cache_names={}
-+		self.launch_dir=Context.launch_dir
 +		self.jobs=Options.options.jobs
 +		self.targets=Options.options.targets
 +		self.keep=Options.options.keep
@@ -227,6 +230,9 @@ Last-Update: 2014-11-28
 +		self.current_group=0
 +		self.groups=[]
 +		self.group_names={}
++		for v in SAVED_ATTRS:
++			if not hasattr(self,v):
++				setattr(self,v,{})
 +	def get_variant_dir(self):
 +		if not self.variant:
 +			return self.out_dir
@@ -236,7 +242,7 @@ Last-Update: 2014-11-28
 +		kw['bld']=self
 +		ret=TaskGen.task_gen(*k,**kw)
 +		self.task_gen_cache_names={}
-+		self.add_to_group(ret,group=kw.get('group',None))
++		self.add_to_group(ret,group=kw.get('group'))
 +		return ret
 +	def rule(self,*k,**kw):
 +		def f(rule):
@@ -245,13 +251,7 @@ Last-Update: 2014-11-28
 +			return ret
 +		return f
 +	def __copy__(self):
-+		raise Errors.WafError('build contexts are not supposed to be copied')
-+	def install_files(self,*k,**kw):
-+		pass
-+	def install_as(self,*k,**kw):
-+		pass
-+	def symlink_as(self,*k,**kw):
-+		pass
++		raise Errors.WafError('build contexts cannot be copied')
 +	def load_envs(self):
 +		node=self.root.find_node(self.cache_dir)
 +		if not node:
@@ -265,12 +265,8 @@ Last-Update: 2014-11-28
 +			self.all_envs[name]=env
 +			for f in env[CFG_FILES]:
 +				newnode=self.root.find_resource(f)
-+				try:
-+					h=Utils.h_file(newnode.abspath())
-+				except(IOError,AttributeError):
-+					Logs.error('cannot find %r'%f)
-+					h=Utils.SIG_NIL
-+				newnode.sig=h
++				if not newnode or not newnode.exists():
++					raise Errors.WafError('Missing configuration file %r, reconfigure the project!'%f)
 +	def init_dirs(self):
 +		if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
 +			raise Errors.WafError('The project was not configured: run "waf configure" first!')
@@ -283,7 +279,7 @@ Last-Update: 2014-11-28
 +			self.load_envs()
 +		self.execute_build()
 +	def execute_build(self):
-+		Logs.info("Waf: Entering directory `%s'"%self.variant_dir)
++		Logs.info("Waf: Entering directory `%s'",self.variant_dir)
 +		self.recurse([self.run_dir])
 +		self.pre_build()
 +		self.timer=Utils.Timer()
@@ -291,10 +287,15 @@ Last-Update: 2014-11-28
 +			self.compile()
 +		finally:
 +			if self.progress_bar==1 and sys.stderr.isatty():
-+				c=len(self.returned_tasks)or 1
++				c=self.producer.processed or 1
 +				m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL)
 +				Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on})
-+			Logs.info("Waf: Leaving directory `%s'"%self.variant_dir)
++			Logs.info("Waf: Leaving directory `%s'",self.variant_dir)
++		try:
++			self.producer.bld=None
++			del self.producer
++		except AttributeError:
++			pass
 +		self.post_build()
 +	def restore(self):
 +		try:
@@ -302,28 +303,28 @@ Last-Update: 2014-11-28
 +		except EnvironmentError:
 +			pass
 +		else:
-+			if env['version']<Context.HEXVERSION:
-+				raise Errors.WafError('Version mismatch! reconfigure the project')
-+			for t in env['tools']:
++			if env.version<Context.HEXVERSION:
++				raise Errors.WafError('Project was configured with a different version of Waf, please reconfigure it')
++			for t in env.tools:
 +				self.setup(**t)
 +		dbfn=os.path.join(self.variant_dir,Context.DBFILE)
 +		try:
 +			data=Utils.readf(dbfn,'rb')
-+		except(IOError,EOFError):
-+			Logs.debug('build: Could not load the build cache %s (missing)'%dbfn)
++		except(EnvironmentError,EOFError):
++			Logs.debug('build: Could not load the build cache %s (missing)',dbfn)
 +		else:
 +			try:
-+				waflib.Node.pickle_lock.acquire()
-+				waflib.Node.Nod3=self.node_class
++				Node.pickle_lock.acquire()
++				Node.Nod3=self.node_class
 +				try:
 +					data=cPickle.loads(data)
 +				except Exception ,e:
-+					Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e))
++					Logs.debug('build: Could not pickle the build cache %s: %r',dbfn,e)
 +				else:
 +					for x in SAVED_ATTRS:
-+						setattr(self,x,data[x])
++						setattr(self,x,data.get(x,{}))
 +			finally:
-+				waflib.Node.pickle_lock.release()
++				Node.pickle_lock.release()
 +		self.init_dirs()
 +	def store(self):
 +		data={}
@@ -331,11 +332,11 @@ Last-Update: 2014-11-28
 +			data[x]=getattr(self,x)
 +		db=os.path.join(self.variant_dir,Context.DBFILE)
 +		try:
-+			waflib.Node.pickle_lock.acquire()
-+			waflib.Node.Nod3=self.node_class
-+			x=cPickle.dumps(data,-1)
++			Node.pickle_lock.acquire()
++			Node.Nod3=self.node_class
++			x=cPickle.dumps(data,PROTOCOL)
 +		finally:
-+			waflib.Node.pickle_lock.release()
++			Node.pickle_lock.release()
 +		Utils.writef(db+'.tmp',x,m='wb')
 +		try:
 +			st=os.stat(db)
@@ -349,7 +350,6 @@ Last-Update: 2014-11-28
 +		Logs.debug('build: compile()')
 +		self.producer=Runner.Parallel(self,self.jobs)
 +		self.producer.biter=self.get_build_iterator()
-+		self.returned_tasks=[]
 +		try:
 +			self.producer.start()
 +		except KeyboardInterrupt:
@@ -375,18 +375,20 @@ Last-Update: 2014-11-28
 +		self.all_envs[self.variant]=val
 +	env=property(get_env,set_env)
 +	def add_manual_dependency(self,path,value):
-+		if path is None:
-+			raise ValueError('Invalid input')
-+		if isinstance(path,waflib.Node.Node):
++		if not path:
++			raise ValueError('Invalid input path %r'%path)
++		if isinstance(path,Node.Node):
 +			node=path
 +		elif os.path.isabs(path):
 +			node=self.root.find_resource(path)
 +		else:
 +			node=self.path.find_resource(path)
++		if not node:
++			raise ValueError('Could not find the path %r'%path)
 +		if isinstance(value,list):
-+			self.deps_man[id(node)].extend(value)
++			self.deps_man[node].extend(value)
 +		else:
-+			self.deps_man[id(node)].append(value)
++			self.deps_man[node].append(value)
 +	def launch_node(self):
 +		try:
 +			return self.p_ln
@@ -409,9 +411,8 @@ Last-Update: 2014-11-28
 +			except KeyError:
 +				pass
 +		lst=[env[a]for a in vars_lst]
-+		ret=Utils.h_list(lst)
++		cache[idx]=ret=Utils.h_list(lst)
 +		Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
-+		cache[idx]=ret
 +		return ret
 +	def get_tgen_by_name(self,name):
 +		cache=self.task_gen_cache_names
@@ -426,20 +427,19 @@ Last-Update: 2014-11-28
 +			return cache[name]
 +		except KeyError:
 +			raise Errors.WafError('Could not find a task generator for the name %r'%name)
-+	def progress_line(self,state,total,col1,col2):
++	def progress_line(self,idx,total,col1,col2):
 +		if not sys.stderr.isatty():
 +			return''
 +		n=len(str(total))
 +		Utils.rot_idx+=1
 +		ind=Utils.rot_chr[Utils.rot_idx%4]
-+		pc=(100.*state)/total
-+		eta=str(self.timer)
-+		fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind)
-+		left=fs%(state,total,col1,pc,col2)
-+		right='][%s%s%s]'%(col1,eta,col2)
++		pc=(100.*idx)/total
++		fs="[%%%dd/%%d][%%s%%2d%%%%%%s][%s]["%(n,ind)
++		left=fs%(idx,total,col1,pc,col2)
++		right='][%s%s%s]'%(col1,self.timer,col2)
 +		cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
 +		if cols<7:cols=7
-+		ratio=((cols*state)//total)-1
++		ratio=((cols*idx)//total)-1
 +		bar=('='*ratio+'>').ljust(cols)
 +		msg=Logs.indicator%(left,bar,right)
 +		return msg
@@ -482,14 +482,14 @@ Last-Update: 2014-11-28
 +		return''
 +	def get_group_idx(self,tg):
 +		se=id(tg)
-+		for i in range(len(self.groups)):
-+			for t in self.groups[i]:
++		for i,tmp in enumerate(self.groups):
++			for t in tmp:
 +				if id(t)==se:
 +					return i
 +		return None
 +	def add_group(self,name=None,move=True):
 +		if name and name in self.group_names:
-+			Logs.error('add_group: name %s already present'%name)
++			raise Errors.WafError('add_group: name %s already present',name)
 +		g=[]
 +		self.group_names[name]=g
 +		self.groups.append(g)
@@ -498,8 +498,8 @@ Last-Update: 2014-11-28
 +	def set_group(self,idx):
 +		if isinstance(idx,str):
 +			g=self.group_names[idx]
-+			for i in range(len(self.groups)):
-+				if id(g)==id(self.groups[i]):
++			for i,tmp in enumerate(self.groups):
++				if id(g)==id(tmp):
 +					self.current_group=i
 +					break
 +		else:
@@ -557,7 +557,7 @@ Last-Update: 2014-11-28
 +				Logs.warn('Building from the build directory, forcing --targets=*')
 +				ln=self.srcnode
 +			elif not ln.is_child_of(self.srcnode):
-+				Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath()))
++				Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)',ln.abspath(),self.srcnode.abspath())
 +				ln=self.srcnode
 +			for tg in self.groups[self.cur]:
 +				try:
@@ -598,84 +598,151 @@ Last-Update: 2014-11-28
 +			yield tasks
 +		while 1:
 +			yield[]
++	def install_files(self,dest,files,**kw):
++		assert(dest)
++		tg=self(features='install_task',install_to=dest,install_from=files,**kw)
++		tg.dest=tg.install_to
++		tg.type='install_files'
++		if not kw.get('postpone',True):
++			tg.post()
++		return tg
++	def install_as(self,dest,srcfile,**kw):
++		assert(dest)
++		tg=self(features='install_task',install_to=dest,install_from=srcfile,**kw)
++		tg.dest=tg.install_to
++		tg.type='install_as'
++		if not kw.get('postpone',True):
++			tg.post()
++		return tg
++	def symlink_as(self,dest,src,**kw):
++		assert(dest)
++		tg=self(features='install_task',install_to=dest,install_from=src,**kw)
++		tg.dest=tg.install_to
++		tg.type='symlink_as'
++		tg.link=src
++		if not kw.get('postpone',True):
++			tg.post()
++		return tg
++ at TaskGen.feature('install_task')
++ at TaskGen.before_method('process_rule','process_source')
++def process_install_task(self):
++	self.add_install_task(**self.__dict__)
++ at TaskGen.taskgen_method
++def add_install_task(self,**kw):
++	if not self.bld.is_install:
++		return
++	if not kw['install_to']:
++		return
++	if kw['type']=='symlink_as'and Utils.is_win32:
++		if kw.get('win32_install'):
++			kw['type']='install_as'
++		else:
++			return
++	tsk=self.install_task=self.create_task('inst')
++	tsk.chmod=kw.get('chmod',Utils.O644)
++	tsk.link=kw.get('link','')or kw.get('install_from','')
++	tsk.relative_trick=kw.get('relative_trick',False)
++	tsk.type=kw['type']
++	tsk.install_to=tsk.dest=kw['install_to']
++	tsk.install_from=kw['install_from']
++	tsk.relative_base=kw.get('cwd')or kw.get('relative_base',self.path)
++	tsk.install_user=kw.get('install_user')
++	tsk.install_group=kw.get('install_group')
++	tsk.init_files()
++	if not kw.get('postpone',True):
++		tsk.run_now()
++	return tsk
++ at TaskGen.taskgen_method
++def add_install_files(self,**kw):
++	kw['type']='install_files'
++	return self.add_install_task(**kw)
++ at TaskGen.taskgen_method
++def add_install_as(self,**kw):
++	kw['type']='install_as'
++	return self.add_install_task(**kw)
++ at TaskGen.taskgen_method
++def add_symlink_as(self,**kw):
++	kw['type']='symlink_as'
++	return self.add_install_task(**kw)
 +class inst(Task.Task):
-+	color='CYAN'
++	def __str__(self):
++		return''
 +	def uid(self):
-+		lst=[self.dest,self.path]+self.source
-+		return Utils.h_list(repr(lst))
-+	def post(self):
-+		buf=[]
-+		for x in self.source:
-+			if isinstance(x,waflib.Node.Node):
-+				y=x
-+			else:
-+				y=self.path.find_resource(x)
-+				if not y:
-+					if Logs.verbose:
-+						Logs.warn('Could not find %s immediately (may cause broken builds)'%x)
-+					idx=self.generator.bld.get_group_idx(self)
-+					for tg in self.generator.bld.groups[idx]:
-+						if not isinstance(tg,inst)and id(tg)!=id(self):
-+							tg.post()
-+						y=self.path.find_resource(x)
-+						if y:
-+							break
-+					else:
-+						raise Errors.WafError('Could not find %r in %r'%(x,self.path))
-+			buf.append(y)
-+		self.inputs=buf
++		lst=self.inputs+self.outputs+[self.link,self.generator.path.abspath()]
++		return Utils.h_list(lst)
++	def init_files(self):
++		if self.type=='symlink_as':
++			inputs=[]
++		else:
++			inputs=self.generator.to_nodes(self.install_from)
++			if self.type=='install_as':
++				assert len(inputs)==1
++		self.set_inputs(inputs)
++		dest=self.get_install_path()
++		outputs=[]
++		if self.type=='symlink_as':
++			if self.relative_trick:
++				self.link=os.path.relpath(self.link,os.path.dirname(dest))
++			outputs.append(self.generator.bld.root.make_node(dest))
++		elif self.type=='install_as':
++			outputs.append(self.generator.bld.root.make_node(dest))
++		else:
++			for y in inputs:
++				if self.relative_trick:
++					destfile=os.path.join(dest,y.path_from(self.relative_base))
++				else:
++					destfile=os.path.join(dest,y.name)
++				outputs.append(self.generator.bld.root.make_node(destfile))
++		self.set_outputs(outputs)
 +	def runnable_status(self):
 +		ret=super(inst,self).runnable_status()
-+		if ret==Task.SKIP_ME:
++		if ret==Task.SKIP_ME and self.generator.bld.is_install:
 +			return Task.RUN_ME
 +		return ret
-+	def __str__(self):
-+		return''
-+	def run(self):
-+		return self.generator.exec_task()
++	def post_run(self):
++		pass
 +	def get_install_path(self,destdir=True):
-+		dest=Utils.subst_vars(self.dest,self.env)
-+		dest=dest.replace('/',os.sep)
++		if isinstance(self.install_to,Node.Node):
++			dest=self.install_to.abspath()
++		else:
++			dest=Utils.subst_vars(self.install_to,self.env)
 +		if destdir and Options.options.destdir:
 +			dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
 +		return dest
-+	def exec_install_files(self):
-+		destpath=self.get_install_path()
-+		if not destpath:
-+			raise Errors.WafError('unknown installation path %r'%self.generator)
-+		for x,y in zip(self.source,self.inputs):
-+			if self.relative_trick:
-+				destfile=os.path.join(destpath,y.path_from(self.path))
-+			else:
-+				destfile=os.path.join(destpath,y.name)
-+			self.generator.bld.do_install(y.abspath(),destfile,chmod=self.chmod,tsk=self)
-+	def exec_install_as(self):
-+		destfile=self.get_install_path()
-+		self.generator.bld.do_install(self.inputs[0].abspath(),destfile,chmod=self.chmod,tsk=self)
-+	def exec_symlink_as(self):
-+		destfile=self.get_install_path()
-+		src=self.link
-+		if self.relative_trick:
-+			src=os.path.relpath(src,os.path.dirname(destfile))
-+		self.generator.bld.do_link(src,destfile,tsk=self)
-+class InstallContext(BuildContext):
-+	'''installs the targets on the system'''
-+	cmd='install'
-+	def __init__(self,**kw):
-+		super(InstallContext,self).__init__(**kw)
-+		self.uninstall=[]
-+		self.is_install=INSTALL
-+	def copy_fun(self,src,tgt,**kw):
++	def copy_fun(self,src,tgt):
 +		if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'):
 +			tgt='\\\\?\\'+tgt
 +		shutil.copy2(src,tgt)
-+		os.chmod(tgt,kw.get('chmod',Utils.O644))
-+	def do_install(self,src,tgt,**kw):
-+		d,_=os.path.split(tgt)
-+		if not d:
-+			raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt))
-+		Utils.check_dir(d)
-+		srclbl=src.replace(self.srcnode.abspath()+os.sep,'')
++		self.fix_perms(tgt)
++	def rm_empty_dirs(self,tgt):
++		while tgt:
++			tgt=os.path.dirname(tgt)
++			try:
++				os.rmdir(tgt)
++			except OSError:
++				break
++	def run(self):
++		is_install=self.generator.bld.is_install
++		if not is_install:
++			return
++		for x in self.outputs:
++			if is_install==INSTALL:
++				x.parent.mkdir()
++		if self.type=='symlink_as':
++			fun=is_install==INSTALL and self.do_link or self.do_unlink
++			fun(self.link,self.outputs[0].abspath())
++		else:
++			fun=is_install==INSTALL and self.do_install or self.do_uninstall
++			launch_node=self.generator.bld.launch_node()
++			for x,y in zip(self.inputs,self.outputs):
++				fun(x.abspath(),y.abspath(),x.path_from(launch_node))
++	def run_now(self):
++		status=self.runnable_status()
++		if status not in(Task.RUN_ME,Task.SKIP_ME):
++			raise Errors.TaskNotReady('Could not process %r: status %r'%(self,status))
++		self.run()
++		self.hasrun=Task.SUCCESS
++	def do_install(self,src,tgt,lbl,**kw):
 +		if not Options.options.force:
 +			try:
 +				st1=os.stat(tgt)
@@ -684,11 +751,11 @@ Last-Update: 2014-11-28
 +				pass
 +			else:
 +				if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
-+					if not self.progress_bar:
-+						Logs.info('- install %s (from %s)'%(tgt,srclbl))
++					if not self.generator.bld.progress_bar:
++						Logs.info('- install %s (from %s)',tgt,lbl)
 +					return False
-+		if not self.progress_bar:
-+			Logs.info('+ install %s (from %s)'%(tgt,srclbl))
++		if not self.generator.bld.progress_bar:
++			Logs.info('+ install %s (from %s)',tgt,lbl)
 +		try:
 +			os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode))
 +		except EnvironmentError:
@@ -698,96 +765,37 @@ Last-Update: 2014-11-28
 +		except OSError:
 +			pass
 +		try:
-+			self.copy_fun(src,tgt,**kw)
-+		except IOError:
-+			try:
-+				os.stat(src)
-+			except EnvironmentError:
-+				Logs.error('File %r does not exist'%src)
-+			raise Errors.WafError('Could not install the file %r'%tgt)
-+	def do_link(self,src,tgt,**kw):
-+		d,_=os.path.split(tgt)
-+		Utils.check_dir(d)
-+		link=False
++			self.copy_fun(src,tgt)
++		except EnvironmentError ,e:
++			if not os.path.exists(src):
++				Logs.error('File %r does not exist',src)
++			elif not os.path.isfile(src):
++				Logs.error('Input %r is not a file',src)
++			raise Errors.WafError('Could not install the file %r'%tgt,e)
++	def fix_perms(self,tgt):
++		if not Utils.is_win32:
++			user=getattr(self,'install_user',None)or getattr(self.generator,'install_user',None)
++			group=getattr(self,'install_group',None)or getattr(self.generator,'install_group',None)
++			if user or group:
++				Utils.lchown(tgt,user or-1,group or-1)
 +		if not os.path.islink(tgt):
-+			link=True
-+		elif os.readlink(tgt)!=src:
-+			link=True
-+		if link:
-+			try:os.remove(tgt)
-+			except OSError:pass
-+			if not self.progress_bar:
-+				Logs.info('+ symlink %s (to %s)'%(tgt,src))
-+			os.symlink(src,tgt)
++			os.chmod(tgt,self.chmod)
++	def do_link(self,src,tgt,**kw):
++		if os.path.islink(tgt)and os.readlink(tgt)==src:
++			if not self.generator.bld.progress_bar:
++				Logs.info('- symlink %s (to %s)',tgt,src)
 +		else:
-+			if not self.progress_bar:
-+				Logs.info('- symlink %s (to %s)'%(tgt,src))
-+	def run_task_now(self,tsk,postpone):
-+		tsk.post()
-+		if not postpone:
-+			if tsk.runnable_status()==Task.ASK_LATER:
-+				raise self.WafError('cannot post the task %r'%tsk)
-+			tsk.run()
-+	def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True,task=None):
-+		tsk=inst(env=env or self.env)
-+		tsk.bld=self
-+		tsk.path=cwd or self.path
-+		tsk.chmod=chmod
-+		tsk.task=task
-+		if isinstance(files,waflib.Node.Node):
-+			tsk.source=[files]
-+		else:
-+			tsk.source=Utils.to_list(files)
-+		tsk.dest=dest
-+		tsk.exec_task=tsk.exec_install_files
-+		tsk.relative_trick=relative_trick
-+		if add:self.add_to_group(tsk)
-+		self.run_task_now(tsk,postpone)
-+		return tsk
-+	def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True,task=None):
-+		tsk=inst(env=env or self.env)
-+		tsk.bld=self
-+		tsk.path=cwd or self.path
-+		tsk.chmod=chmod
-+		tsk.source=[srcfile]
-+		tsk.task=task
-+		tsk.dest=dest
-+		tsk.exec_task=tsk.exec_install_as
-+		if add:self.add_to_group(tsk)
-+		self.run_task_now(tsk,postpone)
-+		return tsk
-+	def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False,task=None):
-+		if Utils.is_win32:
-+			return
-+		tsk=inst(env=env or self.env)
-+		tsk.bld=self
-+		tsk.dest=dest
-+		tsk.path=cwd or self.path
-+		tsk.source=[]
-+		tsk.task=task
-+		tsk.link=src
-+		tsk.relative_trick=relative_trick
-+		tsk.exec_task=tsk.exec_symlink_as
-+		if add:self.add_to_group(tsk)
-+		self.run_task_now(tsk,postpone)
-+		return tsk
-+class UninstallContext(InstallContext):
-+	'''removes the targets installed'''
-+	cmd='uninstall'
-+	def __init__(self,**kw):
-+		super(UninstallContext,self).__init__(**kw)
-+		self.is_install=UNINSTALL
-+	def rm_empty_dirs(self,tgt):
-+		while tgt:
-+			tgt=os.path.dirname(tgt)
 +			try:
-+				os.rmdir(tgt)
++				os.remove(tgt)
 +			except OSError:
-+				break
-+	def do_install(self,src,tgt,**kw):
-+		if not self.progress_bar:
-+			Logs.info('- remove %s'%tgt)
-+		self.uninstall.append(tgt)
++				pass
++			if not self.generator.bld.progress_bar:
++				Logs.info('+ symlink %s (to %s)',tgt,src)
++			os.symlink(src,tgt)
++			self.fix_perms(tgt)
++	def do_uninstall(self,src,tgt,lbl,**kw):
++		if not self.generator.bld.progress_bar:
++			Logs.info('- remove %s',tgt)
 +		try:
 +			os.remove(tgt)
 +		except OSError ,e:
@@ -796,16 +804,28 @@ Last-Update: 2014-11-28
 +					self.uninstall_error=True
 +					Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
 +				if Logs.verbose>1:
-+					Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno))
++					Logs.warn('Could not remove %s (error code %r)',e.filename,e.errno)
 +		self.rm_empty_dirs(tgt)
-+	def do_link(self,src,tgt,**kw):
++	def do_unlink(self,src,tgt,**kw):
 +		try:
-+			if not self.progress_bar:
-+				Logs.info('- remove %s'%tgt)
++			if not self.generator.bld.progress_bar:
++				Logs.info('- remove %s',tgt)
 +			os.remove(tgt)
 +		except OSError:
 +			pass
 +		self.rm_empty_dirs(tgt)
++class InstallContext(BuildContext):
++	'''installs the targets on the system'''
++	cmd='install'
++	def __init__(self,**kw):
++		super(InstallContext,self).__init__(**kw)
++		self.is_install=INSTALL
++class UninstallContext(InstallContext):
++	'''removes the targets installed'''
++	cmd='uninstall'
++	def __init__(self,**kw):
++		super(UninstallContext,self).__init__(**kw)
++		self.is_install=UNINSTALL
 +	def execute(self):
 +		try:
 +			def runnable_status(self):
@@ -831,14 +851,16 @@ Last-Update: 2014-11-28
 +		Logs.debug('build: clean called')
 +		if self.bldnode!=self.srcnode:
 +			lst=[]
-+			for e in self.all_envs.values():
-+				lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES])
++			for env in self.all_envs.values():
++				lst.extend(self.root.find_or_declare(f)for f in env[CFG_FILES])
 +			for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True):
 +				if n in lst:
 +					continue
 +				n.delete()
 +		self.root.children={}
-+		for v in'node_deps task_sigs raw_deps'.split():
++		for v in SAVED_ATTRS:
++			if v=='root':
++				continue
 +			setattr(self,v,{})
 +class ListContext(BuildContext):
 +	'''lists the targets to execute'''
@@ -860,11 +882,9 @@ Last-Update: 2014-11-28
 +					f()
 +		try:
 +			self.get_tgen_by_name('')
-+		except Exception:
++		except Errors.WafError:
 +			pass
-+		lst=list(self.task_gen_cache_names.keys())
-+		lst.sort()
-+		for k in lst:
++		for k in sorted(self.task_gen_cache_names.keys()):
 +			Logs.pprint('GREEN',k)
 +class StepContext(BuildContext):
 +	'''executes tasks in a step-by-step fashion, for debugging'''
@@ -877,7 +897,7 @@ Last-Update: 2014-11-28
 +			Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
 +			BuildContext.compile(self)
 +			return
-+		targets=None
++		targets=[]
 +		if self.targets and self.targets!='*':
 +			targets=self.targets.split(',')
 +		for g in self.groups:
@@ -909,7 +929,7 @@ Last-Update: 2014-11-28
 +								break
 +						if do_exec:
 +							ret=tsk.run()
-+							Logs.info('%s -> exit %r'%(str(tsk),ret))
++							Logs.info('%s -> exit %r',tsk,ret)
 +	def get_matcher(self,pat):
 +		inn=True
 +		out=True
@@ -937,9 +957,16 @@ Last-Update: 2014-11-28
 +			else:
 +				return pattern.match(node.abspath())
 +		return match
++class EnvContext(BuildContext):
++	fun=cmd=None
++	def execute(self):
++		self.restore()
++		if not self.all_envs:
++			self.load_envs()
++		self.recurse([self.run_dir])
 --- /dev/null
 +++ b/waflib/ConfigSet.py
-@@ -0,0 +1,153 @@
+@@ -0,0 +1,159 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -966,12 +993,14 @@ Last-Update: 2014-11-28
 +		keys=list(keys)
 +		keys.sort()
 +		return keys
++	def __iter__(self):
++		return iter(self.keys())
 +	def __str__(self):
 +		return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()])
 +	def __getitem__(self,key):
 +		try:
 +			while 1:
-+				x=self.table.get(key,None)
++				x=self.table.get(key)
 +				if not x is None:
 +					return x
 +				self=self.parent
@@ -1020,16 +1049,19 @@ Last-Update: 2014-11-28
 +		try:
 +			value=self.table[key]
 +		except KeyError:
-+			try:value=self.parent[key]
-+			except AttributeError:value=[]
-+			if isinstance(value,list):
-+				value=value[:]
++			try:
++				value=self.parent[key]
++			except AttributeError:
++				value=[]
 +			else:
-+				value=[value]
++				if isinstance(value,list):
++					value=value[:]
++				else:
++					value=[value]
++			self.table[key]=value
 +		else:
 +			if not isinstance(value,list):
-+				value=[value]
-+		self.table[key]=value
++				self.table[key]=value=[value]
 +		return value
 +	def append_value(self,var,val):
 +		if isinstance(val,str):
@@ -1081,29 +1113,28 @@ Last-Update: 2014-11-28
 +		for m in re_imp.finditer(code):
 +			g=m.group
 +			tbl[g(2)]=eval(g(3))
-+		Logs.debug('env: %s'%str(self.table))
++		Logs.debug('env: %s',self.table)
 +	def update(self,d):
-+		for k,v in d.items():
-+			self[k]=v
++		self.table.update(d)
 +	def stash(self):
 +		orig=self.table
 +		tbl=self.table=self.table.copy()
 +		for x in tbl.keys():
 +			tbl[x]=copy.deepcopy(tbl[x])
 +		self.undo_stack=self.undo_stack+[orig]
++	def commit(self):
++		self.undo_stack.pop(-1)
 +	def revert(self):
 +		self.table=self.undo_stack.pop(-1)
 --- /dev/null
 +++ b/waflib/Configure.py
-@@ -0,0 +1,383 @@
+@@ -0,0 +1,368 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os,shlex,sys,time,re,shutil
 +from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
-+BREAK='break'
-+CONTINUE='continue'
 +WAF_CONFIG_LOG='config.log'
 +autoconfig=False
 +conf_template='''# project %(app)s configured on %(now)s by
@@ -1173,17 +1204,12 @@ Last-Update: 2014-11-28
 +			ver=getattr(Context.g_module,'VERSION','')
 +			if ver:
 +				app="%s (%s)"%(app,ver)
-+		now=time.ctime()
-+		pyver=sys.hexversion
-+		systype=sys.platform
-+		args=" ".join(sys.argv)
-+		wafver=Context.WAFVERSION
-+		abi=Context.ABI
-+		self.to_log(conf_template%vars())
++		params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app}
++		self.to_log(conf_template%params)
 +		self.msg('Setting top to',self.srcnode.abspath())
 +		self.msg('Setting out to',self.bldnode.abspath())
 +		if id(self.srcnode)==id(self.bldnode):
-+			Logs.warn('Setting top == out (remember to use "update_outputs")')
++			Logs.warn('Setting top == out')
 +		elif id(self.path)!=id(self.srcnode):
 +			if self.srcnode.is_child_of(self.path):
 +				Logs.warn('Are you certain that you do not want to set top="." ?')
@@ -1192,14 +1218,15 @@ Last-Update: 2014-11-28
 +		Context.top_dir=self.srcnode.abspath()
 +		Context.out_dir=self.bldnode.abspath()
 +		env=ConfigSet.ConfigSet()
-+		env['argv']=sys.argv
-+		env['options']=Options.options.__dict__
++		env.argv=sys.argv
++		env.options=Options.options.__dict__
++		env.config_cmd=self.cmd
 +		env.run_dir=Context.run_dir
 +		env.top_dir=Context.top_dir
 +		env.out_dir=Context.out_dir
-+		env['hash']=self.hash
-+		env['files']=self.files
-+		env['environ']=dict(self.environ)
++		env.hash=self.hash
++		env.files=self.files
++		env.environ=dict(self.environ)
 +		if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options,'no_lock_in_run'):
 +			env.store(os.path.join(Context.run_dir,Options.lockfile))
 +		if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options,'no_lock_in_top'):
@@ -1209,17 +1236,17 @@ Last-Update: 2014-11-28
 +	def prepare_env(self,env):
 +		if not env.PREFIX:
 +			if Options.options.prefix or Utils.is_win32:
-+				env.PREFIX=os.path.abspath(os.path.expanduser(Options.options.prefix))
++				env.PREFIX=Utils.sane_path(Options.options.prefix)
 +			else:
 +				env.PREFIX=''
 +		if not env.BINDIR:
 +			if Options.options.bindir:
-+				env.BINDIR=os.path.abspath(os.path.expanduser(Options.options.bindir))
++				env.BINDIR=Utils.sane_path(Options.options.bindir)
 +			else:
 +				env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
 +		if not env.LIBDIR:
 +			if Options.options.libdir:
-+				env.LIBDIR=os.path.abspath(os.path.expanduser(Options.options.libdir))
++				env.LIBDIR=Utils.sane_path(Options.options.libdir)
 +			else:
 +				env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env)
 +	def store(self):
@@ -1230,18 +1257,19 @@ Last-Update: 2014-11-28
 +		for key in self.all_envs:
 +			tmpenv=self.all_envs[key]
 +			tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
-+	def load(self,input,tooldir=None,funs=None):
++	def load(self,input,tooldir=None,funs=None,with_sys_path=True,cache=False):
 +		tools=Utils.to_list(input)
 +		if tooldir:tooldir=Utils.to_list(tooldir)
 +		for tool in tools:
-+			mag=(tool,id(self.env),tooldir,funs)
-+			if mag in self.tool_cache:
-+				self.to_log('(tool %s is already loaded, skipping)'%tool)
-+				continue
-+			self.tool_cache.append(mag)
++			if cache:
++				mag=(tool,id(self.env),tooldir,funs)
++				if mag in self.tool_cache:
++					self.to_log('(tool %s is already loaded, skipping)'%tool)
++					continue
++				self.tool_cache.append(mag)
 +			module=None
 +			try:
-+				module=Context.load_tool(tool,tooldir,ctx=self)
++				module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path)
 +			except ImportError ,e:
 +				self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,sys.path,e))
 +			except Exception ,e:
@@ -1264,19 +1292,9 @@ Last-Update: 2014-11-28
 +		self.rules=Utils.to_list(rules)
 +		for x in self.rules:
 +			f=getattr(self,x)
-+			if not f:self.fatal("No such method '%s'."%x)
-+			try:
-+				f()
-+			except Exception ,e:
-+				ret=self.err_handler(x,e)
-+				if ret==BREAK:
-+					break
-+				elif ret==CONTINUE:
-+					continue
-+				else:
-+					raise
-+	def err_handler(self,fun,error):
-+		pass
++			if not f:
++				self.fatal('No such configuration function %r'%x)
++			f()
 +def conf(f):
 +	def fun(*k,**kw):
 +		mandatory=True
@@ -1288,11 +1306,12 @@ Last-Update: 2014-11-28
 +		except Errors.ConfigurationError:
 +			if mandatory:
 +				raise
++	fun.__name__=f.__name__
 +	setattr(ConfigurationContext,f.__name__,fun)
 +	setattr(Build.BuildContext,f.__name__,fun)
 +	return f
 + at conf
-+def add_os_flags(self,var,dest=None,dup=True):
++def add_os_flags(self,var,dest=None,dup=False):
 +	try:
 +		flags=shlex.split(self.environ[var])
 +	except KeyError:
@@ -1301,16 +1320,19 @@ Last-Update: 2014-11-28
 +		self.env.append_value(dest or var,flags)
 + at conf
 +def cmd_to_list(self,cmd):
-+	if isinstance(cmd,str)and cmd.find(' '):
-+		try:
-+			os.stat(cmd)
-+		except OSError:
++	if isinstance(cmd,str):
++		if os.path.isfile(cmd):
++			return[cmd]
++		if os.sep=='/':
 +			return shlex.split(cmd)
 +		else:
-+			return[cmd]
++			try:
++				return shlex.split(cmd,posix=False)
++			except TypeError:
++				return shlex.split(cmd)
 +	return cmd
 + at conf
-+def check_waf_version(self,mini='1.7.99',maxi='1.9.0',**kw):
++def check_waf_version(self,mini='1.8.99',maxi='2.0.0',**kw):
 +	self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw)
 +	ver=Context.HEXVERSION
 +	if Utils.num2ver(mini)>ver:
@@ -1322,7 +1344,7 @@ Last-Update: 2014-11-28
 +def find_file(self,filename,path_list=[]):
 +	for n in Utils.to_list(filename):
 +		for d in Utils.to_list(path_list):
-+			p=os.path.join(d,n)
++			p=os.path.expanduser(os.path.join(d,n))
 +			if os.path.exists(p):
 +				return p
 +	self.fatal('Could not find %r'%filename)
@@ -1341,15 +1363,12 @@ Last-Update: 2014-11-28
 +		path_list=Utils.to_list(path_list)
 +	else:
 +		path_list=environ.get('PATH','').split(os.pathsep)
-+	if var in environ:
-+		filename=environ[var]
-+		if os.path.isfile(filename):
-+			ret=[filename]
-+		else:
-+			ret=self.cmd_to_list(filename)
++	if kw.get('value'):
++		ret=self.cmd_to_list(kw['value'])
++	elif var in environ:
++		ret=self.cmd_to_list(environ[var])
 +	elif self.env[var]:
-+		ret=self.env[var]
-+		ret=self.cmd_to_list(ret)
++		ret=self.cmd_to_list(self.env[var])
 +	else:
 +		if not ret:
 +			ret=self.find_binary(filename,exts.split(','),path_list)
@@ -1365,12 +1384,12 @@ Last-Update: 2014-11-28
 +			retmsg=ret
 +	else:
 +		retmsg=False
-+	self.msg("Checking for program '%s'"%msg,retmsg,**kw)
-+	if not kw.get('quiet',None):
++	self.msg('Checking for program %r'%msg,retmsg,**kw)
++	if not kw.get('quiet'):
 +		self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
 +	if not ret:
 +		self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename)
-+	interpreter=kw.get('interpreter',None)
++	interpreter=kw.get('interpreter')
 +	if interpreter is None:
 +		if not Utils.check_exe(ret[0],env=environ):
 +			self.fatal('Program %r is not executable'%ret)
@@ -1409,9 +1428,7 @@ Last-Update: 2014-11-28
 +	if cachemode==1:
 +		try:
 +			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build'))
-+		except OSError:
-+			pass
-+		except IOError:
++		except EnvironmentError:
 +			pass
 +		else:
 +			ret=proj['cache_run_build']
@@ -1421,7 +1438,8 @@ Last-Update: 2014-11-28
 +	bdir=os.path.join(dir,'testbuild')
 +	if not os.path.exists(bdir):
 +		os.makedirs(bdir)
-+	self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
++	cls_name=getattr(self,'run_build_cls','build')
++	self.test_bld=bld=Context.create_context(cls_name,top_dir=dir,out_dir=bdir)
 +	bld.init_dirs()
 +	bld.progress_bar=0
 +	bld.targets='*'
@@ -1457,7 +1475,7 @@ Last-Update: 2014-11-28
 +def test(self,*k,**kw):
 +	if not'env'in kw:
 +		kw['env']=self.env.derive()
-+	if kw.get('validate',None):
++	if kw.get('validate'):
 +		kw['validate'](kw)
 +	self.start_msg(kw['msg'],**kw)
 +	ret=None
@@ -1471,7 +1489,7 @@ Last-Update: 2014-11-28
 +			self.fatal('The configuration failed')
 +	else:
 +		kw['success']=ret
-+	if kw.get('post_check',None):
++	if kw.get('post_check'):
 +		ret=kw['post_check'](kw)
 +	if ret:
 +		self.end_msg(kw['errmsg'],'YELLOW',**kw)
@@ -1481,7 +1499,7 @@ Last-Update: 2014-11-28
 +	return ret
 --- /dev/null
 +++ b/waflib/Context.py
-@@ -0,0 +1,360 @@
+@@ -0,0 +1,396 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -1489,10 +1507,10 @@ Last-Update: 2014-11-28
 +import os,re,imp,sys
 +from waflib import Utils,Errors,Logs
 +import waflib.Node
-+HEXVERSION=0x1080c00
-+WAFVERSION="1.8.12"
-+WAFREVISION="ae508f2f82fbfad4420f7920b6f68a6801e383fd"
-+ABI=98
++HEXVERSION=0x1090800
++WAFVERSION="1.9.8"
++WAFREVISION="ffcbf5d4020624dcd1b9338005e3e10dcbebf8f1"
++ABI=99
 +DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
 +APPNAME='APPNAME'
 +VERSION='VERSION'
@@ -1504,9 +1522,6 @@ Last-Update: 2014-11-28
 +top_dir=''
 +out_dir=''
 +waf_dir=''
-+local_repo=''
-+remote_repo='http://waf.googlecode.com/git/'
-+remote_locs=['waflib/extras','waflib/Tools']
 +g_module=None
 +STDOUT=1
 +STDERR=-1
@@ -1524,7 +1539,7 @@ Last-Update: 2014-11-28
 +	def __init__(cls,name,bases,dict):
 +		super(store_context,cls).__init__(name,bases,dict)
 +		name=cls.__name__
-+		if name=='ctx'or name=='Context':
++		if name in('ctx','Context'):
 +			return
 +		try:
 +			cls.cmd
@@ -1544,8 +1559,8 @@ Last-Update: 2014-11-28
 +		except KeyError:
 +			global run_dir
 +			rd=run_dir
-+		self.node_class=type("Nod3",(waflib.Node.Node,),{})
-+		self.node_class.__module__="waflib.Node"
++		self.node_class=type('Nod3',(waflib.Node.Node,),{})
++		self.node_class.__module__='waflib.Node'
 +		self.node_class.ctx=self
 +		self.root=self.node_class('',None)
 +		self.cur_script=None
@@ -1553,8 +1568,6 @@ Last-Update: 2014-11-28
 +		self.stack_path=[]
 +		self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self}
 +		self.logger=None
-+	def __hash__(self):
-+		return id(self)
 +	def finalize(self):
 +		try:
 +			logger=self.logger
@@ -1566,8 +1579,9 @@ Last-Update: 2014-11-28
 +	def load(self,tool_list,*k,**kw):
 +		tools=Utils.to_list(tool_list)
 +		path=Utils.to_list(kw.get('tooldir',''))
++		with_sys_path=kw.get('with_sys_path',True)
 +		for t in tools:
-+			module=load_tool(t,path)
++			module=load_tool(t,path,with_sys_path=with_sys_path)
 +			fun=getattr(module,kw.get('name',self.fun),None)
 +			if fun:
 +				fun(self)
@@ -1613,19 +1627,23 @@ Last-Update: 2014-11-28
 +						if not user_function:
 +							if not mandatory:
 +								continue
-+							raise Errors.WafError('No function %s defined in %s'%(name or self.fun,node.abspath()))
++							raise Errors.WafError('No function %r defined in %s'%(name or self.fun,node.abspath()))
 +						user_function(self)
 +					finally:
 +						self.post_recurse(node)
 +				elif not node:
 +					if not mandatory:
 +						continue
++					try:
++						os.listdir(d)
++					except OSError:
++						raise Errors.WafError('Cannot read the folder %r'%d)
 +					raise Errors.WafError('No wscript file in directory %s'%d)
 +	def exec_command(self,cmd,**kw):
 +		subprocess=Utils.subprocess
 +		kw['shell']=isinstance(cmd,str)
-+		Logs.debug('runner: %r'%(cmd,))
-+		Logs.debug('runner_env: kw=%s'%kw)
++		Logs.debug('runner: %r',cmd)
++		Logs.debug('runner_env: kw=%s',kw)
 +		if self.logger:
 +			self.logger.info(cmd)
 +		if'stdout'not in kw:
@@ -1633,27 +1651,36 @@ Last-Update: 2014-11-28
 +		if'stderr'not in kw:
 +			kw['stderr']=subprocess.PIPE
 +		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
-+			raise Errors.WafError("Program %s not found!"%cmd[0])
-+		try:
-+			if kw['stdout']or kw['stderr']:
-+				p=subprocess.Popen(cmd,**kw)
-+				(out,err)=p.communicate()
-+				ret=p.returncode
-+			else:
-+				out,err=(None,None)
-+				ret=subprocess.Popen(cmd,**kw).wait()
++			raise Errors.WafError('Program %s not found!'%cmd[0])
++		cargs={}
++		if'timeout'in kw:
++			if sys.hexversion>=0x3030000:
++				cargs['timeout']=kw['timeout']
++				if not'start_new_session'in kw:
++					kw['start_new_session']=True
++			del kw['timeout']
++		if'input'in kw:
++			if kw['input']:
++				cargs['input']=kw['input']
++				kw['stdin']=subprocess.PIPE
++			del kw['input']
++		if'cwd'in kw:
++			if not isinstance(kw['cwd'],str):
++				kw['cwd']=kw['cwd'].abspath()
++		try:
++			ret,out,err=Utils.run_process(cmd,kw,cargs)
 +		except Exception ,e:
-+			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
++			raise Errors.WafError('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]
 +		if out:
 +			if not isinstance(out,str):
-+				out=out.decode(sys.stdout.encoding or'iso8859-1')
++				out=out
 +			if self.logger:
-+				self.logger.debug('out: %s'%out)
++				self.logger.debug('out: %s',out)
 +			else:
 +				Logs.info(out,extra={'stream':sys.stdout,'c1':''})
 +		if err:
 +			if not isinstance(err,str):
-+				err=err.decode(sys.stdout.encoding or'iso8859-1')
++				err=err
 +			if self.logger:
 +				self.logger.error('err: %s'%err)
 +			else:
@@ -1662,7 +1689,7 @@ Last-Update: 2014-11-28
 +	def cmd_and_log(self,cmd,**kw):
 +		subprocess=Utils.subprocess
 +		kw['shell']=isinstance(cmd,str)
-+		Logs.debug('runner: %r'%(cmd,))
++		Logs.debug('runner: %r',cmd)
 +		if'quiet'in kw:
 +			quiet=kw['quiet']
 +			del kw['quiet']
@@ -1674,26 +1701,40 @@ Last-Update: 2014-11-28
 +		else:
 +			to_ret=STDOUT
 +		if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
-+			raise Errors.WafError("Program %s not found!"%cmd[0])
++			raise Errors.WafError('Program %r not found!'%cmd[0])
 +		kw['stdout']=kw['stderr']=subprocess.PIPE
 +		if quiet is None:
 +			self.to_log(cmd)
-+		try:
-+			p=subprocess.Popen(cmd,**kw)
-+			(out,err)=p.communicate()
++		cargs={}
++		if'timeout'in kw:
++			if sys.hexversion>=0x3030000:
++				cargs['timeout']=kw['timeout']
++				if not'start_new_session'in kw:
++					kw['start_new_session']=True
++			del kw['timeout']
++		if'input'in kw:
++			if kw['input']:
++				cargs['input']=kw['input']
++				kw['stdin']=subprocess.PIPE
++			del kw['input']
++		if'cwd'in kw:
++			if not isinstance(kw['cwd'],str):
++				kw['cwd']=kw['cwd'].abspath()
++		try:
++			ret,out,err=Utils.run_process(cmd,kw,cargs)
 +		except Exception ,e:
-+			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
++			raise Errors.WafError('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]
 +		if not isinstance(out,str):
-+			out=out.decode(sys.stdout.encoding or'iso8859-1')
++			out=out
 +		if not isinstance(err,str):
-+			err=err.decode(sys.stdout.encoding or'iso8859-1')
++			err=err
 +		if out and quiet!=STDOUT and quiet!=BOTH:
 +			self.to_log('out: %s'%out)
 +		if err and quiet!=STDERR and quiet!=BOTH:
 +			self.to_log('err: %s'%err)
-+		if p.returncode:
-+			e=Errors.WafError('Command %r returned %r'%(cmd,p.returncode))
-+			e.returncode=p.returncode
++		if ret:
++			e=Errors.WafError('Command %r returned %r'%(cmd,ret))
++			e.returncode=ret
 +			e.stderr=err
 +			e.stdout=out
 +			raise e
@@ -1707,7 +1748,7 @@ Last-Update: 2014-11-28
 +			self.logger.info('from %s: %s'%(self.path.abspath(),msg))
 +		try:
 +			msg='%s\n(complete log in %s)'%(msg,self.logger.handlers[0].baseFilename)
-+		except Exception:
++		except AttributeError:
 +			pass
 +		raise self.errors.ConfigurationError(msg,ex=ex)
 +	def to_log(self,msg):
@@ -1728,14 +1769,14 @@ Last-Update: 2014-11-28
 +			result=kw['result']
 +		except KeyError:
 +			result=k[1]
-+		color=kw.get('color',None)
++		color=kw.get('color')
 +		if not isinstance(color,str):
 +			color=result and'GREEN'or'YELLOW'
 +		self.end_msg(result,color,**kw)
 +	def start_msg(self,*k,**kw):
-+		if kw.get('quiet',None):
++		if kw.get('quiet'):
 +			return
-+		msg=kw.get('msg',None)or k[0]
++		msg=kw.get('msg')or k[0]
 +		try:
 +			if self.in_msg:
 +				self.in_msg+=1
@@ -1751,12 +1792,12 @@ Last-Update: 2014-11-28
 +			self.to_log(x)
 +		Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
 +	def end_msg(self,*k,**kw):
-+		if kw.get('quiet',None):
++		if kw.get('quiet'):
 +			return
 +		self.in_msg-=1
 +		if self.in_msg:
 +			return
-+		result=kw.get('result',None)or k[0]
++		result=kw.get('result')or k[0]
 +		defcolor='GREEN'
 +		if result==True:
 +			msg='ok'
@@ -1786,13 +1827,13 @@ Last-Update: 2014-11-28
 +			waflibs=PyZipFile(waf_dir)
 +			lst=waflibs.namelist()
 +			for x in lst:
-+				if not re.match("waflib/extras/%s"%var.replace("*",".*"),var):
++				if not re.match('waflib/extras/%s'%var.replace('*','.*'),var):
 +					continue
 +				f=os.path.basename(x)
 +				doban=False
 +				for b in ban:
-+					r=b.replace("*",".*")
-+					if re.match(b,f):
++					r=b.replace('*','.*')
++					if re.match(r,f):
 +						doban=True
 +				if not doban:
 +					f=f.replace('.py','')
@@ -1810,38 +1851,51 @@ Last-Update: 2014-11-28
 +		raise Errors.WafError('Could not read the file %r'%path)
 +	module_dir=os.path.dirname(path)
 +	sys.path.insert(0,module_dir)
-+	exec(compile(code,path,'exec'),module.__dict__)
-+	sys.path.remove(module_dir)
++	try:
++		exec(compile(code,path,'exec'),module.__dict__)
++	finally:
++		sys.path.remove(module_dir)
 +	cache_modules[path]=module
 +	return module
-+def load_tool(tool,tooldir=None,ctx=None):
++def load_tool(tool,tooldir=None,ctx=None,with_sys_path=True):
 +	if tool=='java':
 +		tool='javaw'
 +	else:
 +		tool=tool.replace('++','xx')
-+	if tooldir:
-+		assert isinstance(tooldir,list)
-+		sys.path=tooldir+sys.path
-+		try:
-+			__import__(tool)
++	if not with_sys_path:
++		back_path=sys.path
++		sys.path=[]
++	try:
++		if tooldir:
++			assert isinstance(tooldir,list)
++			sys.path=tooldir+sys.path
++			try:
++				__import__(tool)
++			finally:
++				for d in tooldir:
++					sys.path.remove(d)
 +			ret=sys.modules[tool]
 +			Context.tools[tool]=ret
 +			return ret
-+		finally:
-+			for d in tooldir:
-+				sys.path.remove(d)
-+	else:
-+		for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
++		else:
++			if not with_sys_path:sys.path.insert(0,waf_dir)
 +			try:
-+				__import__(x%tool)
-+				break
-+			except ImportError:
-+				x=None
-+		if x is None:
-+			__import__(tool)
-+		ret=sys.modules[x%tool]
-+		Context.tools[tool]=ret
-+		return ret
++				for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
++					try:
++						__import__(x%tool)
++						break
++					except ImportError:
++						x=None
++				else:
++					__import__(tool)
++			finally:
++				if not with_sys_path:sys.path.remove(waf_dir)
++			ret=sys.modules[x%tool]
++			Context.tools[tool]=ret
++			return ret
++	finally:
++		if not with_sys_path:
++			sys.path+=back_path
 --- /dev/null
 +++ b/waflib/Errors.py
 @@ -0,0 +1,37 @@
@@ -1884,12 +1938,12 @@ Last-Update: 2014-11-28
 +	pass
 --- /dev/null
 +++ b/waflib/Logs.py
-@@ -0,0 +1,196 @@
+@@ -0,0 +1,205 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,re,traceback,sys,types
++import os,re,traceback,sys
 +from waflib import Utils,ansiterm
 +if not os.environ.get('NOSYNC',False):
 +	if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
@@ -1897,12 +1951,16 @@ Last-Update: 2014-11-28
 +	if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__):
 +		sys.stderr=ansiterm.AnsiTerm(sys.stderr)
 +import logging
-+LOG_FORMAT="%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
-+HOUR_FORMAT="%H:%M:%S"
-+zones=''
++LOG_FORMAT=os.environ.get('WAF_LOG_FORMAT','%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s')
++HOUR_FORMAT=os.environ.get('WAF_HOUR_FORMAT','%H:%M:%S')
++zones=[]
 +verbose=0
 +colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','GREY':'\x1b[37m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',}
 +indicator='\r\x1b[K%s%s%s'
++try:
++	unicode
++except NameError:
++	unicode=None
 +def enable_colors(use):
 +	if use==1:
 +		if not(sys.stderr.isatty()or sys.stdout.isatty()):
@@ -1922,14 +1980,15 @@ Last-Update: 2014-11-28
 +	def get_term_cols():
 +		return 80
 +get_term_cols.__doc__="""
-+	Get the console width in characters.
++	Returns the console width in characters.
 +
 +	:return: the number of characters per line
 +	:rtype: int
 +	"""
 +def get_color(cl):
-+	if not colors_lst['USE']:return''
-+	return colors_lst.get(cl,'')
++	if colors_lst['USE']:
++		return colors_lst.get(cl,'')
++	return''
 +class color_dict(object):
 +	def __getattr__(self,a):
 +		return get_color(a)
@@ -1938,9 +1997,10 @@ Last-Update: 2014-11-28
 +colors=color_dict()
 +re_log=re.compile(r'(\w+): (.*)',re.M)
 +class log_filter(logging.Filter):
-+	def __init__(self,name=None):
-+		pass
++	def __init__(self,name=''):
++		logging.Filter.__init__(self,name)
 +	def filter(self,rec):
++		global verbose
 +		rec.zone=rec.module
 +		if rec.levelno>=logging.INFO:
 +			return True
@@ -1972,7 +2032,7 @@ Last-Update: 2014-11-28
 +	def emit_override(self,record,**kw):
 +		self.terminator=getattr(record,'terminator','\n')
 +		stream=self.stream
-+		if hasattr(types,"UnicodeType"):
++		if unicode:
 +			msg=self.formatter.format(record)
 +			fs='%s'+self.terminator
 +			try:
@@ -1985,7 +2045,7 @@ Last-Update: 2014-11-28
 +				else:
 +					stream.write(fs%msg)
 +			except UnicodeError:
-+				stream.write((fs%msg).encode("UTF-8"))
++				stream.write((fs%msg).encode('utf-8'))
 +		else:
 +			logging.StreamHandler.emit(self,record)
 +class formatter(logging.Formatter):
@@ -2010,9 +2070,10 @@ Last-Update: 2014-11-28
 +			c2=getattr(rec,'c2',colors.NORMAL)
 +			msg='%s%s%s'%(c1,msg,c2)
 +		else:
-+			msg=msg.replace('\r','\n')
-+			msg=re.sub(r'\x1B\[(K|.*?(m|h|l))','',msg)
++			msg=re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))','',msg)
 +		if rec.levelno>=logging.INFO:
++			if rec.args:
++				return msg%rec.args
 +			return msg
 +		rec.msg=msg
 +		rec.c1=colors.PINK
@@ -2020,13 +2081,14 @@ Last-Update: 2014-11-28
 +		return logging.Formatter.format(self,rec)
 +log=None
 +def debug(*k,**kw):
++	global verbose
 +	if verbose:
 +		k=list(k)
 +		k[0]=k[0].replace('\n',' ')
 +		global log
 +		log.debug(*k,**kw)
 +def error(*k,**kw):
-+	global log
++	global log,verbose
 +	log.error(*k,**kw)
 +	if verbose>2:
 +		st=traceback.extract_stack()
@@ -2034,10 +2096,10 @@ Last-Update: 2014-11-28
 +			st=st[:-1]
 +			buf=[]
 +			for filename,lineno,name,line in st:
-+				buf.append('  File "%s", line %d, in %s'%(filename,lineno,name))
++				buf.append('  File %r, line %d, in %s'%(filename,lineno,name))
 +				if line:
 +					buf.append('	%s'%line.strip())
-+			if buf:log.error("\n".join(buf))
++			if buf:log.error('\n'.join(buf))
 +def warn(*k,**kw):
 +	global log
 +	log.warn(*k,**kw)
@@ -2077,13 +2139,14 @@ Last-Update: 2014-11-28
 +		for x in logger.handlers:
 +			x.close()
 +			logger.removeHandler(x)
-+	except Exception ,e:
++	except Exception:
 +		pass
 +def pprint(col,msg,label='',sep='\n'):
-+	info("%s%s%s %s"%(colors(col),msg,colors.NORMAL,label),extra={'terminator':sep})
++	global info
++	info('%s%s%s %s',colors(col),msg,colors.NORMAL,label,extra={'terminator':sep})
 --- /dev/null
 +++ b/waflib/Node.py
-@@ -0,0 +1,463 @@
+@@ -0,0 +1,485 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -2121,16 +2184,9 @@ Last-Update: 2014-11-28
 +**/_darcs/**
 +**/.intlcache
 +**/.DS_Store'''
-+split_path=Utils.split_path_unix
-+split_path_cygwin=Utils.split_path_cygwin
-+split_path_win32=Utils.split_path_win32
-+if sys.platform=='cygwin':
-+	split_path=split_path_cygwin
-+elif Utils.is_win32:
-+	split_path=split_path_win32
 +class Node(object):
 +	dict_class=dict
-+	__slots__=('name','sig','children','parent','cache_abspath','cache_isdir','cache_sig')
++	__slots__=('name','parent','children','cache_abspath','cache_isdir')
 +	def __init__(self,name,parent):
 +		self.name=name
 +		self.parent=parent
@@ -2143,38 +2199,68 @@ Last-Update: 2014-11-28
 +		self.parent=data[1]
 +		if data[2]is not None:
 +			self.children=self.dict_class(data[2])
-+		if data[3]is not None:
-+			self.sig=data[3]
 +	def __getstate__(self):
-+		return(self.name,self.parent,getattr(self,'children',None),getattr(self,'sig',None))
++		return(self.name,self.parent,getattr(self,'children',None))
 +	def __str__(self):
-+		return self.name
++		return self.abspath()
 +	def __repr__(self):
 +		return self.abspath()
-+	def __hash__(self):
-+		return id(self)
-+	def __eq__(self,node):
-+		return id(self)==id(node)
 +	def __copy__(self):
 +		raise Errors.WafError('nodes are not supposed to be copied')
 +	def read(self,flags='r',encoding='ISO8859-1'):
 +		return Utils.readf(self.abspath(),flags,encoding)
 +	def write(self,data,flags='w',encoding='ISO8859-1'):
 +		Utils.writef(self.abspath(),data,flags,encoding)
++	def read_json(self,convert=True,encoding='utf-8'):
++		import json
++		object_pairs_hook=None
++		if convert and sys.hexversion<0x3000000:
++			try:
++				_type=unicode
++			except NameError:
++				_type=str
++			def convert(value):
++				if isinstance(value,list):
++					return[convert(element)for element in value]
++				elif isinstance(value,_type):
++					return str(value)
++				else:
++					return value
++			def object_pairs(pairs):
++				return dict((str(pair[0]),convert(pair[1]))for pair in pairs)
++			object_pairs_hook=object_pairs
++		return json.loads(self.read(encoding=encoding),object_pairs_hook=object_pairs_hook)
++	def write_json(self,data,pretty=True):
++		import json
++		indent=2
++		separators=(',',': ')
++		sort_keys=pretty
++		newline=os.linesep
++		if not pretty:
++			indent=None
++			separators=(',',':')
++			newline=''
++		output=json.dumps(data,indent=indent,separators=separators,sort_keys=sort_keys)+newline
++		self.write(output,encoding='utf-8')
++	def exists(self):
++		return os.path.exists(self.abspath())
++	def isdir(self):
++		return os.path.isdir(self.abspath())
 +	def chmod(self,val):
 +		os.chmod(self.abspath(),val)
-+	def delete(self):
++	def delete(self,evict=True):
 +		try:
 +			try:
-+				if hasattr(self,'children'):
++				if os.path.isdir(self.abspath()):
 +					shutil.rmtree(self.abspath())
 +				else:
 +					os.remove(self.abspath())
-+			except OSError ,e:
++			except OSError:
 +				if os.path.exists(self.abspath()):
-+					raise e
++					raise
 +		finally:
-+			self.evict()
++			if evict:
++				self.evict()
 +	def evict(self):
 +		del self.parent.children[self.name]
 +	def suffix(self):
@@ -2192,7 +2278,7 @@ Last-Update: 2014-11-28
 +		lst.sort()
 +		return lst
 +	def mkdir(self):
-+		if getattr(self,'cache_isdir',None):
++		if self.isdir():
 +			return
 +		try:
 +			self.parent.mkdir()
@@ -2203,16 +2289,15 @@ Last-Update: 2014-11-28
 +				os.makedirs(self.abspath())
 +			except OSError:
 +				pass
-+			if not os.path.isdir(self.abspath()):
-+				raise Errors.WafError('Could not create the directory %s'%self.abspath())
++			if not self.isdir():
++				raise Errors.WafError('Could not create the directory %r'%self)
 +			try:
 +				self.children
 +			except AttributeError:
 +				self.children=self.dict_class()
-+		self.cache_isdir=True
 +	def find_node(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		cur=self
 +		for x in lst:
 +			if x=='..':
@@ -2224,48 +2309,39 @@ Last-Update: 2014-11-28
 +				cur.children=self.dict_class()
 +			else:
 +				try:
-+					cur=cur.children[x]
++					cur=ch[x]
 +					continue
 +				except KeyError:
 +					pass
 +			cur=self.__class__(x,cur)
-+			try:
-+				os.stat(cur.abspath())
-+			except OSError:
++			if not cur.exists():
 +				cur.evict()
 +				return None
-+		ret=cur
-+		try:
-+			os.stat(ret.abspath())
-+		except OSError:
-+			ret.evict()
++		if not cur.exists():
++			cur.evict()
 +			return None
-+		try:
-+			while not getattr(cur.parent,'cache_isdir',None):
-+				cur=cur.parent
-+				cur.cache_isdir=True
-+		except AttributeError:
-+			pass
-+		return ret
++		return cur
 +	def make_node(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		cur=self
 +		for x in lst:
 +			if x=='..':
 +				cur=cur.parent or cur
 +				continue
-+			if getattr(cur,'children',{}):
-+				if x in cur.children:
-+					cur=cur.children[x]
-+					continue
-+			else:
++			try:
++				cur=cur.children[x]
++			except AttributeError:
 +				cur.children=self.dict_class()
++			except KeyError:
++				pass
++			else:
++				continue
 +			cur=self.__class__(x,cur)
 +		return cur
 +	def search_node(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		cur=self
 +		for x in lst:
 +			if x=='..':
@@ -2291,19 +2367,17 @@ Last-Update: 2014-11-28
 +			up+=1
 +			c2=c2.parent
 +			c2h-=1
-+		while id(c1)!=id(c2):
++		while not c1 is c2:
 +			lst.append(c1.name)
 +			up+=1
 +			c1=c1.parent
 +			c2=c2.parent
 +		if c1.parent:
-+			for i in range(up):
-+				lst.append('..')
++			lst.extend(['..']*up)
++			lst.reverse()
++			return os.sep.join(lst)or'.'
 +		else:
-+			if lst and not Utils.is_win32:
-+				lst.append('')
-+		lst.reverse()
-+		return os.sep.join(lst)or'.'
++			return self.abspath()
 +	def abspath(self):
 +		try:
 +			return self.cache_abspath
@@ -2337,7 +2411,7 @@ Last-Update: 2014-11-28
 +		while diff>0:
 +			diff-=1
 +			p=p.parent
-+		return id(p)==id(node)
++		return p is node
 +	def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True):
 +		dircont=self.listdir()
 +		dircont.sort()
@@ -2354,7 +2428,7 @@ Last-Update: 2014-11-28
 +			if npats and npats[0]:
 +				accepted=[]in npats[0]
 +				node=self.make_node([name])
-+				isdir=os.path.isdir(node.abspath())
++				isdir=node.isdir()
 +				if accepted:
 +					if isdir:
 +						if dir:
@@ -2362,7 +2436,7 @@ Last-Update: 2014-11-28
 +					else:
 +						if src:
 +							yield node
-+				if getattr(node,'cache_isdir',None)or isdir:
++				if isdir:
 +					node.cache_isdir=True
 +					if maxdepth:
 +						for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove):
@@ -2392,7 +2466,7 @@ Last-Update: 2014-11-28
 +						try:
 +							accu.append(re.compile(k,flags=reflags))
 +						except Exception ,e:
-+							raise Errors.WafError("Invalid pattern: %s"%k,e)
++							raise Errors.WafError('Invalid pattern: %s'%k,e)
 +				ret.append(accu)
 +			return ret
 +		def filtre(name,nn):
@@ -2422,46 +2496,46 @@ Last-Update: 2014-11-28
 +		return ret
 +	def is_src(self):
 +		cur=self
-+		x=id(self.ctx.srcnode)
-+		y=id(self.ctx.bldnode)
++		x=self.ctx.srcnode
++		y=self.ctx.bldnode
 +		while cur.parent:
-+			if id(cur)==y:
++			if cur is y:
 +				return False
-+			if id(cur)==x:
++			if cur is x:
 +				return True
 +			cur=cur.parent
 +		return False
 +	def is_bld(self):
 +		cur=self
-+		y=id(self.ctx.bldnode)
++		y=self.ctx.bldnode
 +		while cur.parent:
-+			if id(cur)==y:
++			if cur is y:
 +				return True
 +			cur=cur.parent
 +		return False
 +	def get_src(self):
 +		cur=self
-+		x=id(self.ctx.srcnode)
-+		y=id(self.ctx.bldnode)
++		x=self.ctx.srcnode
++		y=self.ctx.bldnode
 +		lst=[]
 +		while cur.parent:
-+			if id(cur)==y:
++			if cur is y:
 +				lst.reverse()
-+				return self.ctx.srcnode.make_node(lst)
-+			if id(cur)==x:
++				return x.make_node(lst)
++			if cur is x:
 +				return self
 +			lst.append(cur.name)
 +			cur=cur.parent
 +		return self
 +	def get_bld(self):
 +		cur=self
-+		x=id(self.ctx.srcnode)
-+		y=id(self.ctx.bldnode)
++		x=self.ctx.srcnode
++		y=self.ctx.bldnode
 +		lst=[]
 +		while cur.parent:
-+			if id(cur)==y:
++			if cur is y:
 +				return self
-+			if id(cur)==x:
++			if cur is x:
 +				lst.reverse()
 +				return self.ctx.bldnode.make_node(lst)
 +			lst.append(cur.name)
@@ -2472,42 +2546,33 @@ Last-Update: 2014-11-28
 +		return self.ctx.bldnode.make_node(['__root__']+lst)
 +	def find_resource(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		node=self.get_bld().search_node(lst)
 +		if not node:
-+			self=self.get_src()
-+			node=self.find_node(lst)
-+		if node:
-+			if os.path.isdir(node.abspath()):
-+				return None
++			node=self.get_src().find_node(lst)
++		if node and node.isdir():
++			return None
 +		return node
 +	def find_or_declare(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		node=self.get_bld().search_node(lst)
 +		if node:
 +			if not os.path.isfile(node.abspath()):
-+				node.sig=None
 +				node.parent.mkdir()
 +			return node
 +		self=self.get_src()
 +		node=self.find_node(lst)
 +		if node:
-+			if not os.path.isfile(node.abspath()):
-+				node.sig=None
-+				node.parent.mkdir()
 +			return node
 +		node=self.get_bld().make_node(lst)
 +		node.parent.mkdir()
 +		return node
 +	def find_dir(self,lst):
 +		if isinstance(lst,str):
-+			lst=[x for x in split_path(lst)if x and x!='.']
++			lst=[x for x in Utils.split_path(lst)if x and x!='.']
 +		node=self.find_node(lst)
-+		try:
-+			if not os.path.isdir(node.abspath()):
-+				return None
-+		except(OSError,AttributeError):
++		if node and not node.isdir():
 +			return None
 +		return node
 +	def change_ext(self,ext,ext_in=None):
@@ -2527,23 +2592,43 @@ Last-Update: 2014-11-28
 +		return self.path_from(self.ctx.srcnode)
 +	def relpath(self):
 +		cur=self
-+		x=id(self.ctx.bldnode)
++		x=self.ctx.bldnode
 +		while cur.parent:
-+			if id(cur)==x:
++			if cur is x:
 +				return self.bldpath()
 +			cur=cur.parent
 +		return self.srcpath()
 +	def bld_dir(self):
 +		return self.parent.bldpath()
++	def h_file(self):
++		return Utils.h_file(self.abspath())
 +	def get_bld_sig(self):
 +		try:
-+			return self.cache_sig
++			cache=self.ctx.cache_sig
 +		except AttributeError:
-+			pass
-+		if not self.is_bld()or self.ctx.bldnode is self.ctx.srcnode:
-+			self.sig=Utils.h_file(self.abspath())
-+		self.cache_sig=ret=self.sig
++			cache=self.ctx.cache_sig={}
++		try:
++			ret=cache[self]
++		except KeyError:
++			p=self.abspath()
++			try:
++				ret=cache[self]=self.h_file()
++			except EnvironmentError:
++				if self.isdir():
++					st=os.stat(p)
++					ret=cache[self]=Utils.h_list([p,st.st_ino,st.st_mode])
++					return ret
++				raise
 +		return ret
++	def get_sig(self):
++		return self.h_file()
++	def set_sig(self,val):
++		try:
++			del self.get_bld_sig.__cache__[(self,)]
++		except(AttributeError,KeyError):
++			pass
++	sig=property(get_sig,set_sig)
++	cache_sig=property(get_sig,set_sig)
 +pickle_lock=Utils.threading.Lock()
 +class Nod3(Node):
 +	pass
@@ -2555,13 +2640,11 @@ Last-Update: 2014-11-28
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os,tempfile,optparse,sys,re
-+from waflib import Logs,Utils,Context
-+cmds='distclean configure build install clean uninstall check dist distcheck'.split()
++from waflib import Logs,Utils,Context,Errors
 +options={}
 +commands=[]
 +envvars=[]
 +lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
-+platform=Utils.unversioned_sys_platform()
 +class opt_parser(optparse.OptionParser):
 +	def __init__(self,ctx):
 +		optparse.OptionParser.__init__(self,conflict_handler="resolve",version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION))
@@ -2609,6 +2692,7 @@ Last-Update: 2014-11-28
 +		p('-k','--keep',dest='keep',default=0,action='count',help='continue despite errors (-kk to try harder)')
 +		p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
 +		p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
++		p('--profile',dest='profile',default='',action='store_true',help=optparse.SUPPRESS_HELP)
 +		gr=self.add_option_group('Configuration options')
 +		self.option_groups['configure options']=gr
 +		gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
@@ -2618,7 +2702,7 @@ Last-Update: 2014-11-28
 +		gr.add_option('--no-lock-in-top',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_top')
 +		default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX'))
 +		if not default_prefix:
-+			if platform=='win32':
++			if Utils.unversioned_sys_platform()=='win32':
 +				d=tempfile.gettempdir()
 +				default_prefix=d[0].upper()+d[1:]
 +			else:
@@ -2653,7 +2737,7 @@ Last-Update: 2014-11-28
 +				if not count and os.name not in('nt','java'):
 +					try:
 +						tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0)
-+					except Exception:
++					except Errors.WafError:
 +						pass
 +					else:
 +						if re.match('^[0-9]+$',tmp):
@@ -2689,7 +2773,7 @@ Last-Update: 2014-11-28
 +			else:
 +				commands.append(arg)
 +		if options.destdir:
-+			options.destdir=os.path.abspath(os.path.expanduser(options.destdir))
++			options.destdir=Utils.sane_path(options.destdir)
 +		if options.verbose>=1:
 +			self.load('errcheck')
 +		colors={'yes':2,'auto':1,'no':0}[options.colors]
@@ -2697,24 +2781,42 @@ Last-Update: 2014-11-28
 +	def execute(self):
 +		super(OptionsContext,self).execute()
 +		self.parse_args()
++		Utils.alloc_process_pool(options.jobs)
 --- /dev/null
 +++ b/waflib/Runner.py
-@@ -0,0 +1,201 @@
+@@ -0,0 +1,181 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import random,atexit
++import random
 +try:
 +	from queue import Queue
 +except ImportError:
 +	from Queue import Queue
 +from waflib import Utils,Task,Errors,Logs
-+GAP=10
-+class TaskConsumer(Utils.threading.Thread):
-+	def __init__(self):
++GAP=20
++class Consumer(Utils.threading.Thread):
++	def __init__(self,spawner,task):
++		Utils.threading.Thread.__init__(self)
++		self.task=task
++		self.spawner=spawner
++		self.setDaemon(1)
++		self.start()
++	def run(self):
++		try:
++			if not self.spawner.master.stop:
++				self.task.process()
++		finally:
++			self.spawner.sem.release()
++			self.spawner.master.out.put(self.task)
++			self.task=None
++			self.spawner=None
++class Spawner(Utils.threading.Thread):
++	def __init__(self,master):
 +		Utils.threading.Thread.__init__(self)
-+		self.ready=Queue()
++		self.master=master
++		self.sem=Utils.threading.Semaphore(master.numjobs)
 +		self.setDaemon(1)
 +		self.start()
 +	def run(self):
@@ -2723,37 +2825,20 @@ Last-Update: 2014-11-28
 +		except Exception:
 +			pass
 +	def loop(self):
++		master=self.master
 +		while 1:
-+			tsk=self.ready.get()
-+			if not isinstance(tsk,Task.TaskBase):
-+				tsk(self)
-+			else:
-+				tsk.process()
-+pool=Queue()
-+def get_pool():
-+	try:
-+		return pool.get(False)
-+	except Exception:
-+		return TaskConsumer()
-+def put_pool(x):
-+	pool.put(x)
-+def _free_resources():
-+	global pool
-+	lst=[]
-+	while pool.qsize():
-+		lst.append(pool.get())
-+	for x in lst:
-+		x.ready.put(None)
-+	for x in lst:
-+		x.join()
-+	pool=None
-+atexit.register(_free_resources)
++			task=master.ready.get()
++			self.sem.acquire()
++			if not master.stop:
++				task.log_display(task.generator.bld)
++			Consumer(self,task)
 +class Parallel(object):
 +	def __init__(self,bld,j=2):
 +		self.numjobs=j
 +		self.bld=bld
-+		self.outstanding=[]
-+		self.frozen=[]
++		self.outstanding=Utils.deque()
++		self.frozen=Utils.deque()
++		self.ready=Queue(0)
 +		self.out=Queue(0)
 +		self.count=0
 +		self.processed=1
@@ -2761,13 +2846,14 @@ Last-Update: 2014-11-28
 +		self.error=[]
 +		self.biter=None
 +		self.dirty=False
++		self.spawner=Spawner(self)
 +	def get_next_task(self):
 +		if not self.outstanding:
 +			return None
-+		return self.outstanding.pop(0)
++		return self.outstanding.popleft()
 +	def postpone(self,tsk):
 +		if random.randint(0,1):
-+			self.frozen.insert(0,tsk)
++			self.frozen.appendleft(tsk)
 +		else:
 +			self.frozen.append(tsk)
 +	def refill_task_list(self):
@@ -2794,15 +2880,15 @@ Last-Update: 2014-11-28
 +						raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst)))
 +				self.deadlock=self.processed
 +			if self.frozen:
-+				self.outstanding+=self.frozen
-+				self.frozen=[]
++				self.outstanding.extend(self.frozen)
++				self.frozen.clear()
 +			elif not self.count:
 +				self.outstanding.extend(self.biter.next())
 +				self.total=self.bld.total()
 +				break
 +	def add_more_tasks(self,tsk):
 +		if getattr(tsk,'more_tasks',None):
-+			self.outstanding+=tsk.more_tasks
++			self.outstanding.extend(tsk.more_tasks)
 +			self.total+=len(tsk.more_tasks)
 +	def get_out(self):
 +		tsk=self.out.get()
@@ -2812,38 +2898,15 @@ Last-Update: 2014-11-28
 +		self.dirty=True
 +		return tsk
 +	def add_task(self,tsk):
-+		try:
-+			self.pool
-+		except AttributeError:
-+			self.init_task_pool()
 +		self.ready.put(tsk)
-+	def init_task_pool(self):
-+		pool=self.pool=[get_pool()for i in range(self.numjobs)]
-+		self.ready=Queue(0)
-+		def setq(consumer):
-+			consumer.ready=self.ready
-+		for x in pool:
-+			x.ready.put(setq)
-+		return pool
-+	def free_task_pool(self):
-+		def setq(consumer):
-+			consumer.ready=Queue(0)
-+			self.out.put(self)
-+		try:
-+			pool=self.pool
-+		except AttributeError:
-+			pass
-+		else:
-+			for x in pool:
-+				self.ready.put(setq)
-+			for x in pool:
-+				self.get_out()
-+			for x in pool:
-+				put_pool(x)
-+			self.pool=[]
 +	def skip(self,tsk):
 +		tsk.hasrun=Task.SKIPPED
 +	def error_handler(self,tsk):
++		if hasattr(tsk,'scan')and hasattr(tsk,'uid'):
++			try:
++				del self.bld.imp_sigs[tsk.uid()]
++			except KeyError:
++				pass
 +		if not self.bld.keep:
 +			self.stop=True
 +		self.error.append(tsk)
@@ -2883,12 +2946,14 @@ Last-Update: 2014-11-28
 +				break
 +			st=self.task_status(tsk)
 +			if st==Task.RUN_ME:
-+				tsk.position=(self.processed,self.total)
 +				self.count+=1
-+				tsk.master=self
 +				self.processed+=1
 +				if self.numjobs==1:
-+					tsk.process()
++					tsk.log_display(tsk.generator.bld)
++					try:
++						tsk.process()
++					finally:
++						self.out.put(tsk)
 +				else:
 +					self.add_task(tsk)
 +			if st==Task.ASK_LATER:
@@ -2899,11 +2964,11 @@ Last-Update: 2014-11-28
 +				self.add_more_tasks(tsk)
 +		while self.error and self.count:
 +			self.get_out()
++		self.ready.put(None)
 +		assert(self.count==0 or self.stop)
-+		self.free_task_pool()
 --- /dev/null
 +++ b/waflib/Scripting.py
-@@ -0,0 +1,394 @@
+@@ -0,0 +1,398 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -2916,7 +2981,7 @@ Last-Update: 2014-11-28
 +def waf_entry_point(current_directory,version,wafdir):
 +	Logs.init_log()
 +	if Context.WAFVERSION!=version:
-+		Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir))
++		Logs.error('Waf script %r and library %r do not match (directory %r)',version,Context.WAFVERSION,wafdir)
 +		sys.exit(1)
 +	if'--version'in sys.argv:
 +		Context.run_dir=current_directory
@@ -2931,27 +2996,33 @@ Last-Update: 2014-11-28
 +			sys.argv.pop(1)
 +	Context.waf_dir=wafdir
 +	Context.launch_dir=current_directory
-+	no_climb=os.environ.get('NOCLIMB',None)
++	no_climb=os.environ.get('NOCLIMB')
 +	if not no_climb:
 +		for k in no_climb_commands:
 +			for y in sys.argv:
 +				if y.startswith(k):
 +					no_climb=True
 +					break
-+	for x in sys.argv:
++	for i,x in enumerate(sys.argv):
 +		if x.startswith('--top='):
-+			Context.run_dir=Context.top_dir=x[6:]
++			Context.run_dir=Context.top_dir=Utils.sane_path(x[6:])
++			sys.argv[i]='--top='+Context.run_dir
 +		if x.startswith('--out='):
-+			Context.out_dir=x[6:]
++			Context.out_dir=Utils.sane_path(x[6:])
++			sys.argv[i]='--out='+Context.out_dir
 +	cur=current_directory
 +	while cur and not Context.top_dir:
-+		lst=os.listdir(cur)
++		try:
++			lst=os.listdir(cur)
++		except OSError:
++			lst=[]
++			Logs.error('Directory %r is unreadable!',cur)
 +		if Options.lockfile in lst:
 +			env=ConfigSet.ConfigSet()
 +			try:
 +				env.load(os.path.join(cur,Options.lockfile))
 +				ino=os.stat(cur)[stat.ST_INO]
-+			except Exception:
++			except EnvironmentError:
 +				pass
 +			else:
 +				for x in(env.run_dir,env.top_dir,env.out_dir):
@@ -2969,7 +3040,7 @@ Last-Update: 2014-11-28
 +								load=True
 +								break
 +				else:
-+					Logs.warn('invalid lock file in %s'%cur)
++					Logs.warn('invalid lock file in %s',cur)
 +					load=False
 +				if load:
 +					Context.run_dir=env.run_dir
@@ -2993,38 +3064,44 @@ Last-Update: 2014-11-28
 +			ctx.curdir=current_directory
 +			ctx.parse_args()
 +			sys.exit(0)
-+		Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
++		Logs.error('Waf: Run from a directory containing a file named %r',Context.WSCRIPT_FILE)
 +		sys.exit(1)
 +	try:
 +		os.chdir(Context.run_dir)
 +	except OSError:
-+		Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
++		Logs.error('Waf: The folder %r is unreadable',Context.run_dir)
 +		sys.exit(1)
 +	try:
-+		set_main_module(os.path.join(Context.run_dir,Context.WSCRIPT_FILE))
++		set_main_module(os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)))
 +	except Errors.WafError ,e:
 +		Logs.pprint('RED',e.verbose_msg)
 +		Logs.error(str(e))
 +		sys.exit(1)
 +	except Exception ,e:
-+		Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
-+		traceback.print_exc(file=sys.stdout)
-+		sys.exit(2)
-+	try:
-+		run_commands()
-+	except Errors.WafError ,e:
-+		if Logs.verbose>1:
-+			Logs.pprint('RED',e.verbose_msg)
-+		Logs.error(e.msg)
-+		sys.exit(1)
-+	except SystemExit:
-+		raise
-+	except Exception ,e:
++		Logs.error('Waf: The wscript in %r is unreadable',Context.run_dir)
 +		traceback.print_exc(file=sys.stdout)
 +		sys.exit(2)
-+	except KeyboardInterrupt:
-+		Logs.pprint('RED','Interrupted')
-+		sys.exit(68)
++	if'--profile'in sys.argv:
++		import cProfile,pstats
++		cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt')
++		p=pstats.Stats('profi.txt')
++		p.sort_stats('time').print_stats(75)
++	else:
++		try:
++			run_commands()
++		except Errors.WafError ,e:
++			if Logs.verbose>1:
++				Logs.pprint('RED',e.verbose_msg)
++			Logs.error(e.msg)
++			sys.exit(1)
++		except SystemExit:
++			raise
++		except Exception ,e:
++			traceback.print_exc(file=sys.stdout)
++			sys.exit(2)
++		except KeyboardInterrupt:
++			Logs.pprint('RED','Interrupted')
++			sys.exit(68)
 +def set_main_module(file_path):
 +	Context.g_module=Context.load_module(file_path)
 +	Context.g_module.root_path=file_path
@@ -3032,7 +3109,7 @@ Last-Update: 2014-11-28
 +		name=obj.__name__
 +		if not name in Context.g_module.__dict__:
 +			setattr(Context.g_module,name,obj)
-+	for k in(update,dist,distclean,distcheck,update):
++	for k in(dist,distclean,distcheck):
 +		set_def(k)
 +	if not'init'in Context.g_module.__dict__:
 +		Context.g_module.init=Utils.nada
@@ -3073,22 +3150,17 @@ Last-Update: 2014-11-28
 +	while Options.commands:
 +		cmd_name=Options.commands.pop(0)
 +		ctx=run_command(cmd_name)
-+		Logs.info('%r finished successfully (%s)'%(cmd_name,str(ctx.log_timer)))
++		Logs.info('%r finished successfully (%s)',cmd_name,ctx.log_timer)
 +	run_command('shutdown')
-+def _can_distclean(name):
-+	for k in'.o .moc .exe'.split():
-+		if name.endswith(k):
-+			return True
-+	return False
 +def distclean_dir(dirname):
 +	for(root,dirs,files)in os.walk(dirname):
 +		for f in files:
-+			if _can_distclean(f):
++			if f.endswith(('.o','.moc','.exe')):
 +				fname=os.path.join(root,f)
 +				try:
 +					os.remove(fname)
 +				except OSError:
-+					Logs.warn('Could not remove %r'%fname)
++					Logs.warn('Could not remove %r',fname)
 +	for x in(Context.DBFILE,'config.log'):
 +		try:
 +			os.remove(x)
@@ -3106,16 +3178,14 @@ Last-Update: 2014-11-28
 +			try:
 +				proj=ConfigSet.ConfigSet(f)
 +			except IOError:
-+				Logs.warn('Could not read %r'%f)
++				Logs.warn('Could not read %r',f)
 +				continue
 +			if proj['out_dir']!=proj['top_dir']:
 +				try:
 +					shutil.rmtree(proj['out_dir'])
-+				except IOError:
-+					pass
-+				except OSError ,e:
++				except EnvironmentError ,e:
 +					if e.errno!=errno.ENOENT:
-+						Logs.warn('Could not remove %r'%proj['out_dir'])
++						Logs.warn('Could not remove %r',proj['out_dir'])
 +			else:
 +				distclean_dir(proj['out_dir'])
 +			for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
@@ -3124,7 +3194,7 @@ Last-Update: 2014-11-28
 +					os.remove(p)
 +				except OSError ,e:
 +					if e.errno!=errno.ENOENT:
-+						Logs.warn('Could not remove %r'%p)
++						Logs.warn('Could not remove %r',p)
 +		if not Options.commands:
 +			for x in'.waf-1. waf-1. .waf3-1. waf3-1.'.split():
 +				if f.startswith(x):
@@ -3152,13 +3222,13 @@ Last-Update: 2014-11-28
 +			pass
 +		files=self.get_files()
 +		if self.algo.startswith('tar.'):
-+			tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
++			tar=tarfile.open(node.abspath(),'w:'+self.algo.replace('tar.',''))
 +			for x in files:
 +				self.add_tar_file(x,tar)
 +			tar.close()
 +		elif self.algo=='zip':
 +			import zipfile
-+			zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
++			zip=zipfile.ZipFile(node.abspath(),'w',compression=zipfile.ZIP_DEFLATED)
 +			for x in files:
 +				archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
 +				zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
@@ -3166,14 +3236,12 @@ Last-Update: 2014-11-28
 +		else:
 +			self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip')
 +		try:
-+			from hashlib import sha1 as sha
++			from hashlib import sha1
 +		except ImportError:
-+			from sha import sha
-+		try:
-+			digest=" (sha=%r)"%sha(node.read()).hexdigest()
-+		except Exception:
 +			digest=''
-+		Logs.info('New archive created: %s%s'%(self.arch_name,digest))
++		else:
++			digest=' (sha=%r)'%sha1(node.read(flags='rb')).hexdigest()
++		Logs.info('New archive created: %s%s',self.arch_name,digest)
 +	def get_tar_path(self,node):
 +		return node.abspath()
 +	def add_tar_file(self,x,tar):
@@ -3183,13 +3251,14 @@ Last-Update: 2014-11-28
 +		tinfo.gid=0
 +		tinfo.uname='root'
 +		tinfo.gname='root'
-+		fu=None
-+		try:
++		if os.path.isfile(p):
 +			fu=open(p,'rb')
-+			tar.addfile(tinfo,fileobj=fu)
-+		finally:
-+			if fu:
++			try:
++				tar.addfile(tinfo,fileobj=fu)
++			finally:
 +				fu.close()
++		else:
++			tar.addfile(tinfo)
 +	def get_tar_prefix(self):
 +		try:
 +			return self.tar_prefix
@@ -3237,14 +3306,12 @@ Last-Update: 2014-11-28
 +		self.check()
 +	def check(self):
 +		import tempfile,tarfile
-+		t=None
 +		try:
 +			t=tarfile.open(self.get_arch_name())
 +			for x in t:
 +				t.extract(x)
 +		finally:
-+			if t:
-+				t.close()
++			t.close()
 +		cfg=[]
 +		if Options.options.distcheck_args:
 +			cfg=shlex.split(Options.options.distcheck_args)
@@ -3253,23 +3320,13 @@ Last-Update: 2014-11-28
 +		instdir=tempfile.mkdtemp('.inst',self.get_base_name())
 +		ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait()
 +		if ret:
-+			raise Errors.WafError('distcheck failed with code %i'%ret)
++			raise Errors.WafError('distcheck failed with code %r'%ret)
 +		if os.path.exists(instdir):
 +			raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
 +		shutil.rmtree(self.get_base_name())
 +def distcheck(ctx):
 +	'''checks if the project compiles (tarball from 'dist')'''
 +	pass
-+def update(ctx):
-+	lst=Options.options.files.split(',')
-+	if not lst:
-+		lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')]
-+	for x in lst:
-+		tool=x.replace('.py','')
-+		try:
-+			Configure.download_tool(tool,force=True,ctx=ctx)
-+		except Errors.WafError:
-+			Logs.error('Could not find the tool %s in the remote repository'%x)
 +def autoconfigure(execute_method):
 +	def execute(self):
 +		if not Configure.autoconfig:
@@ -3278,7 +3335,7 @@ Last-Update: 2014-11-28
 +		do_config=False
 +		try:
 +			env.load(os.path.join(Context.top_dir,Options.lockfile))
-+		except Exception:
++		except EnvironmentError:
 +			Logs.warn('Configuring the project')
 +			do_config=True
 +		else:
@@ -3286,26 +3343,38 @@ Last-Update: 2014-11-28
 +				do_config=True
 +			else:
 +				h=0
-+				for f in env['files']:
-+					h=Utils.h_list((h,Utils.readf(f,'rb')))
-+				do_config=h!=env.hash
++				for f in env.files:
++					try:
++						h=Utils.h_list((h,Utils.readf(f,'rb')))
++					except EnvironmentError:
++						do_config=True
++						break
++				else:
++					do_config=h!=env.hash
 +		if do_config:
-+			Options.commands.insert(0,self.cmd)
-+			Options.commands.insert(0,'configure')
++			cmd=env.config_cmd or'configure'
 +			if Configure.autoconfig=='clobber':
++				tmp=Options.options.__dict__
 +				Options.options.__dict__=env.options
-+			return
-+		return execute_method(self)
++				try:
++					run_command(cmd)
++				finally:
++					Options.options.__dict__=tmp
++			else:
++				run_command(cmd)
++			run_command(self.cmd)
++		else:
++			return execute_method(self)
 +	return execute
 +Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
 --- /dev/null
 +++ b/waflib/Task.py
-@@ -0,0 +1,659 @@
+@@ -0,0 +1,708 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,re,sys
++import os,re,sys,tempfile
 +from waflib import Utils,Logs,Errors
 +NOT_RUN=0
 +MISSING=1
@@ -3321,46 +3390,48 @@ Last-Update: 2014-11-28
 +	env = tsk.env
 +	gen = tsk.generator
 +	bld = gen.bld
-+	wd = getattr(tsk, 'cwd', None)
++	cwdx = tsk.get_cwd()
 +	p = env.get_flat
 +	tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
-+	return tsk.exec_command(cmd, cwd=wd, env=env.env or None)
++	return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None)
 +'''
 +COMPILE_TEMPLATE_NOSHELL='''
 +def f(tsk):
 +	env = tsk.env
 +	gen = tsk.generator
 +	bld = gen.bld
-+	wd = getattr(tsk, 'cwd', None)
++	cwdx = tsk.get_cwd()
 +	def to_list(xx):
 +		if isinstance(xx, str): return [xx]
 +		return xx
-+	tsk.last_cmd = lst = []
++	def merge(lst1, lst2):
++		if lst1 and lst2:
++			return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:]
++		return lst1 + lst2
++	lst = []
 +	%s
-+	lst = [x for x in lst if x]
-+	return tsk.exec_command(lst, cwd=wd, env=env.env or None)
++	if '' in lst:
++		lst = [x for x in lst if x]
++	tsk.last_cmd = lst
++	return tsk.exec_command(lst, cwd=cwdx, env=env.env or None)
 +'''
 +classes={}
 +class store_task_type(type):
 +	def __init__(cls,name,bases,dict):
 +		super(store_task_type,cls).__init__(name,bases,dict)
 +		name=cls.__name__
-+		if name.endswith('_task'):
-+			name=name.replace('_task','')
 +		if name!='evil'and name!='TaskBase':
 +			global classes
 +			if getattr(cls,'run_str',None):
 +				(f,dvars)=compile_fun(cls.run_str,cls.shell)
-+				cls.hcode=cls.run_str
++				cls.hcode=Utils.h_cmd(cls.run_str)
 +				cls.orig_run_str=cls.run_str
 +				cls.run_str=None
 +				cls.run=f
 +				cls.vars=list(set(cls.vars+dvars))
 +				cls.vars.sort()
 +			elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
-+				cls.hcode=Utils.h_fun(cls.run)
-+			if sys.hexversion>0x3000000:
-+				cls.hcode=cls.hcode.encode('iso8859-1','xmlcharrefreplace')
++				cls.hcode=Utils.h_cmd(cls.run)
 +			getattr(cls,'register',classes)[name]=cls
 +evil=store_task_type('evil',(object,),{})
 +class TaskBase(evil):
@@ -3370,6 +3441,8 @@ Last-Update: 2014-11-28
 +	before=[]
 +	after=[]
 +	hcode=''
++	keep_last_cmd=False
++	__slots__=('hasrun','generator')
 +	def __init__(self,*k,**kw):
 +		self.hasrun=NOT_RUN
 +		try:
@@ -3382,40 +3455,70 @@ Last-Update: 2014-11-28
 +		if hasattr(self,'fun'):
 +			return self.fun.__name__
 +		return self.__class__.__name__
-+	def __hash__(self):
-+		return id(self)
 +	def keyword(self):
 +		if hasattr(self,'fun'):
 +			return'Function'
 +		return'Processing'
-+	def exec_command(self,cmd,**kw):
++	def get_cwd(self):
 +		bld=self.generator.bld
-+		try:
-+			if not kw.get('cwd',None):
-+				kw['cwd']=bld.cwd
-+		except AttributeError:
-+			bld.cwd=kw['cwd']=bld.variant_dir
-+		return bld.exec_command(cmd,**kw)
++		ret=getattr(self,'cwd',None)or getattr(bld,'cwd',bld.bldnode)
++		if isinstance(ret,str):
++			if os.path.isabs(ret):
++				ret=bld.root.make_node(ret)
++			else:
++				ret=self.generator.path.make_node(ret)
++		return ret
++	def quote_flag(self,x):
++		old=x
++		if'\\'in x:
++			x=x.replace('\\','\\\\')
++		if'"'in x:
++			x=x.replace('"','\\"')
++		if old!=x or' 'in x or'\t'in x or"'"in x:
++			x='"%s"'%x
++		return x
++	def split_argfile(self,cmd):
++		return([cmd[0]],[self.quote_flag(x)for x in cmd[1:]])
++	def exec_command(self,cmd,**kw):
++		if not'cwd'in kw:
++			kw['cwd']=self.get_cwd()
++		if hasattr(self,'timeout'):
++			kw['timeout']=self.timeout
++		if self.env.PATH:
++			env=kw['env']=dict(kw.get('env')or self.env.env or os.environ)
++			env['PATH']=self.env.PATH if isinstance(self.env.PATH,str)else os.pathsep.join(self.env.PATH)
++		if not isinstance(cmd,str)and(len(repr(cmd))>=8192 if Utils.is_win32 else len(cmd)>200000):
++			cmd,args=self.split_argfile(cmd)
++			try:
++				(fd,tmp)=tempfile.mkstemp()
++				os.write(fd,'\r\n'.join(args))
++				os.close(fd)
++				if Logs.verbose:
++					Logs.debug('argfile: @%r -> %r',tmp,args)
++				return self.generator.bld.exec_command(cmd+['@'+tmp],**kw)
++			finally:
++				try:
++					os.remove(tmp)
++				except OSError:
++					pass
++		else:
++			return self.generator.bld.exec_command(cmd,**kw)
 +	def runnable_status(self):
 +		return RUN_ME
++	def uid(self):
++		return Utils.SIG_NIL
 +	def process(self):
-+		m=self.master
-+		if m.stop:
-+			m.out.put(self)
-+			return
++		m=self.generator.bld.producer
 +		try:
 +			del self.generator.bld.task_sigs[self.uid()]
 +		except KeyError:
 +			pass
 +		try:
-+			self.generator.bld.returned_tasks.append(self)
-+			self.log_display(self.generator.bld)
 +			ret=self.run()
 +		except Exception:
 +			self.err_msg=Utils.ex_stack()
 +			self.hasrun=EXCEPTION
 +			m.error_handler(self)
-+			m.out.put(self)
 +			return
 +		if ret:
 +			self.err_code=ret
@@ -3432,7 +3535,6 @@ Last-Update: 2014-11-28
 +				self.hasrun=SUCCESS
 +		if self.hasrun!=SUCCESS:
 +			m.error_handler(self)
-+		m.out.put(self)
 +	def run(self):
 +		if hasattr(self,'fun'):
 +			return self.fun(self)
@@ -3457,7 +3559,7 @@ Last-Update: 2014-11-28
 +	def display(self):
 +		col1=Logs.colors(self.color)
 +		col2=Logs.colors.NORMAL
-+		master=self.master
++		master=self.generator.bld.producer
 +		def cur():
 +			tmp=-1
 +			if hasattr(master,'ready'):
@@ -3486,17 +3588,15 @@ Last-Update: 2014-11-28
 +		if kw:
 +			kw+=' '
 +		return fs%(cur(),total,kw,col1,s,col2)
-+	def attr(self,att,default=None):
-+		ret=getattr(self,att,self)
-+		if ret is self:return getattr(self.__class__,att,default)
-+		return ret
 +	def hash_constraints(self):
 +		cls=self.__class__
 +		tup=(str(cls.before),str(cls.after),str(cls.ext_in),str(cls.ext_out),cls.__name__,cls.hcode)
-+		h=hash(tup)
-+		return h
++		return hash(tup)
 +	def format_error(self):
-+		msg=getattr(self,'last_cmd','')
++		if Logs.verbose:
++			msg=': %r\n%r'%(self,getattr(self,'last_cmd',''))
++		else:
++			msg=' (run with -v to display more information)'
 +		name=getattr(self.generator,'name','')
 +		if getattr(self,"err_msg",None):
 +			return self.err_msg
@@ -3504,11 +3604,11 @@ Last-Update: 2014-11-28
 +			return'task in %r was not executed for some reason: %r'%(name,self)
 +		elif self.hasrun==CRASHED:
 +			try:
-+				return' -> task in %r failed (exit status %r): %r\n%r'%(name,self.err_code,self,msg)
++				return' -> task in %r failed with exit status %r%s'%(name,self.err_code,msg)
 +			except AttributeError:
-+				return' -> task in %r failed: %r\n%r'%(name,self,msg)
++				return' -> task in %r failed%s'%(name,msg)
 +		elif self.hasrun==MISSING:
-+			return' -> missing files in %r: %r\n%r'%(name,self,msg)
++			return' -> missing files in %r%s'%(name,msg)
 +		else:
 +			return'invalid status for task in %r: %r'%(name,self.hasrun)
 +	def colon(self,var1,var2):
@@ -3529,6 +3629,7 @@ Last-Update: 2014-11-28
 +			return lst
 +class Task(TaskBase):
 +	vars=[]
++	always_run=False
 +	shell=False
 +	def __init__(self,*k,**kw):
 +		TaskBase.__init__(self,*k,**kw)
@@ -3536,11 +3637,11 @@ Last-Update: 2014-11-28
 +		self.inputs=[]
 +		self.outputs=[]
 +		self.dep_nodes=[]
-+		self.run_after=set([])
++		self.run_after=set()
 +	def __str__(self):
 +		name=self.__class__.__name__
 +		if self.outputs:
-+			if(name.endswith('lib')or name.endswith('program'))or not self.inputs:
++			if name.endswith(('lib','program'))or not self.inputs:
 +				node=self.outputs[0]
 +				return node.path_from(node.ctx.launch_node())
 +		if not(self.inputs or self.outputs):
@@ -3552,10 +3653,10 @@ Last-Update: 2014-11-28
 +		tgt_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.outputs])
 +		if self.outputs:sep=' -> '
 +		else:sep=''
-+		return'%s: %s%s%s'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
++		return'%s: %s%s%s'%(self.__class__.__name__,src_str,sep,tgt_str)
 +	def keyword(self):
 +		name=self.__class__.__name__
-+		if name.endswith('lib')or name.endswith('program'):
++		if name.endswith(('lib','program')):
 +			return'Linking'
 +		if len(self.inputs)==1 and len(self.outputs)==1:
 +			return'Compiling'
@@ -3577,9 +3678,8 @@ Last-Update: 2014-11-28
 +		try:
 +			return self.uid_
 +		except AttributeError:
-+			m=Utils.md5()
++			m=Utils.md5(self.__class__.__name__)
 +			up=m.update
-+			up(self.__class__.__name__)
 +			for x in self.inputs+self.outputs:
 +				up(x.abspath())
 +			self.uid_=m.digest()
@@ -3594,10 +3694,11 @@ Last-Update: 2014-11-28
 +		assert isinstance(task,TaskBase)
 +		self.run_after.add(task)
 +	def signature(self):
-+		try:return self.cache_sig
-+		except AttributeError:pass
-+		self.m=Utils.md5()
-+		self.m.update(self.hcode)
++		try:
++			return self.cache_sig
++		except AttributeError:
++			pass
++		self.m=Utils.md5(self.hcode)
 +		self.sig_explicit_deps()
 +		self.sig_vars()
 +		if self.scan:
@@ -3611,79 +3712,72 @@ Last-Update: 2014-11-28
 +		for t in self.run_after:
 +			if not t.hasrun:
 +				return ASK_LATER
-+		bld=self.generator.bld
 +		try:
 +			new_sig=self.signature()
 +		except Errors.TaskNotReady:
 +			return ASK_LATER
++		bld=self.generator.bld
 +		key=self.uid()
 +		try:
 +			prev_sig=bld.task_sigs[key]
 +		except KeyError:
-+			Logs.debug("task: task %r must run as it was never run before or the task code changed"%self)
++			Logs.debug('task: task %r must run: it was never run before or the task code changed',self)
 +			return RUN_ME
-+		for node in self.outputs:
-+			try:
-+				if node.sig!=new_sig:
-+					return RUN_ME
-+			except AttributeError:
-+				Logs.debug("task: task %r must run as the output nodes do not exist"%self)
-+				return RUN_ME
 +		if new_sig!=prev_sig:
++			Logs.debug('task: task %r must run: the task signature changed',self)
 +			return RUN_ME
-+		return SKIP_ME
++		for node in self.outputs:
++			sig=bld.node_sigs.get(node)
++			if not sig:
++				Logs.debug('task: task %r must run: an output node has no signature',self)
++				return RUN_ME
++			if sig!=key:
++				Logs.debug('task: task %r must run: an output node was produced by another task',self)
++				return RUN_ME
++			if not node.exists():
++				Logs.debug('task: task %r must run: an output node does not exist',self)
++				return RUN_ME
++		return(self.always_run and RUN_ME)or SKIP_ME
 +	def post_run(self):
 +		bld=self.generator.bld
-+		sig=self.signature()
 +		for node in self.outputs:
-+			try:
-+				os.stat(node.abspath())
-+			except OSError:
++			if not node.exists():
 +				self.hasrun=MISSING
 +				self.err_msg='-> missing file: %r'%node.abspath()
 +				raise Errors.WafError(self.err_msg)
-+			node.sig=node.cache_sig=sig
-+		bld.task_sigs[self.uid()]=self.cache_sig
++			bld.node_sigs[node]=self.uid()
++		bld.task_sigs[self.uid()]=self.signature()
++		if not self.keep_last_cmd:
++			try:
++				del self.last_cmd
++			except AttributeError:
++				pass
 +	def sig_explicit_deps(self):
 +		bld=self.generator.bld
 +		upd=self.m.update
 +		for x in self.inputs+self.dep_nodes:
-+			try:
-+				upd(x.get_bld_sig())
-+			except(AttributeError,TypeError):
-+				raise Errors.WafError('Missing node signature for %r (required by %r)'%(x,self))
++			upd(x.get_bld_sig())
 +		if bld.deps_man:
 +			additional_deps=bld.deps_man
 +			for x in self.inputs+self.outputs:
 +				try:
-+					d=additional_deps[id(x)]
++					d=additional_deps[x]
 +				except KeyError:
 +					continue
 +				for v in d:
 +					if isinstance(v,bld.root.__class__):
-+						try:
-+							v=v.get_bld_sig()
-+						except AttributeError:
-+							raise Errors.WafError('Missing node signature for %r (required by %r)'%(v,self))
++						v=v.get_bld_sig()
 +					elif hasattr(v,'__call__'):
 +						v=v()
 +					upd(v)
-+		return self.m.digest()
 +	def sig_vars(self):
-+		bld=self.generator.bld
-+		env=self.env
-+		upd=self.m.update
-+		act_sig=bld.hash_env_vars(env,self.__class__.vars)
-+		upd(act_sig)
-+		dep_vars=getattr(self,'dep_vars',None)
-+		if dep_vars:
-+			upd(bld.hash_env_vars(env,dep_vars))
-+		return self.m.digest()
++		sig=self.generator.bld.hash_env_vars(self.env,self.vars)
++		self.m.update(sig)
 +	scan=None
 +	def sig_implicit_deps(self):
 +		bld=self.generator.bld
 +		key=self.uid()
-+		prev=bld.task_sigs.get((key,'imp'),[])
++		prev=bld.imp_sigs.get(key,[])
 +		if prev:
 +			try:
 +				if prev==self.compute_sig_implicit_deps():
@@ -3692,38 +3786,27 @@ Last-Update: 2014-11-28
 +				raise
 +			except EnvironmentError:
 +				for x in bld.node_deps.get(self.uid(),[]):
-+					if not x.is_bld():
++					if not x.is_bld()and not x.exists():
 +						try:
-+							os.stat(x.abspath())
-+						except OSError:
-+							try:
-+								del x.parent.children[x.name]
-+							except KeyError:
-+								pass
-+			del bld.task_sigs[(key,'imp')]
++							del x.parent.children[x.name]
++						except KeyError:
++							pass
++			del bld.imp_sigs[key]
 +			raise Errors.TaskRescan('rescan')
-+		(nodes,names)=self.scan()
++		(bld.node_deps[key],bld.raw_deps[key])=self.scan()
 +		if Logs.verbose:
-+			Logs.debug('deps: scanner for %s returned %s %s'%(str(self),str(nodes),str(names)))
-+		bld.node_deps[key]=nodes
-+		bld.raw_deps[key]=names
-+		self.are_implicit_nodes_ready()
++			Logs.debug('deps: scanner for %s: %r; unresolved: %r',self,bld.node_deps[key],bld.raw_deps[key])
 +		try:
-+			bld.task_sigs[(key,'imp')]=sig=self.compute_sig_implicit_deps()
-+		except Exception:
-+			if Logs.verbose:
-+				for k in bld.node_deps.get(self.uid(),[]):
-+					try:
-+						k.get_bld_sig()
-+					except Exception:
-+						Logs.warn('Missing signature for node %r (may cause rebuilds)'%k)
-+		else:
-+			return sig
++			bld.imp_sigs[key]=self.compute_sig_implicit_deps()
++		except EnvironmentError:
++			for k in bld.node_deps.get(self.uid(),[]):
++				if not k.exists():
++					Logs.warn('Dependency %r for %r is missing: check the task declaration and the build order!',k,self)
++			raise
 +	def compute_sig_implicit_deps(self):
 +		upd=self.m.update
-+		bld=self.generator.bld
 +		self.are_implicit_nodes_ready()
-+		for k in bld.node_deps.get(self.uid(),[]):
++		for k in self.generator.bld.node_deps.get(self.uid(),[]):
 +			upd(k.get_bld_sig())
 +		return self.m.digest()
 +	def are_implicit_nodes_ready(self):
@@ -3753,9 +3836,8 @@ Last-Update: 2014-11-28
 +		try:
 +			return self.uid_
 +		except AttributeError:
-+			m=Utils.md5()
++			m=Utils.md5(self.__class__.__name__.encode('iso8859-1','xmlcharrefreplace'))
 +			up=m.update
-+			up(self.__class__.__name__.encode('iso8859-1','xmlcharrefreplace'))
 +			for x in self.inputs+self.outputs:
 +				up(x.abspath().encode('iso8859-1','xmlcharrefreplace'))
 +			self.uid_=m.digest()
@@ -3810,164 +3892,200 @@ Last-Update: 2014-11-28
 +	dc={}
 +	exec(c,dc)
 +	return dc['f']
-+reg_act=re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})",re.M)
++re_cond=re.compile('(?P<var>\w+)|(?P<or>\|)|(?P<and>&)')
++re_novar=re.compile(r'^(SRC|TGT)\W+.*?$')
++reg_act=re.compile(r'(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})',re.M)
 +def compile_fun_shell(line):
 +	extr=[]
 +	def repl(match):
 +		g=match.group
-+		if g('dollar'):return"$"
-+		elif g('backslash'):return'\\\\'
-+		elif g('subst'):extr.append((g('var'),g('code')));return"%s"
++		if g('dollar'):
++			return"$"
++		elif g('backslash'):
++			return'\\\\'
++		elif g('subst'):
++			extr.append((g('var'),g('code')))
++			return"%s"
 +		return None
 +	line=reg_act.sub(repl,line)or line
-+	parm=[]
 +	dvars=[]
++	def replc(m):
++		if m.group('and'):
++			return' and '
++		elif m.group('or'):
++			return' or '
++		else:
++			x=m.group('var')
++			if x not in dvars:
++				dvars.append(x)
++			return'env[%r]'%x
++	parm=[]
 +	app=parm.append
 +	for(var,meth)in extr:
 +		if var=='SRC':
 +			if meth:app('tsk.inputs%s'%meth)
-+			else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])')
++			else:app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
 +		elif var=='TGT':
 +			if meth:app('tsk.outputs%s'%meth)
-+			else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])')
++			else:app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
 +		elif meth:
 +			if meth.startswith(':'):
++				if var not in dvars:
++					dvars.append(var)
 +				m=meth[1:]
 +				if m=='SRC':
-+					m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
++					m='[a.path_from(cwdx) for a in tsk.inputs]'
 +				elif m=='TGT':
-+					m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
++					m='[a.path_from(cwdx) for a in tsk.outputs]'
++				elif re_novar.match(m):
++					m='[tsk.inputs%s]'%m[3:]
++				elif re_novar.match(m):
++					m='[tsk.outputs%s]'%m[3:]
 +				elif m[:3]not in('tsk','gen','bld'):
-+					dvars.extend([var,meth[1:]])
++					dvars.append(meth[1:])
 +					m='%r'%m
 +				app('" ".join(tsk.colon(%r, %s))'%(var,m))
++			elif meth.startswith('?'):
++				expr=re_cond.sub(replc,meth[1:])
++				app('p(%r) if (%s) else ""'%(var,expr))
 +			else:
 +				app('%s%s'%(var,meth))
 +		else:
-+			if not var in dvars:dvars.append(var)
++			if var not in dvars:
++				dvars.append(var)
 +			app("p('%s')"%var)
 +	if parm:parm="%% (%s) "%(',\n\t\t'.join(parm))
 +	else:parm=''
 +	c=COMPILE_TEMPLATE_SHELL%(line,parm)
-+	Logs.debug('action: %s'%c.strip().splitlines())
++	Logs.debug('action: %s',c.strip().splitlines())
 +	return(funex(c),dvars)
++reg_act_noshell=re.compile(r"(?P<space>\s+)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})|(?P<text>([^$ \t\n\r\f\v]|\$\$)+)",re.M)
 +def compile_fun_noshell(line):
-+	extr=[]
-+	def repl(match):
-+		g=match.group
-+		if g('dollar'):return"$"
-+		elif g('backslash'):return'\\'
-+		elif g('subst'):extr.append((g('var'),g('code')));return"<<|@|>>"
-+		return None
-+	line2=reg_act.sub(repl,line)
-+	params=line2.split('<<|@|>>')
-+	assert(extr)
 +	buf=[]
 +	dvars=[]
++	merge=False
 +	app=buf.append
-+	for x in range(len(extr)):
-+		params[x]=params[x].strip()
-+		if params[x]:
-+			app("lst.extend(%r)"%params[x].split())
-+		(var,meth)=extr[x]
-+		if var=='SRC':
-+			if meth:app('lst.append(tsk.inputs%s)'%meth)
-+			else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])")
-+		elif var=='TGT':
-+			if meth:app('lst.append(tsk.outputs%s)'%meth)
-+			else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])")
-+		elif meth:
-+			if meth.startswith(':'):
-+				m=meth[1:]
-+				if m=='SRC':
-+					m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
-+				elif m=='TGT':
-+					m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
-+				elif m[:3]not in('tsk','gen','bld'):
-+					dvars.extend([var,m])
-+					m='%r'%m
-+				app('lst.extend(tsk.colon(%r, %s))'%(var,m))
++	def replc(m):
++		if m.group('and'):
++			return' and '
++		elif m.group('or'):
++			return' or '
++		else:
++			x=m.group('var')
++			if x not in dvars:
++				dvars.append(x)
++			return'env[%r]'%x
++	for m in reg_act_noshell.finditer(line):
++		if m.group('space'):
++			merge=False
++			continue
++		elif m.group('text'):
++			app('[%r]'%m.group('text').replace('$$','$'))
++		elif m.group('subst'):
++			var=m.group('var')
++			code=m.group('code')
++			if var=='SRC':
++				if code:
++					app('[tsk.inputs%s]'%code)
++				else:
++					app('[a.path_from(cwdx) for a in tsk.inputs]')
++			elif var=='TGT':
++				if code:
++					app('[tsk.outputs%s]'%code)
++				else:
++					app('[a.path_from(cwdx) for a in tsk.outputs]')
++			elif code:
++				if code.startswith(':'):
++					if not var in dvars:
++						dvars.append(var)
++					m=code[1:]
++					if m=='SRC':
++						m='[a.path_from(cwdx) for a in tsk.inputs]'
++					elif m=='TGT':
++						m='[a.path_from(cwdx) for a in tsk.outputs]'
++					elif re_novar.match(m):
++						m='[tsk.inputs%s]'%m[3:]
++					elif re_novar.match(m):
++						m='[tsk.outputs%s]'%m[3:]
++					elif m[:3]not in('tsk','gen','bld'):
++						dvars.append(m)
++						m='%r'%m
++					app('tsk.colon(%r, %s)'%(var,m))
++				elif code.startswith('?'):
++					expr=re_cond.sub(replc,code[1:])
++					app('to_list(env[%r] if (%s) else [])'%(var,expr))
++				else:
++					app('gen.to_list(%s%s)'%(var,code))
 +			else:
-+				app('lst.extend(gen.to_list(%s%s))'%(var,meth))
-+		else:
-+			app('lst.extend(to_list(env[%r]))'%var)
-+			if not var in dvars:dvars.append(var)
-+	if extr:
-+		if params[-1]:
-+			app("lst.extend(%r)"%params[-1].split())
++				app('to_list(env[%r])'%var)
++				if not var in dvars:
++					dvars.append(var)
++		if merge:
++			tmp='merge(%s, %s)'%(buf[-2],buf[-1])
++			del buf[-1]
++			buf[-1]=tmp
++		merge=True
++	buf=['lst.extend(%s)'%x for x in buf]
 +	fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf)
-+	Logs.debug('action: %s'%fun.strip().splitlines())
++	Logs.debug('action: %s',fun.strip().splitlines())
 +	return(funex(fun),dvars)
 +def compile_fun(line,shell=False):
-+	if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
-+		shell=True
++	if isinstance(line,str):
++		if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
++			shell=True
++	else:
++		dvars_lst=[]
++		funs_lst=[]
++		for x in line:
++			if isinstance(x,str):
++				fun,dvars=compile_fun(x,shell)
++				dvars_lst+=dvars
++				funs_lst.append(fun)
++			else:
++				funs_lst.append(x)
++		def composed_fun(task):
++			for x in funs_lst:
++				ret=x(task)
++				if ret:
++					return ret
++			return None
++		return composed_fun,dvars_lst
 +	if shell:
 +		return compile_fun_shell(line)
 +	else:
 +		return compile_fun_noshell(line)
 +def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
-+	params={'vars':vars or[],'color':color,'name':name,'ext_in':Utils.to_list(ext_in),'ext_out':Utils.to_list(ext_out),'before':Utils.to_list(before),'after':Utils.to_list(after),'shell':shell,'scan':scan,}
-+	if isinstance(func,str):
++	params={'vars':vars or[],'color':color,'name':name,'shell':shell,'scan':scan,}
++	if isinstance(func,str)or isinstance(func,tuple):
 +		params['run_str']=func
 +	else:
 +		params['run']=func
 +	cls=type(Task)(name,(Task,),params)
 +	global classes
 +	classes[name]=cls
++	if ext_in:
++		cls.ext_in=Utils.to_list(ext_in)
++	if ext_out:
++		cls.ext_out=Utils.to_list(ext_out)
++	if before:
++		cls.before=Utils.to_list(before)
++	if after:
++		cls.after=Utils.to_list(after)
 +	return cls
 +def always_run(cls):
-+	old=cls.runnable_status
-+	def always(self):
-+		ret=old(self)
-+		if ret==SKIP_ME:
-+			ret=RUN_ME
-+		return ret
-+	cls.runnable_status=always
++	Logs.warn('This decorator is deprecated, set always_run on the task class instead!')
++	cls.always_run=True
 +	return cls
 +def update_outputs(cls):
-+	old_post_run=cls.post_run
-+	def post_run(self):
-+		old_post_run(self)
-+		for node in self.outputs:
-+			node.sig=node.cache_sig=Utils.h_file(node.abspath())
-+			self.generator.bld.task_sigs[node.abspath()]=self.uid()
-+	cls.post_run=post_run
-+	old_runnable_status=cls.runnable_status
-+	def runnable_status(self):
-+		status=old_runnable_status(self)
-+		if status!=RUN_ME:
-+			return status
-+		try:
-+			bld=self.generator.bld
-+			prev_sig=bld.task_sigs[self.uid()]
-+			if prev_sig==self.signature():
-+				for x in self.outputs:
-+					if not x.is_child_of(bld.bldnode):
-+						x.sig=Utils.h_file(x.abspath())
-+					if not x.sig or bld.task_sigs[x.abspath()]!=self.uid():
-+						return RUN_ME
-+				return SKIP_ME
-+		except OSError:
-+			pass
-+		except IOError:
-+			pass
-+		except KeyError:
-+			pass
-+		except IndexError:
-+			pass
-+		except AttributeError:
-+			pass
-+		return RUN_ME
-+	cls.runnable_status=runnable_status
 +	return cls
 --- /dev/null
 +++ b/waflib/TaskGen.py
-@@ -0,0 +1,416 @@
+@@ -0,0 +1,458 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import copy,re,os
++import copy,re,os,functools
 +from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
 +feats=Utils.defaultdict(set)
 +HEADER_EXTS=['.h','.hpp','.hxx','.hh']
@@ -3978,8 +4096,6 @@ Last-Update: 2014-11-28
 +		self.source=''
 +		self.target=''
 +		self.meths=[]
-+		self.prec=Utils.defaultdict(list)
-+		self.mappings={}
 +		self.features=[]
 +		self.tasks=[]
 +		if not'bld'in kw:
@@ -3991,20 +4107,22 @@ Last-Update: 2014-11-28
 +			self.env=self.bld.env.derive()
 +			self.path=self.bld.path
 +			try:
-+				self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1
++				self.idx=self.bld.idx[self.path]=self.bld.idx.get(self.path,0)+1
 +			except AttributeError:
 +				self.bld.idx={}
-+				self.idx=self.bld.idx[id(self.path)]=1
++				self.idx=self.bld.idx[self.path]=1
 +		for key,val in kw.items():
 +			setattr(self,key,val)
 +	def __str__(self):
 +		return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
 +	def __repr__(self):
 +		lst=[]
-+		for x in self.__dict__.keys():
++		for x in self.__dict__:
 +			if x not in('env','bld','compiled_tasks','tasks'):
 +				lst.append("%s=%s"%(x,repr(getattr(self,x))))
 +		return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
++	def get_cwd(self):
++		return self.bld.bldnode
 +	def get_name(self):
 +		try:
 +			return self._name
@@ -4019,22 +4137,25 @@ Last-Update: 2014-11-28
 +		self._name=name
 +	name=property(get_name,set_name)
 +	def to_list(self,val):
-+		if isinstance(val,str):return val.split()
-+		else:return val
++		if isinstance(val,str):
++			return val.split()
++		else:
++			return val
 +	def post(self):
 +		if getattr(self,'posted',None):
 +			return False
 +		self.posted=True
 +		keys=set(self.meths)
++		keys.update(feats['*'])
 +		self.features=Utils.to_list(self.features)
-+		for x in self.features+['*']:
++		for x in self.features:
 +			st=feats[x]
-+			if not st:
-+				if not x in Task.classes:
-+					Logs.warn('feature %r does not exist - bind at least one method to it'%x)
-+			keys.update(list(st))
++			if st:
++				keys.update(st)
++			elif not x in Task.classes:
++				Logs.warn('feature %r does not exist - bind at least one method to it?',x)
 +		prec={}
-+		prec_tbl=self.prec or task_gen.prec
++		prec_tbl=self.prec
 +		for x in prec_tbl:
 +			if x in keys:
 +				prec[x]=prec_tbl[x]
@@ -4048,7 +4169,8 @@ Last-Update: 2014-11-28
 +		out=[]
 +		while tmp:
 +			e=tmp.pop()
-+			if e in keys:out.append(e)
++			if e in keys:
++				out.append(e)
 +			try:
 +				nlst=prec[e]
 +			except KeyError:
@@ -4062,29 +4184,33 @@ Last-Update: 2014-11-28
 +					else:
 +						tmp.append(x)
 +		if prec:
-+			raise Errors.WafError('Cycle detected in the method execution %r'%prec)
++			buf=['Cycle detected in the method execution:']
++			for k,v in prec.items():
++				buf.append('- %s after %s'%(k,[x for x in v if x in prec]))
++			raise Errors.WafError('\n'.join(buf))
 +		out.reverse()
 +		self.meths=out
-+		Logs.debug('task_gen: posting %s %d'%(self,id(self)))
++		Logs.debug('task_gen: posting %s %d',self,id(self))
 +		for x in out:
 +			try:
 +				v=getattr(self,x)
 +			except AttributeError:
 +				raise Errors.WafError('%r is not a valid task generator method'%x)
-+			Logs.debug('task_gen: -> %s (%d)'%(x,id(self)))
++			Logs.debug('task_gen: -> %s (%d)',x,id(self))
 +			v()
-+		Logs.debug('task_gen: posted %s'%self.name)
++		Logs.debug('task_gen: posted %s',self.name)
 +		return True
 +	def get_hook(self,node):
 +		name=node.name
-+		if self.mappings:
-+			for k in self.mappings:
++		for k in self.mappings:
++			try:
 +				if name.endswith(k):
 +					return self.mappings[k]
-+		for k in task_gen.mappings:
-+			if name.endswith(k):
-+				return task_gen.mappings[k]
-+		raise Errors.WafError("File %r has no mapping in %r (have you forgotten to load a waf tool?)"%(node,task_gen.mappings.keys()))
++			except TypeError:
++				if k.match(name):
++					return self.mappings[k]
++		keys=list(self.mappings.keys())
++		raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)"%(node,keys))
 +	def create_task(self,name,src=None,tgt=None,**kw):
 +		task=Task.classes[name](env=self.env.derive(),generator=self)
 +		if src:
@@ -4116,12 +4242,11 @@ Last-Update: 2014-11-28
 +		name=rule
 +	cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
 +	def x_file(self,node):
-+		ext=decider and decider(self,node)or cls.ext_out
 +		if ext_in:
 +			_ext_in=ext_in[0]
 +		tsk=self.create_task(name,node)
 +		cnt=0
-+		keys=set(self.mappings.keys())|set(self.__class__.mappings.keys())
++		ext=decider(self,node)if decider else cls.ext_out
 +		for x in ext:
 +			k=node.change_ext(x,ext_in=_ext_in)
 +			tsk.outputs.append(k)
@@ -4129,13 +4254,13 @@ Last-Update: 2014-11-28
 +				if cnt<int(reentrant):
 +					self.source.append(k)
 +			else:
-+				for y in keys:
++				for y in self.mappings:
 +					if k.name.endswith(y):
 +						self.source.append(k)
 +						break
 +			cnt+=1
 +		if install_path:
-+			self.bld.install_files(install_path,tsk.outputs)
++			self.install_task=self.add_install_files(install_to=install_path,install_from=tsk.outputs)
 +		return tsk
 +	for x in cls.ext_in:
 +		task_gen.mappings[x]=x_file
@@ -4206,17 +4331,44 @@ Last-Update: 2014-11-28
 +		cache=self.bld.cache_rule_attr
 +	except AttributeError:
 +		cache=self.bld.cache_rule_attr={}
++	chmod=getattr(self,'chmod',None)
++	shell=getattr(self,'shell',True)
++	color=getattr(self,'color','BLUE')
++	scan=getattr(self,'scan',None)
++	_vars=getattr(self,'vars',[])
++	cls_str=getattr(self,'cls_str',None)
++	cls_keyword=getattr(self,'cls_keyword',None)
++	use_cache=getattr(self,'cache_rule','True')
++	scan_val=has_deps=hasattr(self,'deps')
++	if scan:
++		scan_val=id(scan)
++	key=Utils.h_list((name,self.rule,chmod,shell,color,cls_str,cls_keyword,scan_val,_vars))
 +	cls=None
-+	if getattr(self,'cache_rule','True'):
++	if use_cache:
 +		try:
-+			cls=cache[(name,self.rule)]
++			cls=cache[key]
 +		except KeyError:
 +			pass
 +	if not cls:
-+		cls=Task.task_factory(name,self.rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE'),scan=getattr(self,'scan',None))
-+		if getattr(self,'scan',None):
++		rule=self.rule
++		if chmod is not None:
++			def chmod_fun(tsk):
++				for x in tsk.outputs:
++					os.chmod(x.abspath(),tsk.generator.chmod)
++			if isinstance(rule,tuple):
++				rule=list(rule)
++				rule.append(chmod_fun)
++				rule=tuple(rule)
++			else:
++				rule=(rule,chmod_fun)
++		cls=Task.task_factory(name,rule,_vars,shell=shell,color=color)
++		if cls_str:
++			setattr(cls,'__str__',self.cls_str)
++		if cls_keyword:
++			setattr(cls,'keyword',self.cls_keyword)
++		if scan:
 +			cls.scan=self.scan
-+		elif getattr(self,'deps',None):
++		elif has_deps:
 +			def scan(self):
 +				nodes=[]
 +				for x in self.generator.to_list(getattr(self.generator,'deps',None)):
@@ -4226,15 +4378,15 @@ Last-Update: 2014-11-28
 +					nodes.append(node)
 +				return[nodes,[]]
 +			cls.scan=scan
-+		if getattr(self,'update_outputs',None):
-+			Task.update_outputs(cls)
-+		if getattr(self,'always',None):
-+			Task.always_run(cls)
 +		for x in('after','before','ext_in','ext_out'):
 +			setattr(cls,x,getattr(self,x,[]))
-+		if getattr(self,'cache_rule','True'):
-+			cache[(name,self.rule)]=cls
++		if use_cache:
++			cache[key]=cls
 +	tsk=self.create_task(name)
++	if getattr(self,'timeout',None):
++		tsk.timeout=self.timeout
++	if getattr(self,'always',None):
++		tsk.always_run=True
 +	if getattr(self,'target',None):
 +		if isinstance(self.target,str):
 +			self.target=self.target.split()
@@ -4247,12 +4399,14 @@ Last-Update: 2014-11-28
 +				x.parent.mkdir()
 +				tsk.outputs.append(x)
 +		if getattr(self,'install_path',None):
-+			self.bld.install_files(self.install_path,tsk.outputs)
++			self.install_task=self.add_install_files(install_to=self.install_path,install_from=tsk.outputs,chmod=getattr(self,'chmod',Utils.O644))
 +	if getattr(self,'source',None):
 +		tsk.inputs=self.to_nodes(self.source)
 +		self.source=[]
 +	if getattr(self,'cwd',None):
 +		tsk.cwd=self.cwd
++	if isinstance(tsk.run,functools.partial):
++		tsk.run=functools.partial(tsk.run,tsk)
 + at feature('seq')
 +def sequence_order(self):
 +	if self.meths and self.meths[-1]!='sequence_order':
@@ -4268,20 +4422,28 @@ Last-Update: 2014-11-28
 +	self.bld.prev=self
 +re_m4=re.compile('@(\w+)@',re.M)
 +class subst_pc(Task.Task):
++	def force_permissions(self):
++		if getattr(self.generator,'chmod',None):
++			for x in self.outputs:
++				os.chmod(x.abspath(),self.generator.chmod)
 +	def run(self):
 +		if getattr(self.generator,'is_copy',None):
-+			self.outputs[0].write(self.inputs[0].read('rb'),'wb')
-+			if getattr(self.generator,'chmod',None):
-+				os.chmod(self.outputs[0].abspath(),self.generator.chmod)
++			for i,x in enumerate(self.outputs):
++				x.write(self.inputs[i].read('rb'),'wb')
++			self.force_permissions()
 +			return None
 +		if getattr(self.generator,'fun',None):
-+			return self.generator.fun(self)
++			ret=self.generator.fun(self)
++			if not ret:
++				self.force_permissions()
++			return ret
 +		code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','ISO8859-1'))
 +		if getattr(self.generator,'subst_fun',None):
 +			code=self.generator.subst_fun(self,code)
 +			if code is not None:
 +				self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
-+			return
++			self.force_permissions()
++			return None
 +		code=code.replace('%','%%')
 +		lst=[]
 +		def repl(match):
@@ -4305,11 +4467,10 @@ Last-Update: 2014-11-28
 +				d[x]=tmp
 +		code=code%d
 +		self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
-+		self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst
++		self.generator.bld.raw_deps[self.uid()]=lst
 +		try:delattr(self,'cache_sig')
 +		except AttributeError:pass
-+		if getattr(self.generator,'chmod',None):
-+			os.chmod(self.outputs[0].abspath(),self.generator.chmod)
++		self.force_permissions()
 +	def sig_vars(self):
 +		bld=self.generator.bld
 +		env=self.env
@@ -4327,7 +4488,7 @@ Last-Update: 2014-11-28
 + at extension('.pc.in')
 +def add_pcfile(self,node):
 +	tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
-+	self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs)
++	self.install_task=self.add_install_files(install_to=getattr(self,'install_path','${LIBDIR}/pkgconfig/'),install_from=tsk.outputs)
 +class subst(subst_pc):
 +	pass
 + at feature('subst')
@@ -4349,7 +4510,6 @@ Last-Update: 2014-11-28
 +			a=self.path.find_node(x)
 +			b=self.path.get_bld().make_node(y)
 +			if not os.path.isfile(b.abspath()):
-+				b.sig=None
 +				b.parent.mkdir()
 +		else:
 +			if isinstance(x,str):
@@ -4361,7 +4521,7 @@ Last-Update: 2014-11-28
 +			elif isinstance(y,Node.Node):
 +				b=y
 +		if not a:
-+			raise Errors.WafError('cound not find %r for %r'%(x,self))
++			raise Errors.WafError('could not find %r for %r'%(x,self))
 +		has_constraints=False
 +		tsk=self.create_task('subst',a,b)
 +		for k in('after','before','ext_in','ext_out'):
@@ -4377,7 +4537,7 @@ Last-Update: 2014-11-28
 +					break
 +		inst_to=getattr(self,'install_path',None)
 +		if inst_to:
-+			self.bld.install_files(inst_to,b,chmod=getattr(self,'chmod',Utils.O644))
++			self.install_task=self.add_install_files(install_to=inst_to,install_from=b,chmod=getattr(self,'chmod',Utils.O644))
 +	self.source=[]
 --- /dev/null
 +++ b/waflib/Tools/__init__.py
@@ -4404,16 +4564,14 @@ Last-Update: 2014-11-28
 +		conf.env.ARFLAGS=['rcs']
 --- /dev/null
 +++ b/waflib/Tools/asm.py
-@@ -0,0 +1,25 @@
+@@ -0,0 +1,23 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
-+from waflib import Task,Utils
-+import waflib.Task
++from waflib import Task
 +from waflib.Tools.ccroot import link_task,stlink_task
-+from waflib.TaskGen import extension,feature
++from waflib.TaskGen import extension
 +class asm(Task.Task):
 +	color='BLUE'
 +	run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
@@ -4429,7 +4587,7 @@ Last-Update: 2014-11-28
 +class asmstlib(stlink_task):
 +	pass
 +def configure(conf):
-+	conf.env['ASMPATH_ST']='-I%s'
++	conf.env.ASMPATH_ST='-I%s'
 --- /dev/null
 +++ b/waflib/Tools/bison.py
 @@ -0,0 +1,28 @@
@@ -4445,7 +4603,7 @@ Last-Update: 2014-11-28
 +	ext_out=['.h']
 + at extension('.y','.yc','.yy')
 +def big_bison(self,node):
-+	has_h='-d'in self.env['BISONFLAGS']
++	has_h='-d'in self.env.BISONFLAGS
 +	outs=[]
 +	if node.name.endswith('.yc'):
 +		outs.append(node.change_ext('.tab.cc'))
@@ -4456,7 +4614,7 @@ Last-Update: 2014-11-28
 +		if has_h:
 +			outs.append(node.change_ext('.tab.h'))
 +	tsk=self.create_task('bison',node,outs)
-+	tsk.cwd=node.parent.get_bld().abspath()
++	tsk.cwd=node.parent.get_bld()
 +	self.source.append(outs[0])
 +def configure(conf):
 +	conf.find_program('bison',var='BISON')
@@ -4477,7 +4635,7 @@ Last-Update: 2014-11-28
 +		return self.create_compiled_task('cxx',node)
 +	return self.create_compiled_task('c',node)
 +class c(Task.Task):
-+	run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()}'
++	run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}'
 +	vars=['CCDEPS']
 +	ext_in=['.h']
 +	scan=c_preproc.scan
@@ -4492,45 +4650,50 @@ Last-Update: 2014-11-28
 +	pass
 --- /dev/null
 +++ b/waflib/Tools/c_aliases.py
-@@ -0,0 +1,55 @@
+@@ -0,0 +1,60 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,re
-+from waflib import Utils,Build
++from waflib import Utils,Errors
 +from waflib.Configure import conf
 +def get_extensions(lst):
 +	ret=[]
 +	for x in Utils.to_list(lst):
-+		try:
-+			if not isinstance(x,str):
-+				x=x.name
-+			ret.append(x[x.rfind('.')+1:])
-+		except Exception:
-+			pass
++		if not isinstance(x,str):
++			x=x.name
++		ret.append(x[x.rfind('.')+1:])
 +	return ret
 +def sniff_features(**kw):
 +	exts=get_extensions(kw['source'])
-+	type=kw['_type']
++	typ=kw['typ']
 +	feats=[]
-+	if'cxx'in exts or'cpp'in exts or'c++'in exts or'cc'in exts or'C'in exts:
-+		feats.append('cxx')
-+	if'c'in exts or'vala'in exts:
++	for x in'cxx cpp c++ cc C'.split():
++		if x in exts:
++			feats.append('cxx')
++			break
++	if'c'in exts or'vala'in exts or'gs'in exts:
 +		feats.append('c')
++	for x in'f f90 F F90 for FOR'.split():
++		if x in exts:
++			feats.append('fc')
++			break
 +	if'd'in exts:
 +		feats.append('d')
 +	if'java'in exts:
 +		feats.append('java')
-+	if'java'in exts:
 +		return'java'
-+	if type in('program','shlib','stlib'):
++	if typ in('program','shlib','stlib'):
++		will_link=False
 +		for x in feats:
-+			if x in('cxx','d','c'):
-+				feats.append(x+type)
++			if x in('cxx','d','fc','c'):
++				feats.append(x+typ)
++				will_link=True
++		if not will_link and not kw.get('features',[]):
++			raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?'%kw)
 +	return feats
-+def set_features(kw,_type):
-+	kw['_type']=_type
++def set_features(kw,typ):
++	kw['typ']=typ
 +	kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
 + at conf
 +def program(bld,*k,**kw):
@@ -4550,12 +4713,13 @@ Last-Update: 2014-11-28
 +	return bld(*k,**kw)
 --- /dev/null
 +++ b/waflib/Tools/c_config.py
-@@ -0,0 +1,743 @@
+@@ -0,0 +1,851 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,re,shlex,sys
++from __future__ import with_statement
++import os,re,shlex
 +from waflib import Build,Utils,Task,Options,Logs,Errors,Runner
 +from waflib.TaskGen import after_method,feature
 +from waflib.Configure import conf
@@ -4565,10 +4729,10 @@ Last-Update: 2014-11-28
 +cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
 +SNIP_FUNCTION='''
 +int main(int argc, char **argv) {
-+	void *p;
++	void (*p)();
 +	(void)argc; (void)argv;
-+	p=(void*)(%s);
-+	return (int)p;
++	p=(void(*)())(%s);
++	return !p;
 +}
 +'''
 +SNIP_TYPE='''
@@ -4594,7 +4758,7 @@ Last-Update: 2014-11-28
 +}
 +'''
 +MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'cygwin','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
-+MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh',}
++MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh','__xtensa__':'xtensa',}
 + at conf
 +def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None):
 +	assert(isinstance(line,str))
@@ -4607,72 +4771,81 @@ Last-Update: 2014-11-28
 +	lex.whitespace_split=True
 +	lex.commenters=''
 +	lst=list(lex)
-+	app=env.append_value
-+	appu=env.append_unique
 +	uselib=uselib_store
++	def app(var,val):
++		env.append_value('%s_%s'%(var,uselib),val)
++	def appu(var,val):
++		env.append_unique('%s_%s'%(var,uselib),val)
 +	static=False
 +	while lst:
 +		x=lst.pop(0)
 +		st=x[:2]
 +		ot=x[2:]
 +		if st=='-I'or st=='/I':
-+			if not ot:ot=lst.pop(0)
-+			appu('INCLUDES_'+uselib,[ot])
++			if not ot:
++				ot=lst.pop(0)
++			appu('INCLUDES',ot)
 +		elif st=='-i':
 +			tmp=[x,lst.pop(0)]
 +			app('CFLAGS',tmp)
 +			app('CXXFLAGS',tmp)
 +		elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
-+			if not ot:ot=lst.pop(0)
-+			app('DEFINES_'+uselib,[ot])
++			if not ot:
++				ot=lst.pop(0)
++			app('DEFINES',ot)
 +		elif st=='-l':
-+			if not ot:ot=lst.pop(0)
-+			prefix=(force_static or static)and'STLIB_'or'LIB_'
-+			appu(prefix+uselib,[ot])
++			if not ot:
++				ot=lst.pop(0)
++			prefix='STLIB'if(force_static or static)else'LIB'
++			app(prefix,ot)
 +		elif st=='-L':
-+			if not ot:ot=lst.pop(0)
-+			prefix=(force_static or static)and'STLIBPATH_'or'LIBPATH_'
-+			appu(prefix+uselib,[ot])
++			if not ot:
++				ot=lst.pop(0)
++			prefix='STLIBPATH'if(force_static or static)else'LIBPATH'
++			appu(prefix,ot)
 +		elif x.startswith('/LIBPATH:'):
-+			prefix=(force_static or static)and'STLIBPATH_'or'LIBPATH_'
-+			appu(prefix+uselib,[x.replace('/LIBPATH:','')])
-+		elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
-+			app('CFLAGS_'+uselib,[x])
-+			app('CXXFLAGS_'+uselib,[x])
-+			app('LINKFLAGS_'+uselib,[x])
++			prefix='STLIBPATH'if(force_static or static)else'LIBPATH'
++			appu(prefix,x.replace('/LIBPATH:',''))
++		elif x.startswith('-std='):
++			prefix='CXXFLAGS'if'++'in x else'CFLAGS'
++			app(prefix,x)
++		elif x=='-pthread'or x.startswith('+'):
++			app('CFLAGS',x)
++			app('CXXFLAGS',x)
++			app('LINKFLAGS',x)
 +		elif x=='-framework':
-+			appu('FRAMEWORK_'+uselib,[lst.pop(0)])
++			appu('FRAMEWORK',lst.pop(0))
 +		elif x.startswith('-F'):
-+			appu('FRAMEWORKPATH_'+uselib,[x[2:]])
++			appu('FRAMEWORKPATH',x[2:])
 +		elif x=='-Wl,-rpath'or x=='-Wl,-R':
-+			app('RPATH_'+uselib,lst.pop(0).lstrip('-Wl,'))
++			app('RPATH',lst.pop(0).lstrip('-Wl,'))
 +		elif x.startswith('-Wl,-R,'):
-+			app('RPATH_'+uselib,x[7:])
++			app('RPATH',x[7:])
 +		elif x.startswith('-Wl,-R'):
-+			app('RPATH_'+uselib,x[6:])
++			app('RPATH',x[6:])
 +		elif x.startswith('-Wl,-rpath,'):
-+			app('RPATH_'+uselib,x[11:])
++			app('RPATH',x[11:])
 +		elif x=='-Wl,-Bstatic'or x=='-Bstatic':
 +			static=True
 +		elif x=='-Wl,-Bdynamic'or x=='-Bdynamic':
 +			static=False
 +		elif x.startswith('-Wl'):
-+			app('LINKFLAGS_'+uselib,[x])
-+		elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
-+			app('CFLAGS_'+uselib,[x])
-+			app('CXXFLAGS_'+uselib,[x])
++			app('LINKFLAGS',x)
++		elif x.startswith(('-m','-f','-dynamic','-O')):
++			app('CFLAGS',x)
++			app('CXXFLAGS',x)
 +		elif x.startswith('-bundle'):
-+			app('LINKFLAGS_'+uselib,[x])
-+		elif x.startswith('-undefined')or x.startswith('-Xlinker'):
++			app('LINKFLAGS',x)
++		elif x.startswith(('-undefined','-Xlinker')):
 +			arg=lst.pop(0)
-+			app('LINKFLAGS_'+uselib,[x,arg])
-+		elif x.startswith('-arch')or x.startswith('-isysroot'):
++			app('LINKFLAGS',[x,arg])
++		elif x.startswith(('-arch','-isysroot')):
 +			tmp=[x,lst.pop(0)]
-+			app('CFLAGS_'+uselib,tmp)
-+			app('CXXFLAGS_'+uselib,tmp)
-+			app('LINKFLAGS_'+uselib,tmp)
-+		elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
-+			appu('LINKFLAGS_'+uselib,[x])
++			app('CFLAGS',tmp)
++			app('CXXFLAGS',tmp)
++			app('LINKFLAGS',tmp)
++		elif x.endswith(('.a','.so','.dylib','.lib')):
++			appu('LINKFLAGS',x)
 + at conf
 +def validate_cfg(self,kw):
 +	if not'path'in kw:
@@ -4690,52 +4863,65 @@ Last-Update: 2014-11-28
 +	if'modversion'in kw:
 +		if not'msg'in kw:
 +			kw['msg']='Checking for %r version'%kw['modversion']
++		if not'uselib_store'in kw:
++			kw['uselib_store']=kw['modversion']
++		if not'define_name'in kw:
++			kw['define_name']='%s_VERSION'%Utils.quote_define_name(kw['uselib_store'])
 +		return
-+	for x in cfg_ver.keys():
-+		y=x.replace('-','_')
-+		if y in kw:
-+			if not'package'in kw:
-+				raise ValueError('%s requires a package'%x)
-+			if not'msg'in kw:
-+				kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
-+			return
-+	if not'define_name'in kw:
-+		pkgname=kw.get('uselib_store',kw['package'].upper())
-+		kw['define_name']=self.have_define(pkgname)
++	if not'package'in kw:
++		raise ValueError('a package name is required')
 +	if not'uselib_store'in kw:
-+		self.undefine(kw['define_name'])
++		kw['uselib_store']=kw['package'].upper()
++	if not'define_name'in kw:
++		kw['define_name']=self.have_define(kw['uselib_store'])
 +	if not'msg'in kw:
 +		kw['msg']='Checking for %r'%(kw['package']or kw['path'])
++	for x in cfg_ver:
++		y=x.replace('-','_')
++		if y in kw:
++			package=kw['package']
++			if Logs.verbose:
++				Logs.warn('Passing %r to conf.check_cfg() is obsolete, pass parameters directly, eg:',y)
++				Logs.warn(" conf.check_cfg(package='%s', args=['--libs', '--cflags', '%s >= 1.6'])",package,package)
++			if not'msg'in kw:
++				kw['msg']='Checking for %r %s %s'%(package,cfg_ver[x],kw[y])
++			break
 + at conf
 +def exec_cfg(self,kw):
 +	path=Utils.to_list(kw['path'])
++	env=self.env.env or None
++	if kw.get('pkg_config_path'):
++		if not env:
++			env=dict(self.environ)
++		env['PKG_CONFIG_PATH']=kw['pkg_config_path']
 +	def define_it():
-+		pkgname=kw.get('uselib_store',kw['package'].upper())
-+		if kw.get('global_define'):
-+			self.define(self.have_define(kw['package']),1,False)
++		define_name=kw['define_name']
++		if kw.get('global_define',1):
++			self.define(define_name,1,False)
 +		else:
-+			self.env.append_unique('DEFINES_%s'%pkgname,"%s=1"%self.have_define(pkgname))
-+		self.env[self.have_define(pkgname)]=1
++			self.env.append_unique('DEFINES_%s'%kw['uselib_store'],"%s=1"%define_name)
++		if kw.get('add_have_to_env',1):
++			self.env[define_name]=1
 +	if'atleast_pkgconfig_version'in kw:
 +		cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
-+		self.cmd_and_log(cmd)
++		self.cmd_and_log(cmd,env=env)
 +		if not'okmsg'in kw:
 +			kw['okmsg']='yes'
 +		return
 +	for x in cfg_ver:
 +		y=x.replace('-','_')
 +		if y in kw:
-+			self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']])
++			self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']],env=env)
 +			if not'okmsg'in kw:
 +				kw['okmsg']='yes'
 +			define_it()
 +			break
 +	if'modversion'in kw:
-+		version=self.cmd_and_log(path+['--modversion',kw['modversion']]).strip()
-+		self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
++		version=self.cmd_and_log(path+['--modversion',kw['modversion']],env=env).strip()
++		self.define(kw['define_name'],version)
 +		return version
 +	lst=[]+path
-+	defi=kw.get('define_variable',None)
++	defi=kw.get('define_variable')
 +	if not defi:
 +		defi=self.env.PKG_CONFIG_DEFINES or{}
 +	for key,val in defi.items():
@@ -4748,21 +4934,20 @@ Last-Update: 2014-11-28
 +		lst+=args
 +	lst.extend(Utils.to_list(kw['package']))
 +	if'variables'in kw:
-+		env=kw.get('env',self.env)
-+		uselib=kw.get('uselib_store',kw['package'].upper())
++		v_env=kw.get('env',self.env)
 +		vars=Utils.to_list(kw['variables'])
 +		for v in vars:
-+			val=self.cmd_and_log(lst+['--variable='+v]).strip()
-+			var='%s_%s'%(uselib,v)
-+			env[var]=val
++			val=self.cmd_and_log(lst+['--variable='+v],env=env).strip()
++			var='%s_%s'%(kw['uselib_store'],v)
++			v_env[var]=val
 +		if not'okmsg'in kw:
 +			kw['okmsg']='yes'
 +		return
-+	ret=self.cmd_and_log(lst)
++	ret=self.cmd_and_log(lst,env=env)
 +	if not'okmsg'in kw:
 +		kw['okmsg']='yes'
 +	define_it()
-+	self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static,posix=kw.get('posix',None))
++	self.parse_flags(ret,kw['uselib_store'],kw.get('env',self.env),force_static=static,posix=kw.get('posix'))
 +	return ret
 + at conf
 +def check_cfg(self,*k,**kw):
@@ -4797,7 +4982,7 @@ Last-Update: 2014-11-28
 +	o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog')
 +	for k,v in bld.kw.items():
 +		setattr(o,k,v)
-+	if not bld.kw.get('quiet',None):
++	if not bld.kw.get('quiet'):
 +		bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
 + at conf
 +def validate_c(self,kw):
@@ -4808,12 +4993,12 @@ Last-Update: 2014-11-28
 +	env=kw['env']
 +	if not'compiler'in kw and not'features'in kw:
 +		kw['compiler']='c'
-+		if env['CXX_NAME']and Task.classes.get('cxx',None):
++		if env.CXX_NAME and Task.classes.get('cxx'):
 +			kw['compiler']='cxx'
-+			if not self.env['CXX']:
++			if not self.env.CXX:
 +				self.fatal('a c++ compiler is required')
 +		else:
-+			if not self.env['CC']:
++			if not self.env.CC:
 +				self.fatal('a c compiler is required')
 +	if not'compile_mode'in kw:
 +		kw['compile_mode']='c'
@@ -4822,7 +5007,10 @@ Last-Update: 2014-11-28
 +	if not'type'in kw:
 +		kw['type']='cprogram'
 +	if not'features'in kw:
-+		kw['features']=[kw['compile_mode'],kw['type']]
++		if not'header_name'in kw or kw.get('link_header_test',True):
++			kw['features']=[kw['compile_mode'],kw['type']]
++		else:
++			kw['features']=[kw['compile_mode']]
 +	else:
 +		kw['features']=Utils.to_list(kw['features'])
 +	if not'compile_filename'in kw:
@@ -4840,7 +5028,7 @@ Last-Update: 2014-11-28
 +			if not'header_name'in kw:
 +				kw['header_name']=[]
 +			fwk='%s/%s.h'%(fwkname,fwkname)
-+			if kw.get('remove_dot_h',None):
++			if kw.get('remove_dot_h'):
 +				fwk=fwk[:-2]
 +			kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
 +		kw['msg']='Checking for framework %s'%fwkname
@@ -4875,7 +5063,7 @@ Last-Update: 2014-11-28
 +		if not'msg'in kw:
 +			kw['msg']='Checking for header %s'%kw['header_name']
 +		l=Utils.to_list(kw['header_name'])
-+		assert len(l)>0,'list of headers in header_name is empty'
++		assert len(l),'list of headers in header_name is empty'
 +		kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
 +		if not'uselib_store'in kw:
 +			kw['uselib_store']=l[0].upper()
@@ -4907,6 +5095,7 @@ Last-Update: 2014-11-28
 +		kw['execute']=False
 +	if kw['execute']:
 +		kw['features'].append('test_exec')
++		kw['chmod']=Utils.O755
 +	if not'errmsg'in kw:
 +		kw['errmsg']='not found'
 +	if not'okmsg'in kw:
@@ -4915,6 +5104,9 @@ Last-Update: 2014-11-28
 +		kw['code']=SNIP_EMPTY_PROGRAM
 +	if self.env[INCKEYS]:
 +		kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
++	if kw.get('merge_config_header',False)or env.merge_config_header:
++		kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code'])
++		env.DEFINES=[]
 +	if not kw.get('success'):kw['success']=None
 +	if'define_name'in kw:
 +		self.undefine(kw['define_name'])
@@ -4931,30 +5123,44 @@ Last-Update: 2014-11-28
 +				is_success=(kw['success']==0)
 +	else:
 +		is_success=(kw['success']==0)
-+	if'define_name'in kw:
-+		if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
-+			if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
-+				self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
++	if kw.get('define_name'):
++		comment=kw.get('comment','')
++		define_name=kw['define_name']
++		if kw['execute']and kw.get('define_ret')and isinstance(is_success,str):
++			if kw.get('global_define',1):
++				self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment)
 +			else:
-+				self.define_cond(kw['define_name'],is_success)
++				if kw.get('quote',1):
++					succ='"%s"'%is_success
++				else:
++					succ=int(is_success)
++				val='%s=%s'%(define_name,succ)
++				var='DEFINES_%s'%kw['uselib_store']
++				self.env.append_value(var,val)
 +		else:
-+			self.define_cond(kw['define_name'],is_success)
++			if kw.get('global_define',1):
++				self.define_cond(define_name,is_success,comment=comment)
++			else:
++				var='DEFINES_%s'%kw['uselib_store']
++				self.env.append_value(var,'%s=%s'%(define_name,int(is_success)))
++		if kw.get('add_have_to_env',1):
++			if kw.get('uselib_store'):
++				self.env[self.have_define(kw['uselib_store'])]=1
++			else:
++				self.env[define_name]=int(is_success)
 +	if'header_name'in kw:
 +		if kw.get('auto_add_header_name',False):
 +			self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
 +	if is_success and'uselib_store'in kw:
 +		from waflib.Tools import ccroot
-+		_vars=set([])
++		_vars=set()
 +		for x in kw['features']:
 +			if x in ccroot.USELIB_VARS:
 +				_vars|=ccroot.USELIB_VARS[x]
 +		for k in _vars:
-+			lk=k.lower()
-+			if lk in kw:
-+				val=kw[lk]
-+				if isinstance(val,str):
-+					val=val.rstrip(os.path.sep)
-+				self.env.append_unique(k+'_'+kw['uselib_store'],Utils.to_list(val))
++			x=k.lower()
++			if x in kw:
++				self.env.append_value(k+'_'+kw['uselib_store'],kw[x])
 +	return is_success
 + at conf
 +def check(self,*k,**kw):
@@ -5008,8 +5214,20 @@ Last-Update: 2014-11-28
 +	kw['compiler']='c'
 +	return self.check(*k,**kw)
 + at conf
-+def define(self,key,val,quote=True):
-+	assert key and isinstance(key,str)
++def set_define_comment(self,key,comment):
++	coms=self.env.DEFINE_COMMENTS
++	if not coms:
++		coms=self.env.DEFINE_COMMENTS={}
++	coms[key]=comment or''
++ at conf
++def get_define_comment(self,key):
++	coms=self.env.DEFINE_COMMENTS or{}
++	return coms.get(key,'')
++ at conf
++def define(self,key,val,quote=True,comment=''):
++	assert isinstance(key,str)
++	if not key:
++		return
 +	if val is True:
 +		val=1
 +	elif val in(False,None):
@@ -5020,7 +5238,7 @@ Last-Update: 2014-11-28
 +		s=quote and'%s="%s"'or'%s=%s'
 +	app=s%(key,str(val))
 +	ban=key+'='
-+	lst=self.env['DEFINES']
++	lst=self.env.DEFINES
 +	for x in lst:
 +		if x.startswith(ban):
 +			lst[lst.index(x)]=app
@@ -5028,25 +5246,31 @@ Last-Update: 2014-11-28
 +	else:
 +		self.env.append_value('DEFINES',app)
 +	self.env.append_unique(DEFKEYS,key)
++	self.set_define_comment(key,comment)
 + at conf
-+def undefine(self,key):
-+	assert key and isinstance(key,str)
++def undefine(self,key,comment=''):
++	assert isinstance(key,str)
++	if not key:
++		return
 +	ban=key+'='
-+	lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
-+	self.env['DEFINES']=lst
++	lst=[x for x in self.env.DEFINES if not x.startswith(ban)]
++	self.env.DEFINES=lst
 +	self.env.append_unique(DEFKEYS,key)
++	self.set_define_comment(key,comment)
 + at conf
-+def define_cond(self,key,val):
-+	assert key and isinstance(key,str)
++def define_cond(self,key,val,comment=''):
++	assert isinstance(key,str)
++	if not key:
++		return
 +	if val:
-+		self.define(key,1)
++		self.define(key,1,comment=comment)
 +	else:
-+		self.undefine(key)
++		self.undefine(key,comment=comment)
 + at conf
 +def is_defined(self,key):
 +	assert key and isinstance(key,str)
 +	ban=key+'='
-+	for x in self.env['DEFINES']:
++	for x in self.env.DEFINES:
 +		if x.startswith(ban):
 +			return True
 +	return False
@@ -5054,7 +5278,7 @@ Last-Update: 2014-11-28
 +def get_define(self,key):
 +	assert key and isinstance(key,str)
 +	ban=key+'='
-+	for x in self.env['DEFINES']:
++	for x in self.env.DEFINES:
 +		if x.startswith(ban):
 +			return x[len(ban):]
 +	return None
@@ -5081,19 +5305,24 @@ Last-Update: 2014-11-28
 + at conf
 +def get_config_header(self,defines=True,headers=False,define_prefix=''):
 +	lst=[]
++	if self.env.WAF_CONFIG_H_PRELUDE:
++		lst.append(self.env.WAF_CONFIG_H_PRELUDE)
 +	if headers:
 +		for x in self.env[INCKEYS]:
 +			lst.append('#include <%s>'%x)
 +	if defines:
 +		tbl={}
-+		for k in self.env['DEFINES']:
++		for k in self.env.DEFINES:
 +			a,_,b=k.partition('=')
 +			tbl[a]=b
 +		for k in self.env[DEFKEYS]:
++			caption=self.get_define_comment(k)
++			if caption:
++				caption=' /* %s */'%caption
 +			try:
-+				txt='#define %s%s %s'%(define_prefix,k,tbl[k])
++				txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption)
 +			except KeyError:
-+				txt='/* #undef %s%s */'%(define_prefix,k)
++				txt='/* #undef %s%s */%s'%(define_prefix,k,caption)
 +			lst.append(txt)
 +	return"\n".join(lst)
 + at conf
@@ -5123,13 +5352,9 @@ Last-Update: 2014-11-28
 +	cmd=cc+['-dM','-E','-']
 +	env=conf.env.env or None
 +	try:
-+		p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
-+		p.stdin.write('\n')
-+		out=p.communicate()[0]
++		out,err=conf.cmd_and_log(cmd,output=0,input='\n',env=env)
 +	except Exception:
 +		conf.fatal('Could not determine the compiler version %r'%cmd)
-+	if not isinstance(out,str):
-+		out=out.decode(sys.stdout.encoding or'iso8859-1')
 +	if gcc:
 +		if out.find('__INTEL_COMPILER')>=0:
 +			conf.fatal('The intel compiler pretends to be gcc')
@@ -5152,8 +5377,6 @@ Last-Update: 2014-11-28
 +				k[key]=val
 +		def isD(var):
 +			return var in k
-+		def isT(var):
-+			return var in k and k[var]!='0'
 +		if not conf.env.DEST_OS:
 +			conf.env.DEST_OS=''
 +		for i in MACRO_TO_DESTOS:
@@ -5181,18 +5404,12 @@ Last-Update: 2014-11-28
 +		Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
 +		if icc:
 +			ver=k['__INTEL_COMPILER']
-+			conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
++			conf.env.CC_VERSION=(ver[:-2],ver[-2],ver[-1])
 +		else:
-+			if isD('__clang__'):
-+				try:
-+					conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
-+				except KeyError:
-+					conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
++			if isD('__clang__')and isD('__clang_major__'):
++				conf.env.CC_VERSION=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
 +			else:
-+				try:
-+					conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
-+				except KeyError:
-+					conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],0)
++				conf.env.CC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0'))
 +	return k
 + at conf
 +def get_xlc_version(conf,cc):
@@ -5206,7 +5423,7 @@ Last-Update: 2014-11-28
 +		match=version_re(out or err)
 +		if match:
 +			k=match.groupdict()
-+			conf.env['CC_VERSION']=(k['major'],k['minor'])
++			conf.env.CC_VERSION=(k['major'],k['minor'])
 +			break
 +	else:
 +		conf.fatal('Could not determine the XLC version.')
@@ -5222,11 +5439,11 @@ Last-Update: 2014-11-28
 +		err=e.stderr
 +	version=(out or err)
 +	version=version.splitlines()[0]
-+	version_re=re.compile(r'cc:\s+sun\s+(c\+\+|c)\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
++	version_re=re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
 +	match=version_re(version)
 +	if match:
 +		k=match.groupdict()
-+		conf.env['CC_VERSION']=(k['major'],k['minor'])
++		conf.env.CC_VERSION=(k['major'],k['minor'])
 +	else:
 +		conf.fatal('Could not determine the suncc version.')
 + at conf
@@ -5234,9 +5451,15 @@ Last-Update: 2014-11-28
 +	if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
 +		self.env.append_unique('LINKFLAGS','-Wl,--as-needed')
 +class cfgtask(Task.TaskBase):
++	def __init__(self,*k,**kw):
++		Task.TaskBase.__init__(self,*k,**kw)
++		self.run_after=set()
 +	def display(self):
 +		return''
 +	def runnable_status(self):
++		for x in self.run_after:
++			if not x.hasrun:
++				return Task.ASK_LATER
 +		return Task.RUN_ME
 +	def uid(self):
 +		return Utils.SIG_NIL
@@ -5247,17 +5470,40 @@ Last-Update: 2014-11-28
 +		bld.init_dirs()
 +		bld.in_msg=1
 +		bld.logger=self.logger
++		bld.multicheck_task=self
++		args=self.args
 +		try:
-+			bld.check(**self.args)
++			if'func'in args:
++				bld.test(build_fun=args['func'],msg=args.get('msg',''),okmsg=args.get('okmsg',''),errmsg=args.get('errmsg',''),)
++			else:
++				args['multicheck_mandatory']=args.get('mandatory',True)
++				args['mandatory']=True
++				try:
++					bld.check(**args)
++				finally:
++					args['mandatory']=args['multicheck_mandatory']
 +		except Exception:
 +			return 1
++	def process(self):
++		Task.TaskBase.process(self)
++		if'msg'in self.args:
++			with self.generator.bld.multicheck_lock:
++				self.conf.start_msg(self.args['msg'])
++				if self.hasrun==Task.NOT_RUN:
++					self.conf.end_msg('test cancelled','YELLOW')
++				elif self.hasrun!=Task.SUCCESS:
++					self.conf.end_msg(self.args.get('errmsg','no'),'YELLOW')
++				else:
++					self.conf.end_msg(self.args.get('okmsg','yes'),'GREEN')
 + at conf
 +def multicheck(self,*k,**kw):
 +	self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw)
++	for var in('DEFINES',DEFKEYS):
++		self.env.append_value(var,[])
++	self.env.DEFINE_COMMENTS=self.env.DEFINE_COMMENTS or{}
 +	class par(object):
 +		def __init__(self):
 +			self.keep=False
-+			self.returned_tasks=[]
 +			self.task_sigs={}
 +			self.progress_bar=0
 +		def total(self):
@@ -5265,44 +5511,69 @@ Last-Update: 2014-11-28
 +		def to_log(self,*k,**kw):
 +			return
 +	bld=par()
++	bld.keep=kw.get('run_all_tests',True)
 +	tasks=[]
++	id_to_task={}
 +	for dct in k:
-+		x=cfgtask(bld=bld)
++		x=Task.classes['cfgtask'](bld=bld)
 +		tasks.append(x)
 +		x.args=dct
 +		x.bld=bld
 +		x.conf=self
 +		x.args=dct
 +		x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
++		if'id'in dct:
++			id_to_task[dct['id']]=x
++	for x in tasks:
++		for key in Utils.to_list(x.args.get('before_tests',[])):
++			tsk=id_to_task[key]
++			if not tsk:
++				raise ValueError('No test named %r'%key)
++			tsk.run_after.add(x)
++		for key in Utils.to_list(x.args.get('after_tests',[])):
++			tsk=id_to_task[key]
++			if not tsk:
++				raise ValueError('No test named %r'%key)
++			x.run_after.add(tsk)
 +	def it():
 +		yield tasks
 +		while 1:
 +			yield[]
-+	p=Runner.Parallel(bld,Options.options.jobs)
++	bld.producer=p=Runner.Parallel(bld,Options.options.jobs)
++	bld.multicheck_lock=Utils.threading.Lock()
 +	p.biter=it()
++	self.end_msg('started')
 +	p.start()
 +	for x in tasks:
 +		x.logger.memhandler.flush()
++	self.start_msg('-> processing test results')
 +	if p.error:
 +		for x in p.error:
 +			if getattr(x,'err_msg',None):
 +				self.to_log(x.err_msg)
 +				self.end_msg('fail',color='RED')
 +				raise Errors.WafError('There is an error in the library, read config.log for more information')
++	failure_count=0
++	for x in tasks:
++		if x.hasrun not in(Task.SUCCESS,Task.NOT_RUN):
++			failure_count+=1
++	if failure_count:
++		self.end_msg(kw.get('errmsg','%s test failed'%failure_count),color='YELLOW',**kw)
++	else:
++		self.end_msg('all ok',**kw)
 +	for x in tasks:
 +		if x.hasrun!=Task.SUCCESS:
-+			self.end_msg(kw.get('errmsg','no'),color='YELLOW',**kw)
-+			self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, read config.log for more information')
-+	self.end_msg('ok',**kw)
++			if x.args.get('mandatory',True):
++				self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information')
 --- /dev/null
 +++ b/waflib/Tools/c_osx.py
-@@ -0,0 +1,138 @@
+@@ -0,0 +1,121 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,shutil,sys,platform
-+from waflib import TaskGen,Task,Build,Options,Utils,Errors
++import os,shutil,platform
++from waflib import Task,Utils
 +from waflib.TaskGen import taskgen_method,feature,after_method,before_method
 +app_info='''
 +<?xml version="1.0" encoding="UTF-8"?>
@@ -5324,14 +5595,13 @@ Last-Update: 2014-11-28
 +'''
 + at feature('c','cxx')
 +def set_macosx_deployment_target(self):
-+	if self.env['MACOSX_DEPLOYMENT_TARGET']:
-+		os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET']
++	if self.env.MACOSX_DEPLOYMENT_TARGET:
++		os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env.MACOSX_DEPLOYMENT_TARGET
 +	elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
 +		if Utils.unversioned_sys_platform()=='darwin':
 +			os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
 + at taskgen_method
 +def create_bundle_dirs(self,name,out):
-+	bld=self.bld
 +	dir=out.parent.find_or_declare(name)
 +	dir.mkdir()
 +	macos=dir.find_or_declare(['Contents','MacOS'])
@@ -5348,14 +5618,14 @@ Last-Update: 2014-11-28
 + at feature('cprogram','cxxprogram')
 + at after_method('apply_link')
 +def create_task_macapp(self):
-+	if self.env['MACAPP']or getattr(self,'mac_app',False):
++	if self.env.MACAPP or getattr(self,'mac_app',False):
 +		out=self.link_task.outputs[0]
 +		name=bundle_name_for_output(out)
 +		dir=self.create_bundle_dirs(name,out)
 +		n1=dir.find_or_declare(['Contents','MacOS',out.name])
 +		self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
 +		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
-+		self.bld.install_files(inst_to,n1,chmod=Utils.O755)
++		self.add_install_files(install_to=inst_to,install_from=n1,chmod=Utils.O755)
 +		if getattr(self,'mac_files',None):
 +			mac_files_root=getattr(self,'mac_files_root',None)
 +			if isinstance(mac_files_root,str):
@@ -5366,30 +5636,14 @@ Last-Update: 2014-11-28
 +			inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
 +			for node in self.to_nodes(self.mac_files):
 +				relpath=node.path_from(mac_files_root or node.parent)
-+				tsk=self.create_task('macapp',node,res_dir.make_node(relpath))
-+				self.bld.install_as(os.path.join(inst_to,relpath),node)
-+		if getattr(self,'mac_resources',None):
-+			res_dir=n1.parent.parent.make_node('Resources')
-+			inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
-+			for x in self.to_list(self.mac_resources):
-+				node=self.path.find_node(x)
-+				if not node:
-+					raise Errors.WafError('Missing mac_resource %r in %r'%(x,self))
-+				parent=node.parent
-+				if os.path.isdir(node.abspath()):
-+					nodes=node.ant_glob('**')
-+				else:
-+					nodes=[node]
-+				for node in nodes:
-+					rel=node.path_from(parent)
-+					tsk=self.create_task('macapp',node,res_dir.make_node(rel))
-+					self.bld.install_as(inst_to+'/%s'%rel,node)
++				self.create_task('macapp',node,res_dir.make_node(relpath))
++				self.add_install_as(install_to=os.path.join(inst_to,relpath),install_source=node)
 +		if getattr(self.bld,'is_install',None):
 +			self.install_task.hasrun=Task.SKIP_ME
 + at feature('cprogram','cxxprogram')
 + at after_method('apply_link')
 +def create_task_macplist(self):
-+	if self.env['MACAPP']or getattr(self,'mac_app',False):
++	if self.env.MACAPP or getattr(self,'mac_app',False):
 +		out=self.link_task.outputs[0]
 +		name=bundle_name_for_output(out)
 +		dir=self.create_bundle_dirs(name,out)
@@ -5408,13 +5662,13 @@ Last-Update: 2014-11-28
 +		else:
 +			plisttask.code=app_info
 +		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
-+		self.bld.install_files(inst_to,n1)
++		self.add_install_files(install_to=inst_to,install_from=n1)
 + at feature('cshlib','cxxshlib')
 + at before_method('apply_link','propagate_uselib_vars')
 +def apply_bundle(self):
-+	if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False):
-+		self.env['LINKFLAGS_cshlib']=self.env['LINKFLAGS_cxxshlib']=[]
-+		self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']
++	if self.env.MACBUNDLE or getattr(self,'mac_bundle',False):
++		self.env.LINKFLAGS_cshlib=self.env.LINKFLAGS_cxxshlib=[]
++		self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN
 +		use=self.use=self.to_list(getattr(self,'use',[]))
 +		if not'MACBUNDLE'in use:
 +			use.append('MACBUNDLE')
@@ -5437,16 +5691,17 @@ Last-Update: 2014-11-28
 +		self.outputs[0].write(txt)
 --- /dev/null
 +++ b/waflib/Tools/c_preproc.py
-@@ -0,0 +1,611 @@
+@@ -0,0 +1,616 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import re,string,traceback
 +from waflib import Logs,Utils,Errors
-+from waflib.Logs import debug,error
 +class PreprocError(Errors.WafError):
 +	pass
++FILE_CACHE_SIZE=100000
++LINE_CACHE_SIZE=100000
 +POPFILE='-'
 +recursion_limit=150
 +go_absolute=False
@@ -5456,7 +5711,7 @@ Last-Update: 2014-11-28
 +use_trigraphs=0
 +strict_quotes=0
 +g_optrans={'not':'!','not_eq':'!','and':'&&','and_eq':'&=','or':'||','or_eq':'|=','xor':'^','xor_eq':'^=','bitand':'&','bitor':'|','compl':'~',}
-+re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
++re_lines=re.compile('^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
 +re_mac=re.compile("^[a-zA-Z_]\w*")
 +re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
 +re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
@@ -5477,21 +5732,13 @@ Last-Update: 2014-11-28
 +undefined='u'
 +skipped='s'
 +def repl(m):
-+	s=m.group(0)
-+	if s.startswith('/'):
++	s=m.group()
++	if s[0]=='/':
 +		return' '
 +	return s
-+def filter_comments(filename):
-+	code=Utils.readf(filename)
-+	if use_trigraphs:
-+		for(a,b)in trig_def:code=code.split(a).join(b)
-+	code=re_nl.sub('',code)
-+	code=re_cpp.sub(repl,code)
-+	return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
 +prec={}
 +ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
-+for x in range(len(ops)):
-+	syms=ops[x]
++for x,syms in enumerate(ops):
 +	for u in syms.split():
 +		prec[u]=x
 +def trimquotes(s):
@@ -5527,7 +5774,7 @@ Last-Update: 2014-11-28
 +	else:c=0
 +	return c
 +def get_num(lst):
-+	if not lst:raise PreprocError("empty list for get_num")
++	if not lst:raise PreprocError('empty list for get_num')
 +	(p,v)=lst[0]
 +	if p==OP:
 +		if v=='(':
@@ -5544,7 +5791,7 @@ Last-Update: 2014-11-28
 +						count_par+=1
 +				i+=1
 +			else:
-+				raise PreprocError("rparen expected %r"%lst)
++				raise PreprocError('rparen expected %r'%lst)
 +			(num,_)=get_term(lst[1:i])
 +			return(num,lst[i+1:])
 +		elif v=='+':
@@ -5559,15 +5806,15 @@ Last-Update: 2014-11-28
 +			num,lst=get_num(lst[1:])
 +			return(~int(num),lst)
 +		else:
-+			raise PreprocError("Invalid op token %r for get_num"%lst)
++			raise PreprocError('Invalid op token %r for get_num'%lst)
 +	elif p==NUM:
 +		return v,lst[1:]
 +	elif p==IDENT:
 +		return 0,lst[1:]
 +	else:
-+		raise PreprocError("Invalid token %r for get_num"%lst)
++		raise PreprocError('Invalid token %r for get_num'%lst)
 +def get_term(lst):
-+	if not lst:raise PreprocError("empty list for get_term")
++	if not lst:raise PreprocError('empty list for get_term')
 +	num,lst=get_num(lst)
 +	if not lst:
 +		return(num,[])
@@ -5590,7 +5837,7 @@ Last-Update: 2014-11-28
 +							break
 +				i+=1
 +			else:
-+				raise PreprocError("rparen expected %r"%lst)
++				raise PreprocError('rparen expected %r'%lst)
 +			if int(num):
 +				return get_term(lst[1:i])
 +			else:
@@ -5602,7 +5849,7 @@ Last-Update: 2014-11-28
 +				return get_term([(NUM,num2)]+lst)
 +			p2,v2=lst[0]
 +			if p2!=OP:
-+				raise PreprocError("op expected %r"%lst)
++				raise PreprocError('op expected %r'%lst)
 +			if prec[v2]>=prec[v]:
 +				num2=reduce_nums(num,num2,v)
 +				return get_term([(NUM,num2)]+lst)
@@ -5610,7 +5857,7 @@ Last-Update: 2014-11-28
 +				num3,lst=get_num(lst[1:])
 +				num3=reduce_nums(num2,num3,v2)
 +				return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
-+	raise PreprocError("cannot reduce %r"%lst)
++	raise PreprocError('cannot reduce %r'%lst)
 +def reduce_eval(lst):
 +	num,lst=get_term(lst)
 +	return(NUM,num)
@@ -5650,7 +5897,7 @@ Last-Update: 2014-11-28
 +					else:
 +						lst[i]=(NUM,0)
 +				else:
-+					raise PreprocError("Invalid define expression %r"%lst)
++					raise PreprocError('Invalid define expression %r'%lst)
 +		elif p==IDENT and v in defs:
 +			if isinstance(defs[v],str):
 +				a,b=extract_macro(defs[v])
@@ -5661,17 +5908,17 @@ Last-Update: 2014-11-28
 +				del lst[i]
 +				accu=to_add[:]
 +				reduce_tokens(accu,defs,ban+[v])
-+				for x in range(len(accu)):
-+					lst.insert(i,accu[x])
++				for tmp in accu:
++					lst.insert(i,tmp)
 +					i+=1
 +			else:
 +				args=[]
 +				del lst[i]
 +				if i>=len(lst):
-+					raise PreprocError("expected '(' after %r (got nothing)"%v)
++					raise PreprocError('expected ( after %r (got nothing)'%v)
 +				(p2,v2)=lst[i]
 +				if p2!=OP or v2!='(':
-+					raise PreprocError("expected '(' after %r"%v)
++					raise PreprocError('expected ( after %r'%v)
 +				del lst[i]
 +				one_param=[]
 +				count_paren=0
@@ -5686,7 +5933,7 @@ Last-Update: 2014-11-28
 +							if one_param:args.append(one_param)
 +							break
 +						elif v2==',':
-+							if not one_param:raise PreprocError("empty param in funcall %s"%v)
++							if not one_param:raise PreprocError('empty param in funcall %r'%v)
 +							args.append(one_param)
 +							one_param=[]
 +						else:
@@ -5754,7 +6001,7 @@ Last-Update: 2014-11-28
 +		i+=1
 +def eval_macro(lst,defs):
 +	reduce_tokens(lst,defs,[])
-+	if not lst:raise PreprocError("missing tokens to evaluate")
++	if not lst:raise PreprocError('missing tokens to evaluate')
 +	(p,v)=reduce_eval(lst)
 +	return int(v)!=0
 +def extract_macro(txt):
@@ -5762,7 +6009,7 @@ Last-Update: 2014-11-28
 +	if re_fun.search(txt):
 +		p,name=t[0]
 +		p,v=t[1]
-+		if p!=OP:raise PreprocError("expected open parenthesis")
++		if p!=OP:raise PreprocError('expected (')
 +		i=1
 +		pindex=0
 +		params={}
@@ -5778,27 +6025,27 @@ Last-Update: 2014-11-28
 +				elif p==OP and v==')':
 +					break
 +				else:
-+					raise PreprocError("unexpected token (3)")
++					raise PreprocError('unexpected token (3)')
 +			elif prev==IDENT:
 +				if p==OP and v==',':
 +					prev=v
 +				elif p==OP and v==')':
 +					break
 +				else:
-+					raise PreprocError("comma or ... expected")
++					raise PreprocError('comma or ... expected')
 +			elif prev==',':
 +				if p==IDENT:
 +					params[v]=pindex
 +					pindex+=1
 +					prev=p
 +				elif p==OP and v=='...':
-+					raise PreprocError("not implemented (1)")
++					raise PreprocError('not implemented (1)')
 +				else:
-+					raise PreprocError("comma or ... expected (2)")
++					raise PreprocError('comma or ... expected (2)')
 +			elif prev=='...':
-+				raise PreprocError("not implemented (2)")
++				raise PreprocError('not implemented (2)')
 +			else:
-+				raise PreprocError("unexpected else")
++				raise PreprocError('unexpected else')
 +		return(name,[params,t[i+1:]])
 +	else:
 +		(p,v)=t[0]
@@ -5806,16 +6053,16 @@ Last-Update: 2014-11-28
 +			return(v,[[],t[1:]])
 +		else:
 +			return(v,[[],[('T','')]])
-+re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
++re_include=re.compile('^\s*(<(?:.*)>|"(?:.*)")')
 +def extract_include(txt,defs):
 +	m=re_include.search(txt)
 +	if m:
-+		if m.group('a'):return'<',m.group('a')
-+		if m.group('b'):return'"',m.group('b')
++		txt=m.group(1)
++		return txt[0],txt[1:-1]
 +	toks=tokenize(txt)
 +	reduce_tokens(toks,defs,['waf_include'])
 +	if not toks:
-+		raise PreprocError("could not parse include %s"%txt)
++		raise PreprocError('could not parse include %r'%txt)
 +	if len(toks)==1:
 +		if toks[0][0]==STR:
 +			return'"',toks[0][1]
@@ -5823,9 +6070,10 @@ Last-Update: 2014-11-28
 +		if toks[0][1]=='<'and toks[-1][1]=='>':
 +			ret='<',stringize(toks).lstrip('<').rstrip('>')
 +			return ret
-+	raise PreprocError("could not parse include %s."%txt)
++	raise PreprocError('could not parse include %r'%txt)
 +def parse_char(txt):
-+	if not txt:raise PreprocError("attempted to parse a null char")
++	if not txt:
++		raise PreprocError('attempted to parse a null char')
 +	if txt[0]!='\\':
 +		return ord(txt)
 +	c=txt[1]
@@ -5839,10 +6087,9 @@ Last-Update: 2014-11-28
 +				return(1+i,int(txt[1:1+i],8))
 +	else:
 +		try:return chr_esc[c]
-+		except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
++		except KeyError:raise PreprocError('could not parse char literal %r'%txt)
 +def tokenize(s):
 +	return tokenize_private(s)[:]
-+ at Utils.run_once
 +def tokenize_private(s):
 +	ret=[]
 +	for match in re_clexer.finditer(s):
@@ -5852,7 +6099,7 @@ Last-Update: 2014-11-28
 +			if v:
 +				if name==IDENT:
 +					try:
-+						g_optrans[v];
++						g_optrans[v]
 +						name=OP
 +					except KeyError:
 +						if v.lower()=="true":
@@ -5877,9 +6124,18 @@ Last-Update: 2014-11-28
 +				ret.append((name,v))
 +				break
 +	return ret
-+ at Utils.run_once
-+def define_name(line):
-+	return re_mac.match(line).group(0)
++def format_defines(lst):
++	ret=[]
++	for y in lst:
++		if y:
++			pos=y.find('=')
++			if pos==-1:
++				ret.append(y)
++			elif pos>0:
++				ret.append('%s %s'%(y[:pos],y[pos+1:]))
++			else:
++				raise ValueError('Invalid define expression %r'%y)
++	return ret
 +class c_parser(object):
 +	def __init__(self,nodepaths=None,defines=None):
 +		self.lines=[]
@@ -5894,15 +6150,16 @@ Last-Update: 2014-11-28
 +		self.nodes=[]
 +		self.names=[]
 +		self.curfile=''
-+		self.ban_includes=set([])
++		self.ban_includes=set()
 +	def cached_find_resource(self,node,filename):
 +		try:
-+			nd=node.ctx.cache_nd
++			cache=node.ctx.preproc_cache_node
 +		except AttributeError:
-+			nd=node.ctx.cache_nd={}
-+		tup=(node,filename)
++			global FILE_CACHE_SIZE
++			cache=node.ctx.preproc_cache_node=Utils.lru_cache(FILE_CACHE_SIZE)
++		key=(node,filename)
 +		try:
-+			return nd[tup]
++			return cache[key]
 +		except KeyError:
 +			ret=node.find_resource(filename)
 +			if ret:
@@ -5912,7 +6169,7 @@ Last-Update: 2014-11-28
 +					tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
 +					if tmp and getattr(tmp,'children',None):
 +						ret=None
-+			nd[tup]=ret
++			cache[key]=ret
 +			return ret
 +	def tryfind(self,filename):
 +		if filename.endswith('.moc'):
@@ -5931,49 +6188,51 @@ Last-Update: 2014-11-28
 +			if not filename in self.names:
 +				self.names.append(filename)
 +		return found
++	def filter_comments(self,node):
++		code=node.read()
++		if use_trigraphs:
++			for(a,b)in trig_def:code=code.split(a).join(b)
++		code=re_nl.sub('',code)
++		code=re_cpp.sub(repl,code)
++		return re_lines.findall(code)
++	def parse_lines(self,node):
++		try:
++			cache=node.ctx.preproc_cache_lines
++		except AttributeError:
++			global LINE_CACHE_SIZE
++			cache=node.ctx.preproc_cache_lines=Utils.lru_cache(LINE_CACHE_SIZE)
++		try:
++			return cache[node]
++		except KeyError:
++			cache[node]=lines=self.filter_comments(node)
++			lines.append((POPFILE,''))
++			lines.reverse()
++			return lines
 +	def addlines(self,node):
 +		self.currentnode_stack.append(node.parent)
-+		filepath=node.abspath()
 +		self.count_files+=1
 +		if self.count_files>recursion_limit:
-+			raise PreprocError("recursion limit exceeded")
-+		pc=self.parse_cache
-+		debug('preproc: reading file %r',filepath)
-+		try:
-+			lns=pc[filepath]
-+		except KeyError:
-+			pass
-+		else:
-+			self.lines.extend(lns)
-+			return
++			raise PreprocError('recursion limit exceeded')
++		if Logs.verbose:
++			Logs.debug('preproc: reading file %r',node)
 +		try:
-+			lines=filter_comments(filepath)
-+			lines.append((POPFILE,''))
-+			lines.reverse()
-+			pc[filepath]=lines
-+			self.lines.extend(lines)
-+		except IOError:
-+			raise PreprocError("could not read the file %s"%filepath)
++			lines=self.parse_lines(node)
++		except EnvironmentError:
++			raise PreprocError('could not read the file %r'%node)
 +		except Exception:
 +			if Logs.verbose>0:
-+				error("parsing %s failed"%filepath)
++				Logs.error('parsing %r failed',node)
 +				traceback.print_exc()
++		else:
++			self.lines.extend(lines)
 +	def start(self,node,env):
-+		debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
-+		bld=node.ctx
-+		try:
-+			self.parse_cache=bld.parse_cache
-+		except AttributeError:
-+			self.parse_cache=bld.parse_cache={}
++		Logs.debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
 +		self.current_file=node
 +		self.addlines(node)
-+		if env['DEFINES']:
-+			try:
-+				lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
-+				lst.reverse()
-+				self.lines.extend([('define',x)for x in lst])
-+			except AttributeError:
-+				pass
++		if env.DEFINES:
++			lst=format_defines(env.DEFINES)
++			lst.reverse()
++			self.lines.extend([('define',x)for x in lst])
 +		while self.lines:
 +			(token,line)=self.lines.pop()
 +			if token==POPFILE:
@@ -5982,7 +6241,7 @@ Last-Update: 2014-11-28
 +				continue
 +			try:
 +				ve=Logs.verbose
-+				if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
++				if ve:Logs.debug('preproc: line is %s - %s state is %s',token,line,self.state)
 +				state=self.state
 +				if token[:2]=='if':
 +					state.append(undefined)
@@ -5997,15 +6256,15 @@ Last-Update: 2014-11-28
 +					else:state[-1]=ignored
 +				elif token=='ifdef':
 +					m=re_mac.match(line)
-+					if m and m.group(0)in self.defs:state[-1]=accepted
++					if m and m.group()in self.defs:state[-1]=accepted
 +					else:state[-1]=ignored
 +				elif token=='ifndef':
 +					m=re_mac.match(line)
-+					if m and m.group(0)in self.defs:state[-1]=ignored
++					if m and m.group()in self.defs:state[-1]=ignored
 +					else:state[-1]=accepted
 +				elif token=='include'or token=='import':
 +					(kind,inc)=extract_include(line,self.defs)
-+					if ve:debug('preproc: include found %s    (%s) ',inc,kind)
++					if ve:Logs.debug('preproc: include found %s    (%s) ',inc,kind)
 +					if kind=='"'or not strict_quotes:
 +						self.current_file=self.tryfind(inc)
 +						if token=='import':
@@ -6021,19 +6280,21 @@ Last-Update: 2014-11-28
 +					elif state[-1]==ignored:state[-1]=accepted
 +				elif token=='define':
 +					try:
-+						self.defs[define_name(line)]=line
-+					except Exception:
-+						raise PreprocError("Invalid define line %s"%line)
++						self.defs[self.define_name(line)]=line
++					except AttributeError:
++						raise PreprocError('Invalid define line %r'%line)
 +				elif token=='undef':
 +					m=re_mac.match(line)
-+					if m and m.group(0)in self.defs:
-+						self.defs.__delitem__(m.group(0))
++					if m and m.group()in self.defs:
++						self.defs.__delitem__(m.group())
 +				elif token=='pragma':
 +					if re_pragma_once.match(line.lower()):
 +						self.ban_includes.add(self.current_file)
 +			except Exception ,e:
 +				if Logs.verbose:
-+					debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
++					Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
++	def define_name(self,line):
++		return re_mac.match(line).group()
 +def scan(task):
 +	global go_absolute
 +	try:
@@ -6046,12 +6307,10 @@ Last-Update: 2014-11-28
 +		nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
 +	tmp=c_parser(nodepaths)
 +	tmp.start(task.inputs[0],task.env)
-+	if Logs.verbose:
-+		debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
 +	return(tmp.nodes,tmp.names)
 --- /dev/null
 +++ b/waflib/Tools/c_tests.py
-@@ -0,0 +1,153 @@
+@@ -0,0 +1,152 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -6059,7 +6318,6 @@ Last-Update: 2014-11-28
 +from waflib import Task
 +from waflib.Configure import conf
 +from waflib.TaskGen import feature,before_method,after_method
-+import sys
 +LIB_CODE='''
 +#ifdef _MSC_VER
 +#define testEXPORT __declspec(dllexport)
@@ -6102,7 +6360,7 @@ Last-Update: 2014-11-28
 +		mode='c'
 +		if self.env.CXX:
 +			mode='cxx'
-+	self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec,)
++	self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec)
 +INLINE_CODE='''
 +typedef int foo_t;
 +static %s foo_t static_foo () {return 0; }
@@ -6203,17 +6461,17 @@ Last-Update: 2014-11-28
 +	tmp=[]
 +	def check_msg(self):
 +		return tmp[0]
-+	self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg="Checking for endianness",define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
++	self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg='Checking for endianness',define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
 +	return tmp[0]
 --- /dev/null
 +++ b/waflib/Tools/ccroot.py
-@@ -0,0 +1,444 @@
+@@ -0,0 +1,476 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os,re
-+from waflib import Task,Utils,Node,Errors
++from waflib import Task,Utils,Node,Errors,Logs
 +from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
 +from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
 +from waflib.Configure import conf
@@ -6223,8 +6481,8 @@ Last-Update: 2014-11-28
 +USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
 +USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
 +USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
-+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
-+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
++USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
++USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
 +USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
 +USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
 +USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
@@ -6242,7 +6500,7 @@ Last-Update: 2014-11-28
 + at taskgen_method
 +def to_incnodes(self,inlst):
 +	lst=[]
-+	seen=set([])
++	seen=set()
 +	for x in self.to_list(inlst):
 +		if x in seen or not x:
 +			continue
@@ -6267,15 +6525,20 @@ Last-Update: 2014-11-28
 + at feature('c','cxx','d','asm','fc','includes')
 + at after_method('propagate_uselib_vars','process_source')
 +def apply_incpaths(self):
-+	lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env['INCLUDES'])
++	lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env.INCLUDES)
 +	self.includes_nodes=lst
-+	self.env['INCPATHS']=[x.abspath()for x in lst]
++	cwd=self.get_cwd()
++	self.env.INCPATHS=[x.path_from(cwd)for x in lst]
 +class link_task(Task.Task):
 +	color='YELLOW'
 +	inst_to=None
 +	chmod=Utils.O755
 +	def add_target(self,target):
 +		if isinstance(target,str):
++			base=self.generator.path
++			if target.startswith('#'):
++				target=target[1:]
++				base=self.generator.bld.bldnode
 +			pattern=self.env[self.__class__.__name__+'_PATTERN']
 +			if not pattern:
 +				pattern='%s'
@@ -6288,9 +6551,39 @@ Last-Update: 2014-11-28
 +					pattern='%s.%s'%(pattern,nums[0])
 +					if len(nums)>=2:
 +						pattern+='.%s'%nums[1]
-+			tmp=folder+os.sep+pattern%name
-+			target=self.generator.path.find_or_declare(tmp)
++			if folder:
++				tmp=folder+os.sep+pattern%name
++			else:
++				tmp=pattern%name
++			target=base.find_or_declare(tmp)
 +		self.set_outputs(target)
++	def exec_command(self,*k,**kw):
++		ret=super(link_task,self).exec_command(*k,**kw)
++		if not ret and self.env.DO_MANIFEST:
++			ret=self.exec_mf()
++		return ret
++	def exec_mf(self):
++		if not self.env.MT:
++			return 0
++		manifest=None
++		for out_node in self.outputs:
++			if out_node.name.endswith('.manifest'):
++				manifest=out_node.abspath()
++				break
++		else:
++			return 0
++		mode=''
++		for x in Utils.to_list(self.generator.features):
++			if x in('cprogram','cxxprogram','fcprogram','fcprogram_test'):
++				mode=1
++			elif x in('cshlib','cxxshlib','fcshlib'):
++				mode=2
++		Logs.debug('msvc: embedding manifest in mode %r',mode)
++		lst=[]+self.env.MT
++		lst.extend(Utils.to_list(self.env.MTFLAGS))
++		lst.extend(['-manifest',manifest])
++		lst.append('-outputresource:%s;%s'%(self.outputs[0].abspath(),mode))
++		return super(link_task,self).exec_command(lst)
 +class stlink_task(link_task):
 +	run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
 +	chmod=Utils.O644
@@ -6324,7 +6617,7 @@ Last-Update: 2014-11-28
 +	except AttributeError:
 +		inst_to=self.link_task.__class__.inst_to
 +	if inst_to:
-+		self.install_task=self.bld.install_files(inst_to,self.link_task.outputs[:],env=self.env,chmod=self.link_task.chmod,task=self.link_task)
++		self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task)
 + at taskgen_method
 +def use_rec(self,name,**kw):
 +	if name in self.tmp_use_not or name in self.tmp_use_seen:
@@ -6363,7 +6656,7 @@ Last-Update: 2014-11-28
 + at before_method('apply_incpaths','propagate_uselib_vars')
 + at after_method('apply_link','process_source')
 +def process_use(self):
-+	use_not=self.tmp_use_not=set([])
++	use_not=self.tmp_use_not=set()
 +	self.tmp_use_seen=[]
 +	use_prec=self.tmp_use_prec={}
 +	self.uselib=self.to_list(getattr(self,'uselib',[]))
@@ -6374,7 +6667,7 @@ Last-Update: 2014-11-28
 +	for x in use_not:
 +		if x in use_prec:
 +			del use_prec[x]
-+	out=[]
++	out=self.tmp_use_sorted=[]
 +	tmp=[]
 +	for x in self.tmp_use_seen:
 +		for k in use_prec.values():
@@ -6408,7 +6701,7 @@ Last-Update: 2014-11-28
 +			if var=='LIB'or y.tmp_use_stlib or x in names:
 +				self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
 +				self.link_task.dep_nodes.extend(y.link_task.outputs)
-+				tmp_path=y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
++				tmp_path=y.link_task.outputs[0].parent.path_from(self.get_cwd())
 +				self.env.append_unique(var+'PATH',[tmp_path])
 +		else:
 +			if y.tmp_use_objects:
@@ -6443,7 +6736,7 @@ Last-Update: 2014-11-28
 +					link_task.inputs.append(x)
 + at taskgen_method
 +def get_uselib_vars(self):
-+	_vars=set([])
++	_vars=set()
 +	for x in self.features:
 +		if x in USELIB_VARS:
 +			_vars|=USELIB_VARS[x]
@@ -6474,16 +6767,16 @@ Last-Update: 2014-11-28
 +		name=self.target.name
 +	else:
 +		name=os.path.split(self.target)[1]
-+	implib=self.env['implib_PATTERN']%name
++	implib=self.env.implib_PATTERN%name
 +	implib=dll.parent.find_or_declare(implib)
-+	self.env.append_value('LINKFLAGS',self.env['IMPLIB_ST']%implib.bldpath())
++	self.env.append_value('LINKFLAGS',self.env.IMPLIB_ST%implib.bldpath())
 +	self.link_task.outputs.append(implib)
 +	if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
 +		node=self.path.find_resource(self.defs)
 +		if not node:
 +			raise Errors.WafError('invalid def file %r'%self.defs)
 +		if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
-+			self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.bld.bldnode))
++			self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.get_cwd()))
 +			self.link_task.dep_nodes.append(node)
 +		else:
 +			self.link_task.inputs.append(node)
@@ -6495,10 +6788,10 @@ Last-Update: 2014-11-28
 +				inst_to=self.install_path
 +			except AttributeError:
 +				inst_to='${IMPLIBDIR}'
-+				self.install_task.dest='${BINDIR}'
++				self.install_task.install_to='${BINDIR}'
 +				if not self.env.IMPLIBDIR:
 +					self.env.IMPLIBDIR=self.env.LIBDIR
-+		self.implib_install_task=self.bld.install_files(inst_to,implib,env=self.env,chmod=self.link_task.chmod,task=self.link_task)
++		self.implib_install_task=self.add_install_files(install_to=inst_to,install_from=implib,chmod=self.link_task.chmod,task=self.link_task)
 +re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$')
 + at feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
 + at after_method('apply_link','propagate_uselib_vars')
@@ -6525,27 +6818,26 @@ Last-Update: 2014-11-28
 +		v=self.env.SONAME_ST%name2
 +		self.env.append_value('LINKFLAGS',v.split())
 +	if self.env.DEST_OS!='openbsd':
-+		outs=[node.parent.find_or_declare(name3)]
++		outs=[node.parent.make_node(name3)]
 +		if name2!=name3:
-+			outs.append(node.parent.find_or_declare(name2))
++			outs.append(node.parent.make_node(name2))
 +		self.create_task('vnum',node,outs)
 +	if getattr(self,'install_task',None):
 +		self.install_task.hasrun=Task.SKIP_ME
-+		bld=self.bld
-+		path=self.install_task.dest
++		path=self.install_task.install_to
 +		if self.env.DEST_OS=='openbsd':
 +			libname=self.link_task.outputs[0].name
-+			t1=bld.install_as('%s%s%s'%(path,os.sep,libname),node,env=self.env,chmod=self.link_task.chmod)
++			t1=self.add_install_as(install_to='%s/%s'%(path,libname),install_from=node,chmod=self.link_task.chmod)
 +			self.vnum_install_task=(t1,)
 +		else:
-+			t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
-+			t3=bld.symlink_as(path+os.sep+libname,name3)
++			t1=self.add_install_as(install_to=path+os.sep+name3,install_from=node,chmod=self.link_task.chmod)
++			t3=self.add_symlink_as(install_to=path+os.sep+libname,install_from=name3)
 +			if name2!=name3:
-+				t2=bld.symlink_as(path+os.sep+name2,name3)
++				t2=self.add_symlink_as(install_to=path+os.sep+name2,install_from=name3)
 +				self.vnum_install_task=(t1,t2,t3)
 +			else:
 +				self.vnum_install_task=(t1,t3)
-+	if'-dynamiclib'in self.env['LINKFLAGS']:
++	if'-dynamiclib'in self.env.LINKFLAGS:
 +		try:
 +			inst_to=self.install_path
 +		except AttributeError:
@@ -6558,7 +6850,6 @@ Last-Update: 2014-11-28
 +			self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum)
 +class vnum(Task.Task):
 +	color='CYAN'
-+	quient=True
 +	ext_in=['.bin']
 +	def keyword(self):
 +		return'Symlinking'
@@ -6578,16 +6869,12 @@ Last-Update: 2014-11-28
 +		for t in self.run_after:
 +			if not t.hasrun:
 +				return Task.ASK_LATER
-+		for x in self.outputs:
-+			x.sig=Utils.h_file(x.abspath())
 +		return Task.SKIP_ME
 +class fake_stlib(stlink_task):
 +	def runnable_status(self):
 +		for t in self.run_after:
 +			if not t.hasrun:
 +				return Task.ASK_LATER
-+		for x in self.outputs:
-+			x.sig=Utils.h_file(x.abspath())
 +		return Task.SKIP_ME
 + at conf
 +def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
@@ -6608,7 +6895,10 @@ Last-Update: 2014-11-28
 +		for y in names:
 +			node=x.find_node(y)
 +			if node:
-+				node.sig=Utils.h_file(node.abspath())
++				try:
++					Utils.h_file(node.abspath())
++				except EnvironmentError:
++					raise ValueError('Could not read %r'%y)
 +				break
 +		else:
 +			continue
@@ -6659,7 +6949,6 @@ Last-Update: 2014-11-28
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
 +from waflib.Tools import ccroot,ar,gcc
 +from waflib.Configure import conf
 + at conf
@@ -6669,6 +6958,7 @@ Last-Update: 2014-11-28
 +	conf.env.CC_NAME='clang'
 +def configure(conf):
 +	conf.find_clang()
++	conf.find_program(['llvm-ar','ar'],var='AR')
 +	conf.find_ar()
 +	conf.gcc_common_flags()
 +	conf.gcc_modifier_platform()
@@ -6682,7 +6972,6 @@ Last-Update: 2014-11-28
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
 +from waflib.Tools import ccroot,ar,gxx
 +from waflib.Configure import conf
 + at conf
@@ -6692,6 +6981,7 @@ Last-Update: 2014-11-28
 +	conf.env.CXX_NAME='clang'
 +def configure(conf):
 +	conf.find_clangxx()
++	conf.find_program(['llvm-ar','ar'],var='AR')
 +	conf.find_ar()
 +	conf.gxx_common_flags()
 +	conf.gxx_modifier_platform()
@@ -6700,23 +6990,25 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/compiler_c.py
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,44 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,imp,types,re
++import re
 +from waflib.Tools import ccroot
-+from waflib import Utils,Configure
++from waflib import Utils
 +from waflib.Logs import debug
-+c_compiler={'win32':['msvc','gcc','clang'],'cygwin':['gcc'],'darwin':['clang','gcc'],'aix':['xlc','gcc','clang'],'linux':['gcc','clang','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'osf1V':['gcc'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['gcc','clang'],}
++c_compiler={'win32':['msvc','gcc','clang'],'cygwin':['gcc'],'darwin':['clang','gcc'],'aix':['xlc','gcc','clang'],'linux':['gcc','clang','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'osf1V':['gcc'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['clang','gcc'],}
 +def default_compilers():
 +	build_platform=Utils.unversioned_sys_platform()
 +	possible_compiler_list=c_compiler.get(build_platform,c_compiler['default'])
 +	return' '.join(possible_compiler_list)
 +def configure(conf):
-+	try:test_for_compiler=conf.options.check_c_compiler or default_compilers()
-+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_c')")
++	try:
++		test_for_compiler=conf.options.check_c_compiler or default_compilers()
++	except AttributeError:
++		conf.fatal("Add options(opt): opt.load('compiler_c')")
 +	for compiler in re.split('[ ,]+',test_for_compiler):
 +		conf.env.stash()
 +		conf.start_msg('Checking for %r (C compiler)'%compiler)
@@ -6725,12 +7017,14 @@ Last-Update: 2014-11-28
 +		except conf.errors.ConfigurationError ,e:
 +			conf.env.revert()
 +			conf.end_msg(False)
-+			debug('compiler_c: %r'%e)
++			debug('compiler_c: %r',e)
 +		else:
-+			if conf.env['CC']:
++			if conf.env.CC:
 +				conf.end_msg(conf.env.get_flat('CC'))
-+				conf.env['COMPILER_CC']=compiler
++				conf.env.COMPILER_CC=compiler
++				conf.env.commit()
 +				break
++			conf.env.revert()
 +			conf.end_msg(False)
 +	else:
 +		conf.fatal('could not configure a C compiler!')
@@ -6743,23 +7037,25 @@ Last-Update: 2014-11-28
 +		opt.load('%s'%x)
 --- /dev/null
 +++ b/waflib/Tools/compiler_cxx.py
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,44 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,imp,types,re
++import re
 +from waflib.Tools import ccroot
-+from waflib import Utils,Configure
++from waflib import Utils
 +from waflib.Logs import debug
-+cxx_compiler={'win32':['msvc','g++','clang++'],'cygwin':['g++'],'darwin':['clang++','g++'],'aix':['xlc++','g++','clang++'],'linux':['g++','clang++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'osf1V':['g++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['g++','clang++']}
++cxx_compiler={'win32':['msvc','g++','clang++'],'cygwin':['g++'],'darwin':['clang++','g++'],'aix':['xlc++','g++','clang++'],'linux':['g++','clang++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'osf1V':['g++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['clang++','g++']}
 +def default_compilers():
 +	build_platform=Utils.unversioned_sys_platform()
 +	possible_compiler_list=cxx_compiler.get(build_platform,cxx_compiler['default'])
 +	return' '.join(possible_compiler_list)
 +def configure(conf):
-+	try:test_for_compiler=conf.options.check_cxx_compiler or default_compilers()
-+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_cxx')")
++	try:
++		test_for_compiler=conf.options.check_cxx_compiler or default_compilers()
++	except AttributeError:
++		conf.fatal("Add options(opt): opt.load('compiler_cxx')")
 +	for compiler in re.split('[ ,]+',test_for_compiler):
 +		conf.env.stash()
 +		conf.start_msg('Checking for %r (C++ compiler)'%compiler)
@@ -6768,12 +7064,14 @@ Last-Update: 2014-11-28
 +		except conf.errors.ConfigurationError ,e:
 +			conf.env.revert()
 +			conf.end_msg(False)
-+			debug('compiler_cxx: %r'%e)
++			debug('compiler_cxx: %r',e)
 +		else:
-+			if conf.env['CXX']:
++			if conf.env.CXX:
 +				conf.end_msg(conf.env.get_flat('CXX'))
-+				conf.env['COMPILER_CXX']=compiler
++				conf.env.COMPILER_CXX=compiler
++				conf.env.commit()
 +				break
++			conf.env.revert()
 +			conf.end_msg(False)
 +	else:
 +		conf.fatal('could not configure a C++ compiler!')
@@ -6786,21 +7084,23 @@ Last-Update: 2014-11-28
 +		opt.load('%s'%x)
 --- /dev/null
 +++ b/waflib/Tools/compiler_d.py
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,41 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,imp,types,re
-+from waflib import Utils,Configure,Options,Logs
-+d_compiler={'default':['gdc','dmd','ldc2']}
++import re
++from waflib import Utils,Logs
++d_compiler={'default':['gdc','dmd','ldc2']}
 +def default_compilers():
 +	build_platform=Utils.unversioned_sys_platform()
 +	possible_compiler_list=d_compiler.get(build_platform,d_compiler['default'])
 +	return' '.join(possible_compiler_list)
 +def configure(conf):
-+	try:test_for_compiler=conf.options.check_d_compiler or default_compilers()
-+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_d')")
++	try:
++		test_for_compiler=conf.options.check_d_compiler or default_compilers()
++	except AttributeError:
++		conf.fatal("Add options(opt): opt.load('compiler_d')")
 +	for compiler in re.split('[ ,]+',test_for_compiler):
 +		conf.env.stash()
 +		conf.start_msg('Checking for %r (D compiler)'%compiler)
@@ -6809,12 +7109,14 @@ Last-Update: 2014-11-28
 +		except conf.errors.ConfigurationError ,e:
 +			conf.env.revert()
 +			conf.end_msg(False)
-+			Logs.debug('compiler_d: %r'%e)
++			Logs.debug('compiler_d: %r',e)
 +		else:
 +			if conf.env.D:
 +				conf.end_msg(conf.env.get_flat('D'))
-+				conf.env['COMPILER_D']=compiler
++				conf.env.COMPILER_D=compiler
++				conf.env.commit()
 +				break
++			conf.env.revert()
 +			conf.end_msg(False)
 +	else:
 +		conf.fatal('could not configure a D compiler!')
@@ -6826,13 +7128,13 @@ Last-Update: 2014-11-28
 +		opt.load('%s'%x)
 --- /dev/null
 +++ b/waflib/Tools/compiler_fc.py
-@@ -0,0 +1,39 @@
+@@ -0,0 +1,43 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,imp,types,re
-+from waflib import Utils,Configure,Options,Logs,Errors
++import re
++from waflib import Utils,Logs
 +from waflib.Tools import fc
 +fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
 +def default_compilers():
@@ -6840,8 +7142,10 @@ Last-Update: 2014-11-28
 +	possible_compiler_list=fc_compiler.get(build_platform,fc_compiler['default'])
 +	return' '.join(possible_compiler_list)
 +def configure(conf):
-+	try:test_for_compiler=conf.options.check_fortran_compiler or default_compilers()
-+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_fc')")
++	try:
++		test_for_compiler=conf.options.check_fortran_compiler or default_compilers()
++	except AttributeError:
++		conf.fatal("Add options(opt): opt.load('compiler_fc')")
 +	for compiler in re.split('[ ,]+',test_for_compiler):
 +		conf.env.stash()
 +		conf.start_msg('Checking for %r (Fortran compiler)'%compiler)
@@ -6850,12 +7154,14 @@ Last-Update: 2014-11-28
 +		except conf.errors.ConfigurationError ,e:
 +			conf.env.revert()
 +			conf.end_msg(False)
-+			Logs.debug('compiler_fortran: %r'%e)
++			Logs.debug('compiler_fortran: %r',e)
 +		else:
-+			if conf.env['FC']:
++			if conf.env.FC:
 +				conf.end_msg(conf.env.get_flat('FC'))
 +				conf.env.COMPILER_FORTRAN=compiler
++				conf.env.commit()
 +				break
++			conf.env.revert()
 +			conf.end_msg(False)
 +	else:
 +		conf.fatal('could not configure a Fortran compiler!')
@@ -6868,16 +7174,15 @@ Last-Update: 2014-11-28
 +		opt.load('%s'%x)
 --- /dev/null
 +++ b/waflib/Tools/cs.py
-@@ -0,0 +1,132 @@
+@@ -0,0 +1,98 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+from waflib import Utils,Task,Options,Logs,Errors
++from waflib import Utils,Task,Options,Errors
 +from waflib.TaskGen import before_method,after_method,feature
 +from waflib.Tools import ccroot
 +from waflib.Configure import conf
-+import os,tempfile
 +ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
 +ccroot.lib_patterns['csshlib']=['%s']
 + at feature('cs')
@@ -6899,7 +7204,7 @@ Last-Update: 2014-11-28
 +	inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
 +	if inst_to:
 +		mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
-+		self.install_task=self.bld.install_files(inst_to,self.cs_task.outputs[:],env=self.env,chmod=mod)
++		self.install_task=self.add_install_files(install_to=inst_to,install_from=self.cs_task.outputs[:],chmod=mod)
 + at feature('cs')
 + at after_method('apply_cs')
 +def use_cs(self):
@@ -6945,40 +7250,9 @@ Last-Update: 2014-11-28
 +	color='YELLOW'
 +	run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
 +	def exec_command(self,cmd,**kw):
-+		bld=self.generator.bld
-+		try:
-+			if not kw.get('cwd',None):
-+				kw['cwd']=bld.cwd
-+		except AttributeError:
-+			bld.cwd=kw['cwd']=bld.variant_dir
-+		try:
-+			tmp=None
-+			if isinstance(cmd,list)and len(' '.join(cmd))>=8192:
-+				program=cmd[0]
-+				cmd=[self.quote_response_command(x)for x in cmd]
-+				(fd,tmp)=tempfile.mkstemp()
-+				os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
-+				os.close(fd)
-+				cmd=[program,'@'+tmp]
-+			ret=self.generator.bld.exec_command(cmd,**kw)
-+		finally:
-+			if tmp:
-+				try:
-+					os.remove(tmp)
-+				except OSError:
-+					pass
-+		return ret
-+	def quote_response_command(self,flag):
-+		if flag.lower()=='/noconfig':
-+			return''
-+		if flag.find(' ')>-1:
-+			for x in('/r:','/reference:','/resource:','/lib:','/out:'):
-+				if flag.startswith(x):
-+					flag='%s"%s"'%(x,'","'.join(flag[len(x):].split(',')))
-+					break
-+			else:
-+				flag='"%s"'%flag
-+		return flag
++		if'/noconfig'in cmd:
++			raise ValueError('/noconfig is not allowed when using response files, check your flags!')
++		return super(self.__class__,self).exec_command(cmd,**kw)
 +def configure(conf):
 +	csc=getattr(Options.options,'cscbinary',None)
 +	if csc:
@@ -6995,8 +7269,6 @@ Last-Update: 2014-11-28
 +	color='YELLOW'
 +	inst_to=None
 +	def runnable_status(self):
-+		for x in self.outputs:
-+			x.sig=Utils.h_file(x.abspath())
 +		return Task.SKIP_ME
 + at conf
 +def read_csshlib(self,name,paths=[]):
@@ -7017,7 +7289,7 @@ Last-Update: 2014-11-28
 +if not'.c'in TaskGen.task_gen.mappings:
 +	TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
 +class cxx(Task.Task):
-+	run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()}'
++	run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}'
 +	vars=['CXXDEPS']
 +	ext_in=['.h']
 +	scan=c_preproc.scan
@@ -7070,7 +7342,7 @@ Last-Update: 2014-11-28
 +		return task
 +	if getattr(self,'generate_headers',None):
 +		tsk=create_compiled_task(self,'d_with_header',node)
-+		tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
++		tsk.outputs.append(node.change_ext(self.env.DHEADER_ext))
 +	else:
 +		tsk=create_compiled_task(self,'d',node)
 +	return tsk
@@ -7103,17 +7375,17 @@ Last-Update: 2014-11-28
 +		v.DEST_OS=Utils.unversioned_sys_platform()
 +	binfmt=Utils.destos_to_binfmt(self.env.DEST_OS)
 +	if binfmt=='pe':
-+		v['dprogram_PATTERN']='%s.exe'
-+		v['dshlib_PATTERN']='lib%s.dll'
-+		v['dstlib_PATTERN']='lib%s.a'
++		v.dprogram_PATTERN='%s.exe'
++		v.dshlib_PATTERN='lib%s.dll'
++		v.dstlib_PATTERN='lib%s.a'
 +	elif binfmt=='mac-o':
-+		v['dprogram_PATTERN']='%s'
-+		v['dshlib_PATTERN']='lib%s.dylib'
-+		v['dstlib_PATTERN']='lib%s.a'
++		v.dprogram_PATTERN='%s'
++		v.dshlib_PATTERN='lib%s.dylib'
++		v.dstlib_PATTERN='lib%s.a'
 +	else:
-+		v['dprogram_PATTERN']='%s'
-+		v['dshlib_PATTERN']='lib%s.so'
-+		v['dstlib_PATTERN']='lib%s.a'
++		v.dprogram_PATTERN='%s'
++		v.dshlib_PATTERN='lib%s.so'
++		v.dstlib_PATTERN='lib%s.a'
 +DLIB='''
 +version(D_Version2) {
 +	import std.stdio;
@@ -7144,13 +7416,13 @@ Last-Update: 2014-11-28
 +		self.env.DLIBRARY=ret.strip()
 --- /dev/null
 +++ b/waflib/Tools/d_scan.py
-@@ -0,0 +1,133 @@
+@@ -0,0 +1,131 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import re
-+from waflib import Utils,Logs
++from waflib import Utils
 +def filter_comments(filename):
 +	txt=Utils.readf(filename)
 +	i=0
@@ -7275,8 +7547,6 @@ Last-Update: 2014-11-28
 +	gruik.start(node)
 +	nodes=gruik.nodes
 +	names=gruik.names
-+	if Logs.verbose:
-+		Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names))
 +	return(nodes,names)
 --- /dev/null
 +++ b/waflib/Tools/dbus.py
@@ -7309,7 +7579,7 @@ Last-Update: 2014-11-28
 +	run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
 +	shell=True
 +def configure(conf):
-+	dbus_binding_tool=conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
++	conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
 --- /dev/null
 +++ b/waflib/Tools/dmd.py
 @@ -0,0 +1,51 @@
@@ -7331,32 +7601,32 @@ Last-Update: 2014-11-28
 + at conf
 +def common_flags_ldc(conf):
 +	v=conf.env
-+	v['DFLAGS']=['-d-version=Posix']
-+	v['LINKFLAGS']=[]
-+	v['DFLAGS_dshlib']=['-relocation-model=pic']
++	v.DFLAGS=['-d-version=Posix']
++	v.LINKFLAGS=[]
++	v.DFLAGS_dshlib=['-relocation-model=pic']
 + at conf
 +def common_flags_dmd(conf):
 +	v=conf.env
-+	v['D_SRC_F']=['-c']
-+	v['D_TGT_F']='-of%s'
-+	v['D_LINKER']=v['D']
-+	v['DLNK_SRC_F']=''
-+	v['DLNK_TGT_F']='-of%s'
-+	v['DINC_ST']='-I%s'
-+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
-+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
-+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
-+	v['LINKFLAGS_dprogram']=['-quiet']
-+	v['DFLAGS_dshlib']=['-fPIC']
-+	v['LINKFLAGS_dshlib']=['-L-shared']
-+	v['DHEADER_ext']='.di'
++	v.D_SRC_F=['-c']
++	v.D_TGT_F='-of%s'
++	v.D_LINKER=v.D
++	v.DLNK_SRC_F=''
++	v.DLNK_TGT_F='-of%s'
++	v.DINC_ST='-I%s'
++	v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
++	v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s'
++	v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s'
++	v.LINKFLAGS_dprogram=['-quiet']
++	v.DFLAGS_dshlib=['-fPIC']
++	v.LINKFLAGS_dshlib=['-L-shared']
++	v.DHEADER_ext='.di'
 +	v.DFLAGS_d_with_header=['-H','-Hf']
-+	v['D_HDR_F']='%s'
++	v.D_HDR_F='%s'
 +def configure(conf):
 +	conf.find_dmd()
 +	if sys.platform=='win32':
 +		out=conf.cmd_and_log(conf.env.D+['--help'])
-+		if out.find("D Compiler v2.")>-1:
++		if out.find('D Compiler v2.')>-1:
 +			conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
 +	conf.load('ar')
 +	conf.load('d')
@@ -7366,21 +7636,24 @@ Last-Update: 2014-11-28
 +		conf.common_flags_ldc()
 --- /dev/null
 +++ b/waflib/Tools/errcheck.py
-@@ -0,0 +1,161 @@
+@@ -0,0 +1,167 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy',}
 +meths_typos=['__call__','program','shlib','stlib','objects']
++import sys
 +from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
-+import waflib.Tools.ccroot
++from waflib.Tools import ccroot
 +def check_same_targets(self):
 +	mp=Utils.defaultdict(list)
 +	uids={}
 +	def check_task(tsk):
 +		if not isinstance(tsk,Task.Task):
 +			return
++		if hasattr(tsk,'no_errcheck_out'):
++			return
 +		for node in tsk.outputs:
 +			mp[node].append(tsk)
 +		try:
@@ -7402,35 +7675,38 @@ Last-Update: 2014-11-28
 +			Logs.error(msg)
 +			for x in v:
 +				if Logs.verbose>1:
-+					Logs.error('  %d. %r'%(1+v.index(x),x.generator))
++					Logs.error('  %d. %r',1+v.index(x),x.generator)
 +				else:
-+					Logs.error('  %d. %r in %r'%(1+v.index(x),x.generator.name,getattr(x.generator,'path',None)))
++					Logs.error('  %d. %r in %r',1+v.index(x),x.generator.name,getattr(x.generator,'path',None))
++			Logs.error('If you think that this is an error, set no_errcheck_out on the task instance')
 +	if not dupe:
 +		for(k,v)in uids.items():
 +			if len(v)>1:
 +				Logs.error('* Several tasks use the same identifier. Please check the information on\n   https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid')
 +				for tsk in v:
-+					Logs.error('  - object %r (%r) defined in %r'%(tsk.__class__.__name__,tsk,tsk.generator))
++					Logs.error('  - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tsk.generator)
 +def check_invalid_constraints(self):
-+	feat=set([])
++	feat=set()
 +	for x in list(TaskGen.feats.values()):
 +		feat.union(set(x))
 +	for(x,y)in TaskGen.task_gen.prec.items():
 +		feat.add(x)
 +		feat.union(set(y))
-+	ext=set([])
++	ext=set()
 +	for x in TaskGen.task_gen.mappings.values():
 +		ext.add(x.__name__)
 +	invalid=ext&feat
 +	if invalid:
-+		Logs.error('The methods %r have invalid annotations:  @extension <-> @feature/@before_method/@after_method'%list(invalid))
++		Logs.error('The methods %r have invalid annotations:  @extension <-> @feature/@before_method/@after_method',list(invalid))
 +	for cls in list(Task.classes.values()):
++		if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str):
++			raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)'%(cls,cls.hcode))
 +		for x in('before','after'):
 +			for y in Utils.to_list(getattr(cls,x,[])):
-+				if not Task.classes.get(y,None):
-+					Logs.error('Erroneous order constraint %r=%r on task class %r'%(x,y,cls.__name__))
++				if not Task.classes.get(y):
++					Logs.error('Erroneous order constraint %r=%r on task class %r',x,y,cls.__name__)
 +		if getattr(cls,'rule',None):
-+			Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")'%cls.__name__)
++			Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")',cls.__name__)
 +def replace(m):
 +	oldcall=getattr(Build.BuildContext,m)
 +	def call(self,*k,**kw):
@@ -7439,8 +7715,7 @@ Last-Update: 2014-11-28
 +			if x in kw:
 +				if x=='iscopy'and'subst'in getattr(self,'features',''):
 +					continue
-+				err=True
-+				Logs.error('Fix the typo %r -> %r on %r'%(x,typos[x],ret))
++				Logs.error('Fix the typo %r -> %r on %r',x,typos[x],ret)
 +		return ret
 +	setattr(Build.BuildContext,m,call)
 +def enhance_lib():
@@ -7450,12 +7725,15 @@ Last-Update: 2014-11-28
 +		if k:
 +			lst=Utils.to_list(k[0])
 +			for pat in lst:
-+				if'..'in pat.split('/'):
-+					Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'"%k[0])
++				sp=pat.split('/')
++				if'..'in sp:
++					Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0])
++				if'.'in sp:
++					Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0])
 +		if kw.get('remove',True):
 +			try:
 +				if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
-+					Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)'%self)
++					Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)',self)
 +			except AttributeError:
 +				pass
 +		return self.old_ant_glob(*k,**kw)
@@ -7465,7 +7743,7 @@ Last-Update: 2014-11-28
 +	def is_before(t1,t2):
 +		ret=old(t1,t2)
 +		if ret and old(t2,t1):
-+			Logs.error('Contradictory order constraints in classes %r %r'%(t1,t2))
++			Logs.error('Contradictory order constraints in classes %r %r',t1,t2)
 +		return ret
 +	Task.is_before=is_before
 +	def check_err_features(self):
@@ -7474,18 +7752,18 @@ Last-Update: 2014-11-28
 +			Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
 +		for x in('c','cxx','d','fc'):
 +			if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
-+				Logs.error('%r features is probably missing %r'%(self,x))
++				Logs.error('%r features is probably missing %r',self,x)
 +	TaskGen.feature('*')(check_err_features)
 +	def check_err_order(self):
 +		if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
 +			for x in('before','after','ext_in','ext_out'):
 +				if hasattr(self,x):
-+					Logs.warn('Erroneous order constraint %r on non-rule based task generator %r'%(x,self))
++					Logs.warn('Erroneous order constraint %r on non-rule based task generator %r',x,self)
 +		else:
 +			for x in('before','after'):
 +				for y in self.to_list(getattr(self,x,[])):
 +					if not Task.classes.get(y,None):
-+						Logs.error('Erroneous order constraint %s=%r on %r (no such class)'%(x,y,self))
++						Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self)
 +	TaskGen.feature('*')(check_err_order)
 +	def check_compile(self):
 +		check_invalid_constraints(self)
@@ -7514,7 +7792,7 @@ Last-Update: 2014-11-28
 +		self.orig_use_rec(name,**kw)
 +	TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
 +	TaskGen.task_gen.use_rec=use_rec
-+	def getattri(self,name,default=None):
++	def _getattr(self,name,default=None):
 +		if name=='append'or name=='add':
 +			raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
 +		elif name=='prepend':
@@ -7523,29 +7801,24 @@ Last-Update: 2014-11-28
 +			return object.__getattr__(self,name,default)
 +		else:
 +			return self[name]
-+	ConfigSet.ConfigSet.__getattr__=getattri
++	ConfigSet.ConfigSet.__getattr__=_getattr
 +def options(opt):
 +	enhance_lib()
-+def configure(conf):
-+	pass
 --- /dev/null
 +++ b/waflib/Tools/fc.py
-@@ -0,0 +1,115 @@
+@@ -0,0 +1,108 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+from waflib import Utils,Task,Logs
++from waflib import Utils,Task
 +from waflib.Tools import ccroot,fc_config,fc_scan
-+from waflib.TaskGen import feature,extension
++from waflib.TaskGen import extension
 +from waflib.Configure import conf
-+ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES'])
++ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES','FCPPFLAGS'])
 +ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
 +ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
 +ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
-+ at feature('fcprogram','fcshlib','fcstlib','fcprogram_test')
-+def dummy(self):
-+	pass
 + at extension('.f','.f90','.F','.F90','.for','.FOR')
 +def fc_hook(self,node):
 +	return self.create_compiled_task('fc',node)
@@ -7558,14 +7831,12 @@ Last-Update: 2014-11-28
 +	return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
 +class fc(Task.Task):
 +	color='GREEN'
-+	run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
++	run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}'
 +	vars=["FORTRANMODPATHFLAG"]
 +	def scan(self):
 +		tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
 +		tmp.task=self
 +		tmp.start(self.inputs[0])
-+		if Logs.verbose:
-+			Logs.debug('deps: deps for %r: %r; unresolved %r'%(self.inputs,tmp.nodes,tmp.names))
 +		return(tmp.nodes,tmp.names)
 +	def runnable_status(self):
 +		if getattr(self,'mod_fortran_done',None):
@@ -7588,8 +7859,6 @@ Last-Update: 2014-11-28
 +				if x.startswith('MOD@'):
 +					name=bld.modfile(x.replace('MOD@',''))
 +					node=bld.srcnode.find_or_declare(name)
-+					if not getattr(node,'sig',None):
-+						node.sig=Utils.SIG_NIL
 +					tsk.set_outputs(node)
 +					outs[id(node)].add(tsk)
 +		for tsk in lst:
@@ -7622,6 +7891,8 @@ Last-Update: 2014-11-28
 +	inst_to='${BINDIR}'
 +class fcshlib(fcprogram):
 +	inst_to='${LIBDIR}'
++class fcstlib(ccroot.stlink_task):
++	pass
 +class fcprogram_test(fcprogram):
 +	def runnable_status(self):
 +		ret=super(fcprogram_test,self).runnable_status()
@@ -7632,7 +7903,7 @@ Last-Update: 2014-11-28
 +		bld=self.generator.bld
 +		kw['shell']=isinstance(cmd,str)
 +		kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
-+		kw['cwd']=bld.variant_dir
++		kw['cwd']=self.get_cwd()
 +		bld.out=bld.err=''
 +		bld.to_log('command: %s\n'%cmd)
 +		kw['output']=0
@@ -7641,14 +7912,12 @@ Last-Update: 2014-11-28
 +		except Exception:
 +			return-1
 +		if bld.out:
-+			bld.to_log("out: %s\n"%bld.out)
++			bld.to_log('out: %s\n'%bld.out)
 +		if bld.err:
-+			bld.to_log("err: %s\n"%bld.err)
-+class fcstlib(ccroot.stlink_task):
-+	pass
++			bld.to_log('err: %s\n'%bld.err)
 --- /dev/null
 +++ b/waflib/Tools/fc_config.py
-@@ -0,0 +1,286 @@
+@@ -0,0 +1,287 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -7656,32 +7925,33 @@ Last-Update: 2014-11-28
 +import re,os,sys,shlex
 +from waflib.Configure import conf
 +from waflib.TaskGen import feature,before_method
-+from waflib import Utils
 +FC_FRAGMENT='        program main\n        end     program main\n'
 +FC_FRAGMENT2='        PROGRAM MAIN\n        END\n'
 + at conf
 +def fc_flags(conf):
 +	v=conf.env
-+	v['FC_SRC_F']=[]
-+	v['FC_TGT_F']=['-c','-o']
-+	v['FCINCPATH_ST']='-I%s'
-+	v['FCDEFINES_ST']='-D%s'
-+	if not v['LINK_FC']:v['LINK_FC']=v['FC']
-+	v['FCLNK_SRC_F']=[]
-+	v['FCLNK_TGT_F']=['-o']
-+	v['FCFLAGS_fcshlib']=['-fpic']
-+	v['LINKFLAGS_fcshlib']=['-shared']
-+	v['fcshlib_PATTERN']='lib%s.so'
-+	v['fcstlib_PATTERN']='lib%s.a'
-+	v['FCLIB_ST']='-l%s'
-+	v['FCLIBPATH_ST']='-L%s'
-+	v['FCSTLIB_ST']='-l%s'
-+	v['FCSTLIBPATH_ST']='-L%s'
-+	v['FCSTLIB_MARKER']='-Wl,-Bstatic'
-+	v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
-+	v['SONAME_ST']='-Wl,-h,%s'
++	v.FC_SRC_F=[]
++	v.FC_TGT_F=['-c','-o']
++	v.FCINCPATH_ST='-I%s'
++	v.FCDEFINES_ST='-D%s'
++	if not v.LINK_FC:
++		v.LINK_FC=v.FC
++	v.FCLNK_SRC_F=[]
++	v.FCLNK_TGT_F=['-o']
++	v.FCFLAGS_fcshlib=['-fpic']
++	v.LINKFLAGS_fcshlib=['-shared']
++	v.fcshlib_PATTERN='lib%s.so'
++	v.fcstlib_PATTERN='lib%s.a'
++	v.FCLIB_ST='-l%s'
++	v.FCLIBPATH_ST='-L%s'
++	v.FCSTLIB_ST='-l%s'
++	v.FCSTLIBPATH_ST='-L%s'
++	v.FCSTLIB_MARKER='-Wl,-Bstatic'
++	v.FCSHLIB_MARKER='-Wl,-Bdynamic'
++	v.SONAME_ST='-Wl,-h,%s'
 + at conf
 +def fc_add_flags(conf):
++	conf.add_os_flags('FCPPFLAGS',dup=False)
 +	conf.add_os_flags('FCFLAGS',dup=False)
 +	conf.add_os_flags('LINKFLAGS',dup=False)
 +	conf.add_os_flags('LDFLAGS',dup=False)
@@ -7703,32 +7973,31 @@ Last-Update: 2014-11-28
 + at conf
 +def fortran_modifier_darwin(conf):
 +	v=conf.env
-+	v['FCFLAGS_fcshlib']=['-fPIC']
-+	v['LINKFLAGS_fcshlib']=['-dynamiclib']
-+	v['fcshlib_PATTERN']='lib%s.dylib'
-+	v['FRAMEWORKPATH_ST']='-F%s'
-+	v['FRAMEWORK_ST']='-framework %s'
-+	v['LINKFLAGS_fcstlib']=[]
-+	v['FCSHLIB_MARKER']=''
-+	v['FCSTLIB_MARKER']=''
-+	v['SONAME_ST']=''
++	v.FCFLAGS_fcshlib=['-fPIC']
++	v.LINKFLAGS_fcshlib=['-dynamiclib']
++	v.fcshlib_PATTERN='lib%s.dylib'
++	v.FRAMEWORKPATH_ST='-F%s'
++	v.FRAMEWORK_ST='-framework %s'
++	v.LINKFLAGS_fcstlib=[]
++	v.FCSHLIB_MARKER=''
++	v.FCSTLIB_MARKER=''
++	v.SONAME_ST=''
 + at conf
 +def fortran_modifier_win32(conf):
 +	v=conf.env
-+	v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
-+	v['fcshlib_PATTERN']='%s.dll'
-+	v['implib_PATTERN']='lib%s.dll.a'
-+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
-+	v['FCFLAGS_fcshlib']=[]
-+	v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
++	v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
++	v.fcshlib_PATTERN='%s.dll'
++	v.implib_PATTERN='lib%s.dll.a'
++	v.IMPLIB_ST='-Wl,--out-implib,%s'
++	v.FCFLAGS_fcshlib=[]
 +	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
 + at conf
 +def fortran_modifier_cygwin(conf):
 +	fortran_modifier_win32(conf)
 +	v=conf.env
-+	v['fcshlib_PATTERN']='cyg%s.dll'
++	v.fcshlib_PATTERN='cyg%s.dll'
 +	v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
-+	v['FCFLAGS_fcshlib']=[]
++	v.FCFLAGS_fcshlib=[]
 + at conf
 +def check_fortran_dummy_main(self,*k,**kw):
 +	if not self.env.CC:
@@ -7847,22 +8116,23 @@ Last-Update: 2014-11-28
 +		return flags
 +	return[]
 +def getoutput(conf,cmd,stdin=False):
-+	if stdin:
-+		stdin=Utils.subprocess.PIPE
++	from waflib import Errors
++	if conf.env.env:
++		env=conf.env.env
 +	else:
-+		stdin=None
-+	env=conf.env.env or None
++		env=dict(os.environ)
++		env['LANG']='C'
++	input=stdin and'\n'or None
 +	try:
-+		p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
-+		if stdin:
-+			p.stdin.write('\n')
-+		out,err=p.communicate()
++		out,err=conf.cmd_and_log(cmd,env=env,output=0,input=input)
++	except Errors.WafError ,e:
++		if not(hasattr(e,'stderr')and hasattr(e,'stdout')):
++			raise e
++		else:
++			out=e.stdout
++			err=e.stderr
 +	except Exception:
 +		conf.fatal('could not determine the compiler version %r'%cmd)
-+	if not isinstance(out,str):
-+		out=out.decode(sys.stdout.encoding or'iso8859-1')
-+	if not isinstance(err,str):
-+		err=err.decode(sys.stdout.encoding or'iso8859-1')
 +	return(out,err)
 +ROUTINES_CODE="""\
 +      subroutine foobar()
@@ -7909,7 +8179,7 @@ Last-Update: 2014-11-28
 +	self.start_msg('Getting fortran mangling scheme')
 +	for(u,du,c)in mangling_schemes():
 +		try:
-+			self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
++			self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',dummy_func_nounder=mangle_name(u,du,c,'foobar'),dummy_func_under=mangle_name(u,du,c,'foo_bar'),main_func_name=self.env.FC_MAIN)
 +		except self.errors.ConfigurationError:
 +			pass
 +		else:
@@ -7923,10 +8193,10 @@ Last-Update: 2014-11-28
 + at feature('pyext')
 + at before_method('propagate_uselib_vars','apply_link')
 +def set_lib_pat(self):
-+	self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
++	self.env.fcshlib_PATTERN=self.env.pyext_PATTERN
 + at conf
 +def detect_openmp(self):
-+	for x in('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'):
++	for x in('-qopenmp','-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'):
 +		try:
 +			self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n  call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
 +		except self.errors.ConfigurationError:
@@ -7937,15 +8207,12 @@ Last-Update: 2014-11-28
 +		self.fatal('Could not find OpenMP')
 --- /dev/null
 +++ b/waflib/Tools/fc_scan.py
-@@ -0,0 +1,68 @@
+@@ -0,0 +1,64 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import re
-+from waflib import Utils,Task,TaskGen,Logs
-+from waflib.TaskGen import feature,before_method,after_method,extension
-+from waflib.Configure import conf
 +INC_REGEX="""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
 +USE_REGEX="""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
 +MOD_REGEX="""(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
@@ -7980,7 +8247,6 @@ Last-Update: 2014-11-28
 +			nd=self.waiting.pop(0)
 +			self.iter(nd)
 +	def iter(self,node):
-+		path=node.abspath()
 +		incs,uses,mods=self.find_deps(node)
 +		for x in incs:
 +			if x in self.seen:
@@ -8008,12 +8274,14 @@ Last-Update: 2014-11-28
 +				self.names.append(filename)
 --- /dev/null
 +++ b/waflib/Tools/flex.py
-@@ -0,0 +1,32 @@
+@@ -0,0 +1,37 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import waflib.TaskGen,os,re
++import os,re
++from waflib import Task,TaskGen
++from waflib.Tools import ccroot
 +def decide_ext(self,node):
 +	if'cxx'in self.features:
 +		return['.lex.cc']
@@ -8026,16 +8294,19 @@ Last-Update: 2014-11-28
 +		if isinstance(xx,str):return[xx]
 +		return xx
 +	tsk.last_cmd=lst=[]
-+	lst.extend(to_list(env['FLEX']))
-+	lst.extend(to_list(env['FLEXFLAGS']))
-+	inputs=[a.path_from(bld.bldnode)for a in tsk.inputs]
++	lst.extend(to_list(env.FLEX))
++	lst.extend(to_list(env.FLEXFLAGS))
++	inputs=[a.path_from(tsk.get_cwd())for a in tsk.inputs]
 +	if env.FLEX_MSYS:
 +		inputs=[x.replace(os.sep,'/')for x in inputs]
 +	lst.extend(inputs)
 +	lst=[x for x in lst if x]
 +	txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
 +	tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n'))
-+waflib.TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
++TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
++Task.classes['flex'].vars=['FLEXFLAGS','FLEX']
++ccroot.USELIB_VARS['c'].add('FLEXFLAGS')
++ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS')
 +def configure(conf):
 +	conf.find_program('flex',var='FLEX')
 +	conf.env.FLEXFLAGS=['-t']
@@ -8060,9 +8331,9 @@ Last-Update: 2014-11-28
 + at conf
 +def g95_flags(conf):
 +	v=conf.env
-+	v['FCFLAGS_fcshlib']=['-fPIC']
-+	v['FORTRANMODFLAG']=['-fmod=','']
-+	v['FCFLAGS_DEBUG']=['-Werror']
++	v.FCFLAGS_fcshlib=['-fPIC']
++	v.FORTRANMODFLAG=['-fmod=','']
++	v.FCFLAGS_DEBUG=['-Werror']
 + at conf
 +def g95_modifier_win32(conf):
 +	fc_config.fortran_modifier_win32(conf)
@@ -8074,7 +8345,7 @@ Last-Update: 2014-11-28
 +	fc_config.fortran_modifier_darwin(conf)
 + at conf
 +def g95_modifier_platform(conf):
-+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
++	dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
 +	g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
 +	if g95_modifier_func:
 +		g95_modifier_func()
@@ -8090,7 +8361,7 @@ Last-Update: 2014-11-28
 +	if not match:
 +		conf.fatal('cannot determine g95 version')
 +	k=match.groupdict()
-+	conf.env['FC_VERSION']=(k['major'],k['minor'])
++	conf.env.FC_VERSION=(k['major'],k['minor'])
 +def configure(conf):
 +	conf.find_g95()
 +	conf.find_ar()
@@ -8115,13 +8386,11 @@ Last-Update: 2014-11-28
 +	conf.load('asm')
 --- /dev/null
 +++ b/waflib/Tools/gcc.py
-@@ -0,0 +1,104 @@
+@@ -0,0 +1,103 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
-+from waflib import Configure,Options,Utils
 +from waflib.Tools import ccroot,ar
 +from waflib.Configure import conf
 + at conf
@@ -8132,81 +8401,82 @@ Last-Update: 2014-11-28
 + at conf
 +def gcc_common_flags(conf):
 +	v=conf.env
-+	v['CC_SRC_F']=[]
-+	v['CC_TGT_F']=['-c','-o']
-+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
-+	v['CCLNK_SRC_F']=[]
-+	v['CCLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['RPATH_ST']='-Wl,-rpath,%s'
-+	v['SONAME_ST']='-Wl,-h,%s'
-+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
-+	v['STLIB_MARKER']='-Wl,-Bstatic'
-+	v['cprogram_PATTERN']='%s'
-+	v['CFLAGS_cshlib']=['-fPIC']
-+	v['LINKFLAGS_cshlib']=['-shared']
-+	v['cshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cstlib']=['-Wl,-Bstatic']
-+	v['cstlib_PATTERN']='lib%s.a'
-+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
-+	v['CFLAGS_MACBUNDLE']=['-fPIC']
-+	v['macbundle_PATTERN']='%s.bundle'
++	v.CC_SRC_F=[]
++	v.CC_TGT_F=['-c','-o']
++	if not v.LINK_CC:
++		v.LINK_CC=v.CC
++	v.CCLNK_SRC_F=[]
++	v.CCLNK_TGT_F=['-o']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.RPATH_ST='-Wl,-rpath,%s'
++	v.SONAME_ST='-Wl,-h,%s'
++	v.SHLIB_MARKER='-Wl,-Bdynamic'
++	v.STLIB_MARKER='-Wl,-Bstatic'
++	v.cprogram_PATTERN='%s'
++	v.CFLAGS_cshlib=['-fPIC']
++	v.LINKFLAGS_cshlib=['-shared']
++	v.cshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cstlib=['-Wl,-Bstatic']
++	v.cstlib_PATTERN='lib%s.a'
++	v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup']
++	v.CFLAGS_MACBUNDLE=['-fPIC']
++	v.macbundle_PATTERN='%s.bundle'
 + at conf
 +def gcc_modifier_win32(conf):
 +	v=conf.env
-+	v['cprogram_PATTERN']='%s.exe'
-+	v['cshlib_PATTERN']='%s.dll'
-+	v['implib_PATTERN']='lib%s.dll.a'
-+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
-+	v['CFLAGS_cshlib']=[]
++	v.cprogram_PATTERN='%s.exe'
++	v.cshlib_PATTERN='%s.dll'
++	v.implib_PATTERN='lib%s.dll.a'
++	v.IMPLIB_ST='-Wl,--out-implib,%s'
++	v.CFLAGS_cshlib=[]
 +	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
 + at conf
 +def gcc_modifier_cygwin(conf):
 +	gcc_modifier_win32(conf)
 +	v=conf.env
-+	v['cshlib_PATTERN']='cyg%s.dll'
++	v.cshlib_PATTERN='cyg%s.dll'
 +	v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
-+	v['CFLAGS_cshlib']=[]
++	v.CFLAGS_cshlib=[]
 + at conf
 +def gcc_modifier_darwin(conf):
 +	v=conf.env
-+	v['CFLAGS_cshlib']=['-fPIC']
-+	v['LINKFLAGS_cshlib']=['-dynamiclib']
-+	v['cshlib_PATTERN']='lib%s.dylib'
-+	v['FRAMEWORKPATH_ST']='-F%s'
-+	v['FRAMEWORK_ST']=['-framework']
-+	v['ARCH_ST']=['-arch']
-+	v['LINKFLAGS_cstlib']=[]
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['SONAME_ST']=[]
++	v.CFLAGS_cshlib=['-fPIC']
++	v.LINKFLAGS_cshlib=['-dynamiclib']
++	v.cshlib_PATTERN='lib%s.dylib'
++	v.FRAMEWORKPATH_ST='-F%s'
++	v.FRAMEWORK_ST=['-framework']
++	v.ARCH_ST=['-arch']
++	v.LINKFLAGS_cstlib=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.SONAME_ST=[]
 + at conf
 +def gcc_modifier_aix(conf):
 +	v=conf.env
-+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
-+	v['LINKFLAGS_cshlib']=['-shared','-Wl,-brtl,-bexpfull']
-+	v['SHLIB_MARKER']=[]
++	v.LINKFLAGS_cprogram=['-Wl,-brtl']
++	v.LINKFLAGS_cshlib=['-shared','-Wl,-brtl,-bexpfull']
++	v.SHLIB_MARKER=[]
 + at conf
 +def gcc_modifier_hpux(conf):
 +	v=conf.env
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['CFLAGS_cshlib']=['-fPIC','-DPIC']
-+	v['cshlib_PATTERN']='lib%s.sl'
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.CFLAGS_cshlib=['-fPIC','-DPIC']
++	v.cshlib_PATTERN='lib%s.sl'
 + at conf
 +def gcc_modifier_openbsd(conf):
 +	conf.env.SONAME_ST=[]
 + at conf
 +def gcc_modifier_osf1V(conf):
 +	v=conf.env
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['SONAME_ST']=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.SONAME_ST=[]
 + at conf
 +def gcc_modifier_platform(conf):
 +	gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
@@ -8222,12 +8492,11 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/gdc.py
-@@ -0,0 +1,36 @@
+@@ -0,0 +1,35 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import sys
 +from waflib.Tools import ar,d
 +from waflib.Configure import conf
 + at conf
@@ -8239,20 +8508,20 @@ Last-Update: 2014-11-28
 + at conf
 +def common_flags_gdc(conf):
 +	v=conf.env
-+	v['DFLAGS']=[]
-+	v['D_SRC_F']=['-c']
-+	v['D_TGT_F']='-o%s'
-+	v['D_LINKER']=v['D']
-+	v['DLNK_SRC_F']=''
-+	v['DLNK_TGT_F']='-o%s'
-+	v['DINC_ST']='-I%s'
-+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
-+	v['DSTLIB_ST']=v['DSHLIB_ST']='-l%s'
-+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L%s'
-+	v['LINKFLAGS_dshlib']=['-shared']
-+	v['DHEADER_ext']='.di'
++	v.DFLAGS=[]
++	v.D_SRC_F=['-c']
++	v.D_TGT_F='-o%s'
++	v.D_LINKER=v.D
++	v.DLNK_SRC_F=''
++	v.DLNK_TGT_F='-o%s'
++	v.DINC_ST='-I%s'
++	v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
++	v.DSTLIB_ST=v.DSHLIB_ST='-l%s'
++	v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L%s'
++	v.LINKFLAGS_dshlib=['-shared']
++	v.DHEADER_ext='.di'
 +	v.DFLAGS_d_with_header='-fintfc'
-+	v['D_HDR_F']='-fintfc-file=%s'
++	v.D_HDR_F='-fintfc-file=%s'
 +def configure(conf):
 +	conf.find_gdc()
 +	conf.load('ar')
@@ -8278,9 +8547,9 @@ Last-Update: 2014-11-28
 + at conf
 +def gfortran_flags(conf):
 +	v=conf.env
-+	v['FCFLAGS_fcshlib']=['-fPIC']
-+	v['FORTRANMODFLAG']=['-J','']
-+	v['FCFLAGS_DEBUG']=['-Werror']
++	v.FCFLAGS_fcshlib=['-fPIC']
++	v.FORTRANMODFLAG=['-J','']
++	v.FCFLAGS_DEBUG=['-Werror']
 + at conf
 +def gfortran_modifier_win32(conf):
 +	fc_config.fortran_modifier_win32(conf)
@@ -8292,7 +8561,7 @@ Last-Update: 2014-11-28
 +	fc_config.fortran_modifier_darwin(conf)
 + at conf
 +def gfortran_modifier_platform(conf):
-+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
++	dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
 +	gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
 +	if gfortran_modifier_func:
 +		gfortran_modifier_func()
@@ -8322,7 +8591,7 @@ Last-Update: 2014-11-28
 +		return var in k
 +	def isT(var):
 +		return var in k and k[var]!='0'
-+	conf.env['FC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
++	conf.env.FC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
 +def configure(conf):
 +	conf.find_gfortran()
 +	conf.find_ar()
@@ -8332,14 +8601,15 @@ Last-Update: 2014-11-28
 +	conf.gfortran_modifier_platform()
 --- /dev/null
 +++ b/waflib/Tools/glib2.py
-@@ -0,0 +1,234 @@
+@@ -0,0 +1,241 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os
++import functools
 +from waflib import Context,Task,Utils,Options,Errors,Logs
-+from waflib.TaskGen import taskgen_method,before_method,after_method,feature,extension
++from waflib.TaskGen import taskgen_method,before_method,feature,extension
 +from waflib.Configure import conf
 + at taskgen_method
 +def add_marshal_file(self,filename,prefix):
@@ -8360,8 +8630,11 @@ Last-Update: 2014-11-28
 +	self.source=self.to_nodes(getattr(self,'source',[]))
 +	self.source.append(c_node)
 +class glib_genmarshal(Task.Task):
++	vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
++	color='BLUE'
++	ext_out=['.h']
 +	def run(self):
-+		bld=self.inputs[0].__class__.ctx
++		bld=self.generator.bld
 +		get=self.env.get_flat
 +		cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
 +		ret=bld.exec_command(cmd1)
@@ -8370,9 +8643,6 @@ Last-Update: 2014-11-28
 +		self.outputs[1].write(c)
 +		cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
 +		return bld.exec_command(cmd2)
-+	vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
-+	color='BLUE'
-+	ext_out=['.h']
 + at taskgen_method
 +def add_enums_from_template(self,source='',target='',template='',comments=''):
 +	if not hasattr(self,'enums_list'):
@@ -8396,13 +8666,13 @@ Last-Update: 2014-11-28
 +			raise Errors.WafError('missing source '+str(enum))
 +		source_list=[self.path.find_resource(k)for k in source_list]
 +		inputs+=source_list
-+		env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
++		env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list]
 +		if not enum['target']:
 +			raise Errors.WafError('missing target '+str(enum))
 +		tgt_node=self.path.find_or_declare(enum['target'])
 +		if tgt_node.name.endswith('.c'):
 +			self.source.append(tgt_node)
-+		env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
++		env.GLIB_MKENUMS_TARGET=tgt_node.abspath()
 +		options=[]
 +		if enum['template']:
 +			template_node=self.path.find_resource(enum['template'])
@@ -8412,7 +8682,7 @@ Last-Update: 2014-11-28
 +		for param,option in params.items():
 +			if enum[param]:
 +				options.append('%s %r'%(option,enum[param]))
-+		env['GLIB_MKENUMS_OPTIONS']=' '.join(options)
++		env.GLIB_MKENUMS_OPTIONS=' '.join(options)
 +		task.set_inputs(inputs)
 +		task.set_outputs(tgt_node)
 +class glib_mkenums(Task.Task):
@@ -8429,7 +8699,7 @@ Last-Update: 2014-11-28
 + at taskgen_method
 +def add_settings_enums(self,namespace,filename_list):
 +	if hasattr(self,'settings_enum_namespace'):
-+		raise Errors.WafError("Tried to add gsettings enums to '%s' more than once"%self.name)
++		raise Errors.WafError("Tried to add gsettings enums to %r more than once"%self.name)
 +	self.settings_enum_namespace=namespace
 +	if type(filename_list)!='list':
 +		filename_list=[filename_list]
@@ -8439,53 +8709,63 @@ Last-Update: 2014-11-28
 +	enums_tgt_node=[]
 +	install_files=[]
 +	settings_schema_files=getattr(self,'settings_schema_files',[])
-+	if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
++	if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS:
 +		raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
 +	if hasattr(self,'settings_enum_files'):
 +		enums_task=self.create_task('glib_mkenums')
 +		source_list=self.settings_enum_files
 +		source_list=[self.path.find_resource(k)for k in source_list]
 +		enums_task.set_inputs(source_list)
-+		enums_task.env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
++		enums_task.env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list]
 +		target=self.settings_enum_namespace+'.enums.xml'
 +		tgt_node=self.path.find_or_declare(target)
 +		enums_task.set_outputs(tgt_node)
-+		enums_task.env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
++		enums_task.env.GLIB_MKENUMS_TARGET=tgt_node.abspath()
 +		enums_tgt_node=[tgt_node]
 +		install_files.append(tgt_node)
 +		options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead "  <@type@ id=\\"%s. at EnumName@\\">" --vprod "    <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail "  </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
-+		enums_task.env['GLIB_MKENUMS_OPTIONS']=options
++		enums_task.env.GLIB_MKENUMS_OPTIONS=options
 +	for schema in settings_schema_files:
 +		schema_task=self.create_task('glib_validate_schema')
 +		schema_node=self.path.find_resource(schema)
 +		if not schema_node:
-+			raise Errors.WafError("Cannot find the schema file '%s'"%schema)
++			raise Errors.WafError("Cannot find the schema file %r"%schema)
 +		install_files.append(schema_node)
 +		source_list=enums_tgt_node+[schema_node]
 +		schema_task.set_inputs(source_list)
-+		schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS']=[("--schema-file="+k.abspath())for k in source_list]
++		schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS=[("--schema-file="+k.abspath())for k in source_list]
 +		target_node=schema_node.change_ext('.xml.valid')
 +		schema_task.set_outputs(target_node)
-+		schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
++		schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT=target_node.abspath()
 +	def compile_schemas_callback(bld):
-+		if not bld.is_install:return
-+		Logs.pprint('YELLOW','Updating GSettings schema cache')
-+		command=Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}",bld.env)
-+		ret=self.bld.exec_command(command)
++		if not bld.is_install:
++			return
++		compile_schemas=Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS)
++		destdir=Options.options.destdir
++		paths=bld._compile_schemas_registered
++		if destdir:
++			paths=(os.path.join(destdir,path.lstrip(os.sep))for path in paths)
++		for path in paths:
++			Logs.pprint('YELLOW','Updating GSettings schema cache %r'%path)
++			if self.bld.exec_command(compile_schemas+[path]):
++				Logs.warn('Could not update GSettings schema cache %r'%path)
 +	if self.bld.is_install:
-+		if not self.env['GSETTINGSSCHEMADIR']:
++		schemadir=self.env.GSETTINGSSCHEMADIR
++		if not schemadir:
 +			raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
 +		if install_files:
-+			self.bld.install_files(self.env['GSETTINGSSCHEMADIR'],install_files)
-+			if not hasattr(self.bld,'_compile_schemas_registered'):
++			self.add_install_files(install_to=schemadir,install_from=install_files)
++			registered_schemas=getattr(self.bld,'_compile_schemas_registered',None)
++			if not registered_schemas:
++				registered_schemas=self.bld._compile_schemas_registered=set()
 +				self.bld.add_post_fun(compile_schemas_callback)
-+				self.bld._compile_schemas_registered=True
++			registered_schemas.add(schemadir)
 +class glib_validate_schema(Task.Task):
 +	run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
 +	color='PINK'
 + at extension('.gresource.xml')
 +def process_gresource_source(self,node):
-+	if not self.env['GLIB_COMPILE_RESOURCES']:
++	if not self.env.GLIB_COMPILE_RESOURCES:
 +		raise Errors.WafError("Unable to process GResource file - glib-compile-resources was not found during configure")
 +	if'gresource'in self.features:
 +		return
@@ -8500,18 +8780,14 @@ Last-Update: 2014-11-28
 +		task=self.create_task('glib_gresource_bundle',node,node.change_ext(''))
 +		inst_to=getattr(self,'install_path',None)
 +		if inst_to:
-+			self.bld.install_files(inst_to,task.outputs)
++			self.add_install_files(install_to=inst_to,install_from=task.outputs)
 +class glib_gresource_base(Task.Task):
 +	color='BLUE'
 +	base_cmd='${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}'
 +	def scan(self):
 +		bld=self.generator.bld
 +		kw={}
-+		try:
-+			if not kw.get('cwd',None):
-+				kw['cwd']=bld.cwd
-+		except AttributeError:
-+			bld.cwd=kw['cwd']=bld.variant_dir
++		kw['cwd']=self.get_cwd()
 +		kw['quiet']=Context.BOTH
 +		cmd=Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s'%(self.inputs[0].parent.srcpath(),self.inputs[0].bld_dir(),self.inputs[0].bldpath()),self.env)
 +		output=bld.cmd_and_log(cmd,**kw)
@@ -8552,10 +8828,10 @@ Last-Update: 2014-11-28
 +	if not gsettingsschemadir:
 +		datadir=getstr('DATADIR')
 +		if not datadir:
-+			prefix=conf.env['PREFIX']
++			prefix=conf.env.PREFIX
 +			datadir=os.path.join(prefix,'share')
 +		gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
-+	conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
++	conf.env.GSETTINGSSCHEMADIR=gsettingsschemadir
 + at conf
 +def find_glib_compile_resources(conf):
 +	conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES')
@@ -8638,13 +8914,11 @@ Last-Update: 2014-11-28
 +		dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
 --- /dev/null
 +++ b/waflib/Tools/gxx.py
-@@ -0,0 +1,104 @@
+@@ -0,0 +1,103 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
-+from waflib import Configure,Options,Utils
 +from waflib.Tools import ccroot,ar
 +from waflib.Configure import conf
 + at conf
@@ -8655,81 +8929,82 @@ Last-Update: 2014-11-28
 + at conf
 +def gxx_common_flags(conf):
 +	v=conf.env
-+	v['CXX_SRC_F']=[]
-+	v['CXX_TGT_F']=['-c','-o']
-+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
-+	v['CXXLNK_SRC_F']=[]
-+	v['CXXLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['RPATH_ST']='-Wl,-rpath,%s'
-+	v['SONAME_ST']='-Wl,-h,%s'
-+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
-+	v['STLIB_MARKER']='-Wl,-Bstatic'
-+	v['cxxprogram_PATTERN']='%s'
-+	v['CXXFLAGS_cxxshlib']=['-fPIC']
-+	v['LINKFLAGS_cxxshlib']=['-shared']
-+	v['cxxshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cxxstlib']=['-Wl,-Bstatic']
-+	v['cxxstlib_PATTERN']='lib%s.a'
-+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
-+	v['CXXFLAGS_MACBUNDLE']=['-fPIC']
-+	v['macbundle_PATTERN']='%s.bundle'
++	v.CXX_SRC_F=[]
++	v.CXX_TGT_F=['-c','-o']
++	if not v.LINK_CXX:
++		v.LINK_CXX=v.CXX
++	v.CXXLNK_SRC_F=[]
++	v.CXXLNK_TGT_F=['-o']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.RPATH_ST='-Wl,-rpath,%s'
++	v.SONAME_ST='-Wl,-h,%s'
++	v.SHLIB_MARKER='-Wl,-Bdynamic'
++	v.STLIB_MARKER='-Wl,-Bstatic'
++	v.cxxprogram_PATTERN='%s'
++	v.CXXFLAGS_cxxshlib=['-fPIC']
++	v.LINKFLAGS_cxxshlib=['-shared']
++	v.cxxshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cxxstlib=['-Wl,-Bstatic']
++	v.cxxstlib_PATTERN='lib%s.a'
++	v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup']
++	v.CXXFLAGS_MACBUNDLE=['-fPIC']
++	v.macbundle_PATTERN='%s.bundle'
 + at conf
 +def gxx_modifier_win32(conf):
 +	v=conf.env
-+	v['cxxprogram_PATTERN']='%s.exe'
-+	v['cxxshlib_PATTERN']='%s.dll'
-+	v['implib_PATTERN']='lib%s.dll.a'
-+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
-+	v['CXXFLAGS_cxxshlib']=[]
++	v.cxxprogram_PATTERN='%s.exe'
++	v.cxxshlib_PATTERN='%s.dll'
++	v.implib_PATTERN='lib%s.dll.a'
++	v.IMPLIB_ST='-Wl,--out-implib,%s'
++	v.CXXFLAGS_cxxshlib=[]
 +	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
 + at conf
 +def gxx_modifier_cygwin(conf):
 +	gxx_modifier_win32(conf)
 +	v=conf.env
-+	v['cxxshlib_PATTERN']='cyg%s.dll'
++	v.cxxshlib_PATTERN='cyg%s.dll'
 +	v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
-+	v['CXXFLAGS_cxxshlib']=[]
++	v.CXXFLAGS_cxxshlib=[]
 + at conf
 +def gxx_modifier_darwin(conf):
 +	v=conf.env
-+	v['CXXFLAGS_cxxshlib']=['-fPIC']
-+	v['LINKFLAGS_cxxshlib']=['-dynamiclib']
-+	v['cxxshlib_PATTERN']='lib%s.dylib'
-+	v['FRAMEWORKPATH_ST']='-F%s'
-+	v['FRAMEWORK_ST']=['-framework']
-+	v['ARCH_ST']=['-arch']
-+	v['LINKFLAGS_cxxstlib']=[]
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['SONAME_ST']=[]
++	v.CXXFLAGS_cxxshlib=['-fPIC']
++	v.LINKFLAGS_cxxshlib=['-dynamiclib']
++	v.cxxshlib_PATTERN='lib%s.dylib'
++	v.FRAMEWORKPATH_ST='-F%s'
++	v.FRAMEWORK_ST=['-framework']
++	v.ARCH_ST=['-arch']
++	v.LINKFLAGS_cxxstlib=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.SONAME_ST=[]
 + at conf
 +def gxx_modifier_aix(conf):
 +	v=conf.env
-+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
-+	v['LINKFLAGS_cxxshlib']=['-shared','-Wl,-brtl,-bexpfull']
-+	v['SHLIB_MARKER']=[]
++	v.LINKFLAGS_cxxprogram=['-Wl,-brtl']
++	v.LINKFLAGS_cxxshlib=['-shared','-Wl,-brtl,-bexpfull']
++	v.SHLIB_MARKER=[]
 + at conf
 +def gxx_modifier_hpux(conf):
 +	v=conf.env
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['CFLAGS_cxxshlib']=['-fPIC','-DPIC']
-+	v['cxxshlib_PATTERN']='lib%s.sl'
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.CFLAGS_cxxshlib=['-fPIC','-DPIC']
++	v.cxxshlib_PATTERN='lib%s.sl'
 + at conf
 +def gxx_modifier_openbsd(conf):
 +	conf.env.SONAME_ST=[]
 + at conf
 +def gcc_modifier_osf1V(conf):
 +	v=conf.env
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['SONAME_ST']=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.SONAME_ST=[]
 + at conf
 +def gxx_modifier_platform(conf):
 +	gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
@@ -8745,18 +9020,16 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/icc.py
-@@ -0,0 +1,22 @@
+@@ -0,0 +1,20 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
++import sys
 +from waflib.Tools import ccroot,ar,gcc
 +from waflib.Configure import conf
 + at conf
 +def find_icc(conf):
-+	if sys.platform=='cygwin':
-+		conf.fatal('The Intel compiler does not work on Cygwin')
 +	cc=conf.find_program(['icc','ICL'],var='CC')
 +	conf.get_cc_version(cc,icc=True)
 +	conf.env.CC_NAME='icc'
@@ -8770,18 +9043,16 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/icpc.py
-@@ -0,0 +1,22 @@
+@@ -0,0 +1,20 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys
++import sys
 +from waflib.Tools import ccroot,ar,gxx
 +from waflib.Configure import conf
 + at conf
 +def find_icpc(conf):
-+	if sys.platform=='cygwin':
-+		conf.fatal('The Intel compiler does not work on Cygwin')
 +	cxx=conf.find_program('icpc',var='CXX')
 +	conf.get_cc_version(cxx,icc=True)
 +	conf.env.CXX_NAME='icc'
@@ -8795,38 +9066,55 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/ifort.py
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,301 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import re
-+from waflib import Utils
-+from waflib.Tools import fc,fc_config,fc_scan,ar
++import os,re
++from waflib import Utils,Logs,Errors
++from waflib.Tools import fc,fc_config,fc_scan,ar,ccroot
 +from waflib.Configure import conf
++from waflib.TaskGen import after_method,feature
 + at conf
 +def find_ifort(conf):
 +	fc=conf.find_program('ifort',var='FC')
 +	conf.get_ifort_version(fc)
 +	conf.env.FC_NAME='IFORT'
 + at conf
-+def ifort_modifier_cygwin(conf):
-+	raise NotImplementedError("Ifort on cygwin not yet implemented")
-+ at conf
-+def ifort_modifier_win32(conf):
-+	fc_config.fortran_modifier_win32(conf)
++def ifort_modifier_win32(self):
++	v=self.env
++	v.IFORT_WIN32=True
++	v.FCSTLIB_MARKER=''
++	v.FCSHLIB_MARKER=''
++	v.FCLIB_ST=v.FCSTLIB_ST='%s.lib'
++	v.FCLIBPATH_ST=v.STLIBPATH_ST='/LIBPATH:%s'
++	v.FCINCPATH_ST='/I%s'
++	v.FCDEFINES_ST='/D%s'
++	v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
++	v.fcshlib_PATTERN='%s.dll'
++	v.fcstlib_PATTERN=v.implib_PATTERN='%s.lib'
++	v.FCLNK_TGT_F='/out:'
++	v.FC_TGT_F=['/c','/o','']
++	v.FCFLAGS_fcshlib=''
++	v.LINKFLAGS_fcshlib='/DLL'
++	v.AR_TGT_F='/out:'
++	v.IMPLIB_ST='/IMPLIB:%s'
++	v.append_value('LINKFLAGS','/subsystem:console')
++	if v.IFORT_MANIFEST:
++		v.append_value('LINKFLAGS',['/MANIFEST'])
 + at conf
 +def ifort_modifier_darwin(conf):
 +	fc_config.fortran_modifier_darwin(conf)
 + at conf
 +def ifort_modifier_platform(conf):
-+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
++	dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
 +	ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
 +	if ifort_modifier_func:
 +		ifort_modifier_func()
 + at conf
 +def get_ifort_version(conf,fc):
-+	version_re=re.compile(r"Intel[\sa-zA-Z()0-9,-]*Version\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
++	version_re=re.compile(r"\bIntel\b.*\bVersion\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
 +	if Utils.is_win32:
 +		cmd=fc
 +	else:
@@ -8836,14 +9124,250 @@ Last-Update: 2014-11-28
 +	if not match:
 +		conf.fatal('cannot determine ifort version.')
 +	k=match.groupdict()
-+	conf.env['FC_VERSION']=(k['major'],k['minor'])
++	conf.env.FC_VERSION=(k['major'],k['minor'])
 +def configure(conf):
-+	conf.find_ifort()
-+	conf.find_program('xiar',var='AR')
-+	conf.env.ARFLAGS='rcs'
-+	conf.fc_flags()
-+	conf.fc_add_flags()
-+	conf.ifort_modifier_platform()
++	if Utils.is_win32:
++		compiler,version,path,includes,libdirs,arch=conf.detect_ifort(True)
++		v=conf.env
++		v.DEST_CPU=arch
++		v.PATH=path
++		v.INCLUDES=includes
++		v.LIBPATH=libdirs
++		v.MSVC_COMPILER=compiler
++		try:
++			v.MSVC_VERSION=float(version)
++		except Exception:
++			raise
++			v.MSVC_VERSION=float(version[:-3])
++		conf.find_ifort_win32()
++		conf.ifort_modifier_win32()
++	else:
++		conf.find_ifort()
++		conf.find_program('xiar',var='AR')
++		conf.find_ar()
++		conf.fc_flags()
++		conf.fc_add_flags()
++		conf.ifort_modifier_platform()
++all_ifort_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
++ at conf
++def gather_ifort_versions(conf,versions):
++	version_pattern=re.compile('^...?.?\....?.?')
++	try:
++		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran')
++	except WindowsError:
++		try:
++			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran')
++		except WindowsError:
++			return
++	index=0
++	while 1:
++		try:
++			version=Utils.winreg.EnumKey(all_versions,index)
++		except WindowsError:
++			break
++		index+=1
++		if not version_pattern.match(version):
++			continue
++		targets={}
++		for target,arch in all_ifort_platforms:
++			if target=='intel64':targetDir='EM64T_NATIVE'
++			else:targetDir=target
++			try:
++				Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
++				icl_version=Utils.winreg.OpenKey(all_versions,version)
++				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
++			except WindowsError:
++				pass
++			else:
++				batch_file=os.path.join(path,'bin','iclvars.bat')
++				if os.path.isfile(batch_file):
++					targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
++		for target,arch in all_ifort_platforms:
++			try:
++				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
++				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
++			except WindowsError:
++				continue
++			else:
++				batch_file=os.path.join(path,'bin','iclvars.bat')
++				if os.path.isfile(batch_file):
++					targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
++		major=version[0:2]
++		versions['intel '+major]=targets
++ at conf
++def setup_ifort(conf,versiondict):
++	platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_ifort_platforms]
++	desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys())))
++	for version in desired_versions:
++		try:
++			targets=versiondict[version]
++		except KeyError:
++			continue
++		for arch in platforms:
++			try:
++				cfg=targets[arch]
++			except KeyError:
++				continue
++			cfg.evaluate()
++			if cfg.is_valid:
++				compiler,revision=version.rsplit(' ',1)
++				return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu
++	conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys())))
++ at conf
++def get_ifort_version_win32(conf,compiler,version,target,vcvars):
++	try:
++		conf.msvc_cnt+=1
++	except AttributeError:
++		conf.msvc_cnt=1
++	batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt)
++	batfile.write("""@echo off
++set INCLUDE=
++set LIB=
++call "%s" %s
++echo PATH=%%PATH%%
++echo INCLUDE=%%INCLUDE%%
++echo LIB=%%LIB%%;%%LIBPATH%%
++"""%(vcvars,target))
++	sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
++	batfile.delete()
++	lines=sout.splitlines()
++	if not lines[0]:
++		lines.pop(0)
++	MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
++	for line in lines:
++		if line.startswith('PATH='):
++			path=line[5:]
++			MSVC_PATH=path.split(';')
++		elif line.startswith('INCLUDE='):
++			MSVC_INCDIR=[i for i in line[8:].split(';')if i]
++		elif line.startswith('LIB='):
++			MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
++	if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
++		conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)')
++	env=dict(os.environ)
++	env.update(PATH=path)
++	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
++	fc=conf.find_program(compiler_name,path_list=MSVC_PATH)
++	if'CL'in env:
++		del(env['CL'])
++	try:
++		conf.cmd_and_log(fc+['/help'],env=env)
++	except UnicodeError:
++		st=Utils.ex_stack()
++		if conf.logger:
++			conf.logger.error(st)
++		conf.fatal('ifort: Unicode error - check the code page?')
++	except Exception ,e:
++		Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s',compiler,version,target,str(e))
++		conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)')
++	else:
++		Logs.debug('ifort: get_ifort_version: %r %r %r -> OK',compiler,version,target)
++	finally:
++		conf.env[compiler_name]=''
++	return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
++class target_compiler(object):
++	def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None):
++		self.conf=ctx
++		self.name=None
++		self.is_valid=False
++		self.is_done=False
++		self.compiler=compiler
++		self.cpu=cpu
++		self.version=version
++		self.bat_target=bat_target
++		self.bat=bat
++		self.callback=callback
++	def evaluate(self):
++		if self.is_done:
++			return
++		self.is_done=True
++		try:
++			vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat)
++		except Errors.ConfigurationError:
++			self.is_valid=False
++			return
++		if self.callback:
++			vs=self.callback(self,vs)
++		self.is_valid=True
++		(self.bindirs,self.incdirs,self.libdirs)=vs
++	def __str__(self):
++		return str((self.bindirs,self.incdirs,self.libdirs))
++	def __repr__(self):
++		return repr((self.bindirs,self.incdirs,self.libdirs))
++ at conf
++def detect_ifort(self):
++	return self.setup_ifort(self.get_ifort_versions(False))
++ at conf
++def get_ifort_versions(self,eval_and_save=True):
++	dct={}
++	self.gather_ifort_versions(dct)
++	return dct
++def _get_prog_names(self,compiler):
++	if compiler=='intel':
++		compiler_name='ifort'
++		linker_name='XILINK'
++		lib_name='XILIB'
++	else:
++		compiler_name='CL'
++		linker_name='LINK'
++		lib_name='LIB'
++	return compiler_name,linker_name,lib_name
++ at conf
++def find_ifort_win32(conf):
++	v=conf.env
++	path=v.PATH
++	compiler=v.MSVC_COMPILER
++	version=v.MSVC_VERSION
++	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
++	v.IFORT_MANIFEST=(compiler=='intel'and version>=11)
++	fc=conf.find_program(compiler_name,var='FC',path_list=path)
++	env=dict(conf.environ)
++	if path:env.update(PATH=';'.join(path))
++	if not conf.cmd_and_log(fc+['/nologo','/help'],env=env):
++		conf.fatal('not intel fortran compiler could not be identified')
++	v.FC_NAME='IFORT'
++	if not v.LINK_FC:
++		conf.find_program(linker_name,var='LINK_FC',path_list=path,mandatory=True)
++	if not v.AR:
++		conf.find_program(lib_name,path_list=path,var='AR',mandatory=True)
++		v.ARFLAGS=['/nologo']
++	if v.IFORT_MANIFEST:
++		conf.find_program('MT',path_list=path,var='MT')
++		v.MTFLAGS=['/nologo']
++	try:
++		conf.load('winres')
++	except Errors.WafError:
++		Logs.warn('Resource compiler not found. Compiling resource file is disabled')
++ at after_method('apply_link')
++ at feature('fc')
++def apply_flags_ifort(self):
++	if not self.env.IFORT_WIN32 or not getattr(self,'link_task',None):
++		return
++	is_static=isinstance(self.link_task,ccroot.stlink_task)
++	subsystem=getattr(self,'subsystem','')
++	if subsystem:
++		subsystem='/subsystem:%s'%subsystem
++		flags=is_static and'ARFLAGS'or'LINKFLAGS'
++		self.env.append_value(flags,subsystem)
++	if not is_static:
++		for f in self.env.LINKFLAGS:
++			d=f.lower()
++			if d[1:]=='debug':
++				pdbnode=self.link_task.outputs[0].change_ext('.pdb')
++				self.link_task.outputs.append(pdbnode)
++				if getattr(self,'install_task',None):
++					self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode)
++				break
++ at feature('fcprogram','fcshlib','fcprogram_test')
++ at after_method('apply_link')
++def apply_manifest_ifort(self):
++	if self.env.IFORT_WIN32 and getattr(self,'link_task',None):
++		self.link_task.env.FC=self.env.LINK_FC
++	if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self,'link_task',None):
++		out_node=self.link_task.outputs[0]
++		man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
++		self.link_task.outputs.append(man_node)
++		self.env.DO_MANIFEST=True
 --- /dev/null
 +++ b/waflib/Tools/intltool.py
 @@ -0,0 +1,97 @@
@@ -8852,7 +9376,7 @@ Last-Update: 2014-11-28
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os,re
-+from waflib import Configure,Context,TaskGen,Task,Utils,Runner,Options,Build,Logs
++from waflib import Context,Task,Utils,Logs
 +import waflib.Tools.ccroot
 +from waflib.TaskGen import feature,before_method,taskgen_method
 +from waflib.Logs import error
@@ -8894,7 +9418,7 @@ Last-Update: 2014-11-28
 +		task=self.create_task('intltool',node,node.change_ext(''))
 +		inst=getattr(self,'install_path',None)
 +		if inst:
-+			self.bld.install_files(inst,task.outputs)
++			self.add_install_files(install_to=inst,install_from=task.outputs)
 + at feature('intltool_po')
 +def apply_intltool_po(self):
 +	try:self.meths.remove('process_source')
@@ -8920,7 +9444,7 @@ Last-Update: 2014-11-28
 +					filename=task.outputs[0].name
 +					(langname,ext)=os.path.splitext(filename)
 +					inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
-+					self.bld.install_as(inst_file,task.outputs[0],chmod=getattr(self,'chmod',Utils.O644),env=task.env)
++					self.add_install_as(install_to=inst_file,install_from=task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
 +	else:
 +		Logs.pprint('RED',"Error no LINGUAS file found in po directory")
 +class po(Task.Task):
@@ -8946,46 +9470,49 @@ Last-Update: 2014-11-28
 +		conf.check(header_name='locale.h')
 --- /dev/null
 +++ b/waflib/Tools/irixcc.py
-@@ -0,0 +1,47 @@
+@@ -0,0 +1,50 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os
-+from waflib import Utils
 +from waflib.Tools import ccroot,ar
 +from waflib.Configure import conf
 + at conf
 +def find_irixcc(conf):
 +	v=conf.env
 +	cc=None
-+	if v['CC']:cc=v['CC']
-+	elif'CC'in conf.environ:cc=conf.environ['CC']
-+	if not cc:cc=conf.find_program('cc',var='CC')
-+	if not cc:conf.fatal('irixcc was not found')
++	if v.CC:
++		cc=v.CC
++	elif'CC'in conf.environ:
++		cc=conf.environ['CC']
++	if not cc:
++		cc=conf.find_program('cc',var='CC')
++	if not cc:
++		conf.fatal('irixcc was not found')
 +	try:
 +		conf.cmd_and_log(cc+['-version'])
 +	except Exception:
 +		conf.fatal('%r -version could not be executed'%cc)
-+	v['CC']=cc
-+	v['CC_NAME']='irix'
++	v.CC=cc
++	v.CC_NAME='irix'
 + at conf
 +def irixcc_common_flags(conf):
 +	v=conf.env
-+	v['CC_SRC_F']=''
-+	v['CC_TGT_F']=['-c','-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
-+	v['CCLNK_SRC_F']=''
-+	v['CCLNK_TGT_F']=['-o']
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['cprogram_PATTERN']='%s'
-+	v['cshlib_PATTERN']='lib%s.so'
-+	v['cstlib_PATTERN']='lib%s.a'
++	v.CC_SRC_F=''
++	v.CC_TGT_F=['-c','-o']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	if not v.LINK_CC:
++		v.LINK_CC=v.CC
++	v.CCLNK_SRC_F=''
++	v.CCLNK_TGT_F=['-o']
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.cprogram_PATTERN='%s'
++	v.cshlib_PATTERN='lib%s.so'
++	v.cstlib_PATTERN='lib%s.a'
 +def configure(conf):
 +	conf.find_irixcc()
 +	conf.find_cpp()
@@ -8996,13 +9523,13 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/javaw.py
-@@ -0,0 +1,307 @@
+@@ -0,0 +1,296 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,re,tempfile,shutil
-+from waflib import TaskGen,Task,Utils,Options,Build,Errors,Node,Logs
++import os,shutil
++from waflib import Task,Utils,Errors,Node
 +from waflib.Configure import conf
 +from waflib.TaskGen import feature,before_method,after_method
 +from waflib.Tools import ccroot
@@ -9032,7 +9559,6 @@ Last-Update: 2014-11-28
 + at before_method('process_source')
 +def apply_java(self):
 +	Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
-+	nodes_lst=[]
 +	outdir=getattr(self,'outdir',None)
 +	if outdir:
 +		if not isinstance(outdir,Node.Node):
@@ -9041,7 +9567,7 @@ Last-Update: 2014-11-28
 +		outdir=self.path.get_bld()
 +	outdir.mkdir()
 +	self.outdir=outdir
-+	self.env['OUTDIR']=outdir.abspath()
++	self.env.OUTDIR=outdir.abspath()
 +	self.javac_task=tsk=self.create_task('javac')
 +	tmp=[]
 +	srcdir=getattr(self,'srcdir','')
@@ -9057,7 +9583,7 @@ Last-Update: 2014-11-28
 +		tmp.append(y)
 +	tsk.srcdir=tmp
 +	if getattr(self,'compat',None):
-+		tsk.env.append_value('JAVACFLAGS',['-source',self.compat])
++		tsk.env.append_value('JAVACFLAGS',['-source',str(self.compat)])
 +	if hasattr(self,'sourcepath'):
 +		fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
 +		names=os.pathsep.join([x.srcpath()for x in fold])
@@ -9075,14 +9601,17 @@ Last-Update: 2014-11-28
 +	for x in names:
 +		try:
 +			y=get(x)
-+		except Exception:
++		except Errors.WafError:
 +			self.uselib.append(x)
 +		else:
 +			y.post()
-+			lst.append(y.jar_task.outputs[0].abspath())
-+			self.javac_task.set_run_after(y.jar_task)
-+	if lst:
-+		self.env.append_value('CLASSPATH',lst)
++			if hasattr(y,'jar_task'):
++				lst.append(y.jar_task.outputs[0].abspath())
++				self.javac_task.set_run_after(y.jar_task)
++			else:
++				for tsk in y.tasks:
++					self.javac_task.set_run_after(tsk)
++	self.env.append_value('CLASSPATH',lst)
 + at feature('javac')
 + at after_method('apply_java','propagate_uselib_vars','use_javac_files')
 +def set_classpath(self):
@@ -9107,7 +9636,10 @@ Last-Update: 2014-11-28
 +	self.jar_task=tsk=self.create_task('jar_create')
 +	if manifest:
 +		jarcreate=getattr(self,'jarcreate','cfm')
-+		node=self.path.find_node(manifest)
++		if not isinstance(manifest,Node.Node):
++			node=self.path.find_or_declare(manifest)
++		else:
++			node=manifest
 +		tsk.dep_nodes.append(node)
 +		jaropts.insert(0,node.abspath())
 +	else:
@@ -9121,26 +9653,35 @@ Last-Update: 2014-11-28
 +	jaropts.append('-C')
 +	jaropts.append(basedir.bldpath())
 +	jaropts.append('.')
-+	tsk.env['JAROPTS']=jaropts
-+	tsk.env['JARCREATE']=jarcreate
++	tsk.env.JAROPTS=jaropts
++	tsk.env.JARCREATE=jarcreate
 +	if getattr(self,'javac_task',None):
 +		tsk.set_run_after(self.javac_task)
 + at feature('jar')
 + at after_method('jar_files')
 +def use_jar_files(self):
-+	lst=[]
 +	self.uselib=self.to_list(getattr(self,'uselib',[]))
 +	names=self.to_list(getattr(self,'use',[]))
 +	get=self.bld.get_tgen_by_name
 +	for x in names:
 +		try:
 +			y=get(x)
-+		except Exception:
++		except Errors.WafError:
 +			self.uselib.append(x)
 +		else:
 +			y.post()
 +			self.jar_task.run_after.update(y.tasks)
-+class jar_create(Task.Task):
++class JTask(Task.Task):
++	def split_argfile(self,cmd):
++		inline=[cmd[0]]
++		infile=[]
++		for x in cmd[1:]:
++			if x.startswith('-J'):
++				inline.append(x)
++			else:
++				infile.append(self.quote_flag(x))
++		return(inline,infile)
++class jar_create(JTask):
 +	color='GREEN'
 +	run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
 +	def runnable_status(self):
@@ -9154,9 +9695,15 @@ Last-Update: 2014-11-28
 +			except Exception:
 +				raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
 +		return super(jar_create,self).runnable_status()
-+class javac(Task.Task):
++class javac(JTask):
 +	color='BLUE'
++	run_str='${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}'
 +	vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
++	def uid(self):
++		lst=[self.__class__.__name__,self.generator.outdir.abspath()]
++		for x in self.srcdir:
++			lst.append(x.abspath())
++		return Utils.h_list(lst)
 +	def runnable_status(self):
 +		for t in self.run_after:
 +			if not t.hasrun:
@@ -9167,44 +9714,9 @@ Last-Update: 2014-11-28
 +			for x in self.srcdir:
 +				self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
 +		return super(javac,self).runnable_status()
-+	def run(self):
-+		env=self.env
-+		gen=self.generator
-+		bld=gen.bld
-+		wd=bld.bldnode.abspath()
-+		def to_list(xx):
-+			if isinstance(xx,str):return[xx]
-+			return xx
-+		cmd=[]
-+		cmd.extend(to_list(env['JAVAC']))
-+		cmd.extend(['-classpath'])
-+		cmd.extend(to_list(env['CLASSPATH']))
-+		cmd.extend(['-d'])
-+		cmd.extend(to_list(env['OUTDIR']))
-+		cmd.extend(to_list(env['JAVACFLAGS']))
-+		files=[a.path_from(bld.bldnode)for a in self.inputs]
-+		tmp=None
-+		try:
-+			if len(str(files))+len(str(cmd))>8192:
-+				(fd,tmp)=tempfile.mkstemp(dir=bld.bldnode.abspath())
-+				try:
-+					os.write(fd,'\n'.join(files))
-+				finally:
-+					if tmp:
-+						os.close(fd)
-+				if Logs.verbose:
-+					Logs.debug('runner: %r'%(cmd+files))
-+				cmd.append('@'+tmp)
-+			else:
-+				cmd+=files
-+			ret=self.exec_command(cmd,cwd=wd,env=env.env or None)
-+		finally:
-+			if tmp:
-+				os.remove(tmp)
-+		return ret
 +	def post_run(self):
-+		for n in self.generator.outdir.ant_glob('**/*.class'):
-+			n.sig=Utils.h_file(n.abspath())
++		for node in self.generator.outdir.ant_glob('**/*.class'):
++			self.generator.bld.node_sigs[node]=self.uid()
 +		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
 + at feature('javadoc')
 + at after_method('process_rule')
@@ -9221,7 +9733,7 @@ Last-Update: 2014-11-28
 +	def run(self):
 +		env=self.env
 +		bld=self.generator.bld
-+		wd=bld.bldnode.abspath()
++		wd=bld.bldnode
 +		srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir
 +		srcpath+=os.pathsep
 +		srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir
@@ -9230,7 +9742,7 @@ Last-Update: 2014-11-28
 +		classpath+=os.pathsep.join(self.classpath)
 +		classpath="".join(classpath)
 +		self.last_cmd=lst=[]
-+		lst.extend(Utils.to_list(env['JAVADOC']))
++		lst.extend(Utils.to_list(env.JAVADOC))
 +		lst.extend(['-d',self.generator.javadoc_output.abspath()])
 +		lst.extend(['-sourcepath',srcpath])
 +		lst.extend(['-classpath',classpath])
@@ -9240,36 +9752,38 @@ Last-Update: 2014-11-28
 +		self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
 +	def post_run(self):
 +		nodes=self.generator.javadoc_output.ant_glob('**')
-+		for x in nodes:
-+			x.sig=Utils.h_file(x.abspath())
++		for node in nodes:
++			self.generator.bld.node_sigs[node]=self.uid()
 +		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
 +def configure(self):
 +	java_path=self.environ['PATH'].split(os.pathsep)
 +	v=self.env
 +	if'JAVA_HOME'in self.environ:
 +		java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
-+		self.env['JAVA_HOME']=[self.environ['JAVA_HOME']]
++		self.env.JAVA_HOME=[self.environ['JAVA_HOME']]
 +	for x in'javac java jar javadoc'.split():
 +		self.find_program(x,var=x.upper(),path_list=java_path)
 +	if'CLASSPATH'in self.environ:
-+		v['CLASSPATH']=self.environ['CLASSPATH']
-+	if not v['JAR']:self.fatal('jar is required for making java packages')
-+	if not v['JAVAC']:self.fatal('javac is required for compiling java classes')
-+	v['JARCREATE']='cf'
-+	v['JAVACFLAGS']=[]
++		v.CLASSPATH=self.environ['CLASSPATH']
++	if not v.JAR:
++		self.fatal('jar is required for making java packages')
++	if not v.JAVAC:
++		self.fatal('javac is required for compiling java classes')
++	v.JARCREATE='cf'
++	v.JAVACFLAGS=[]
 + at conf
 +def check_java_class(self,classname,with_classpath=None):
 +	javatestdir='.waf-javatest'
 +	classpath=javatestdir
-+	if self.env['CLASSPATH']:
-+		classpath+=os.pathsep+self.env['CLASSPATH']
++	if self.env.CLASSPATH:
++		classpath+=os.pathsep+self.env.CLASSPATH
 +	if isinstance(with_classpath,str):
 +		classpath+=os.pathsep+with_classpath
 +	shutil.rmtree(javatestdir,True)
 +	os.mkdir(javatestdir)
 +	Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source)
-+	self.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False)
-+	cmd=self.env['JAVA']+['-cp',classpath,'Test',classname]
++	self.exec_command(self.env.JAVAC+[os.path.join(javatestdir,'Test.java')],shell=False)
++	cmd=self.env.JAVA+['-cp',classpath,'Test',classname]
 +	self.to_log("%s\n"%str(cmd))
 +	found=self.exec_command(cmd,shell=False)
 +	self.msg('Checking for java class %s'%classname,not found)
@@ -9281,7 +9795,7 @@ Last-Update: 2014-11-28
 +		conf.fatal('load a compiler first (gcc, g++, ..)')
 +	if not conf.env.JAVA_HOME:
 +		conf.fatal('set JAVA_HOME in the system environment')
-+	javaHome=conf.env['JAVA_HOME'][0]
++	javaHome=conf.env.JAVA_HOME[0]
 +	dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
 +	if dir is None:
 +		dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers')
@@ -9295,6 +9809,8 @@ Last-Update: 2014-11-28
 +	f=dir.ant_glob('**/*jvm.(lib)')
 +	if f:
 +		libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
++	if conf.env.DEST_OS=='freebsd':
++		conf.env.append_unique('LINKFLAGS_JAVA','-pthread')
 +	for d in libDirs:
 +		try:
 +			conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
@@ -9305,64 +9821,12 @@ Last-Update: 2014-11-28
 +	else:
 +		conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
 --- /dev/null
-+++ b/waflib/Tools/kde4.py
-@@ -0,0 +1,48 @@
-+#! /usr/bin/env python
-+# encoding: utf-8
-+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
-+
-+import os,sys,re
-+from waflib import Options,TaskGen,Task,Utils
-+from waflib.TaskGen import feature,after_method
-+ at feature('msgfmt')
-+def apply_msgfmt(self):
-+	for lang in self.to_list(self.langs):
-+		node=self.path.find_resource(lang+'.po')
-+		task=self.create_task('msgfmt',node,node.change_ext('.mo'))
-+		langname=lang.split('/')
-+		langname=langname[-1]
-+		inst=getattr(self,'install_path','${KDE4_LOCALE_INSTALL_DIR}')
-+		self.bld.install_as(inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+getattr(self,'appname','set_your_appname')+'.mo',task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
-+class msgfmt(Task.Task):
-+	color='BLUE'
-+	run_str='${MSGFMT} ${SRC} -o ${TGT}'
-+def configure(self):
-+	kdeconfig=self.find_program('kde4-config')
-+	prefix=self.cmd_and_log(kdeconfig+['--prefix']).strip()
-+	fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
-+	try:os.stat(fname)
-+	except OSError:
-+		fname='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
-+		try:os.stat(fname)
-+		except OSError:self.fatal('could not open %s'%fname)
-+	try:
-+		txt=Utils.readf(fname)
-+	except EnvironmentError:
-+		self.fatal('could not read %s'%fname)
-+	txt=txt.replace('\\\n','\n')
-+	fu=re.compile('#(.*)\n')
-+	txt=fu.sub('',txt)
-+	setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
-+	found=setregexp.findall(txt)
-+	for(_,key,val)in found:
-+		self.env[key]=val
-+	self.env['LIB_KDECORE']=['kdecore']
-+	self.env['LIB_KDEUI']=['kdeui']
-+	self.env['LIB_KIO']=['kio']
-+	self.env['LIB_KHTML']=['khtml']
-+	self.env['LIB_KPARTS']=['kparts']
-+	self.env['LIBPATH_KDECORE']=[os.path.join(self.env.KDE4_LIB_INSTALL_DIR,'kde4','devel'),self.env.KDE4_LIB_INSTALL_DIR]
-+	self.env['INCLUDES_KDECORE']=[self.env['KDE4_INCLUDE_INSTALL_DIR']]
-+	self.env.append_value('INCLUDES_KDECORE',[self.env['KDE4_INCLUDE_INSTALL_DIR']+os.sep+'KDE'])
-+	self.find_program('msgfmt',var='MSGFMT')
---- /dev/null
 +++ b/waflib/Tools/ldc2.py
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,36 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import sys
 +from waflib.Tools import ar,d
 +from waflib.Configure import conf
 + at conf
@@ -9374,21 +9838,21 @@ Last-Update: 2014-11-28
 + at conf
 +def common_flags_ldc2(conf):
 +	v=conf.env
-+	v['D_SRC_F']=['-c']
-+	v['D_TGT_F']='-of%s'
-+	v['D_LINKER']=v['D']
-+	v['DLNK_SRC_F']=''
-+	v['DLNK_TGT_F']='-of%s'
-+	v['DINC_ST']='-I%s'
-+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
-+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
-+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
-+	v['LINKFLAGS_dshlib']=['-L-shared']
-+	v['DHEADER_ext']='.di'
-+	v['DFLAGS_d_with_header']=['-H','-Hf']
-+	v['D_HDR_F']='%s'
-+	v['LINKFLAGS']=[]
-+	v['DFLAGS_dshlib']=['-relocation-model=pic']
++	v.D_SRC_F=['-c']
++	v.D_TGT_F='-of%s'
++	v.D_LINKER=v.D
++	v.DLNK_SRC_F=''
++	v.DLNK_TGT_F='-of%s'
++	v.DINC_ST='-I%s'
++	v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
++	v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s'
++	v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s'
++	v.LINKFLAGS_dshlib=['-L-shared']
++	v.DHEADER_ext='.di'
++	v.DFLAGS_d_with_header=['-H','-Hf']
++	v.D_HDR_F='%s'
++	v.LINKFLAGS=[]
++	v.DFLAGS_dshlib=['-relocation-model=pic']
 +def configure(conf):
 +	conf.find_ldc2()
 +	conf.load('ar')
@@ -9403,13 +9867,13 @@ Last-Update: 2014-11-28
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +from waflib.TaskGen import extension
-+from waflib import Task,Utils
++from waflib import Task
 + at extension('.lua')
 +def add_lua(self,node):
 +	tsk=self.create_task('luac',node,node.change_ext('.luac'))
 +	inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
 +	if inst_to:
-+		self.bld.install_files(inst_to,tsk.outputs)
++		self.add_install_files(install_to=inst_to,install_from=tsk.outputs)
 +	return tsk
 +class luac(Task.Task):
 +	run_str='${LUAC} -s -o ${TGT} ${SRC}'
@@ -9417,18 +9881,45 @@ Last-Update: 2014-11-28
 +def configure(conf):
 +	conf.find_program('luac',var='LUAC')
 --- /dev/null
++++ b/waflib/Tools/md5_tstamp.py
+@@ -0,0 +1,25 @@
++#! /usr/bin/env python
++# encoding: utf-8
++# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
++
++import os,stat
++from waflib import Utils,Build,Node
++STRONGEST=True
++Build.SAVED_ATTRS.append('hashes_md5_tstamp')
++def h_file(self):
++	filename=self.abspath()
++	st=os.stat(filename)
++	cache=self.ctx.hashes_md5_tstamp
++	if filename in cache and cache[filename][0]==st.st_mtime:
++		return cache[filename][1]
++	global STRONGEST
++	if STRONGEST:
++		ret=Utils.h_file(filename)
++	else:
++		if stat.S_ISDIR(st[stat.ST_MODE]):
++			raise IOError('Not a file')
++		ret=Utils.md5(str((st.st_mtime,st.st_size))).digest()
++	cache[filename]=(st.st_mtime,ret)
++	return ret
++h_file.__doc__=Node.Node.h_file.__doc__
++Node.Node.h_file=h_file
+--- /dev/null
 +++ b/waflib/Tools/msvc.py
-@@ -0,0 +1,749 @@
+@@ -0,0 +1,660 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,re,tempfile
-+from waflib import Utils,Task,Logs,Options,Errors
-+from waflib.Logs import debug,warn
++import os,sys,re
++from waflib import Utils,Logs,Options,Errors
 +from waflib.TaskGen import after_method,feature
 +from waflib.Configure import conf
-+from waflib.Tools import ccroot,c,cxx,ar,winres
++from waflib.Tools import ccroot,c,cxx,ar
 +g_msvc_systemlibs='''
 +aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
 +cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
@@ -9455,31 +9946,44 @@ Last-Update: 2014-11-28
 +def options(opt):
 +	opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
 +	opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
-+def setup_msvc(conf,versions,arch=False):
++	opt.add_option('--no-msvc-lazy',action='store_false',help='lazily check msvc target environments',default=True,dest='msvc_lazy')
++ at conf
++def setup_msvc(conf,versiondict):
 +	platforms=getattr(Options.options,'msvc_targets','').split(',')
 +	if platforms==['']:
-+		platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
++		platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
 +	desired_versions=getattr(Options.options,'msvc_version','').split(',')
 +	if desired_versions==['']:
-+		desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
-+	versiondict=dict(versions)
++		desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys())))
++	lazy_detect=getattr(Options.options,'msvc_lazy',True)
++	if conf.env.MSVC_LAZY_AUTODETECT is False:
++		lazy_detect=False
++	if not lazy_detect:
++		for val in versiondict.values():
++			for arch in list(val.keys()):
++				cfg=val[arch]
++				cfg.evaluate()
++				if not cfg.is_valid:
++					del val[arch]
++		conf.env.MSVC_INSTALLED_VERSIONS=versiondict
 +	for version in desired_versions:
 +		try:
-+			targets=dict(versiondict[version])
-+			for target in platforms:
-+				try:
-+					arch,(p1,p2,p3)=targets[target]
-+					compiler,revision=version.rsplit(' ',1)
-+					if arch:
-+						return compiler,revision,p1,p2,p3,arch
-+					else:
-+						return compiler,revision,p1,p2,p3
-+				except KeyError:continue
-+		except KeyError:continue
-+	conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
++			targets=versiondict[version]
++		except KeyError:
++			continue
++		for arch in platforms:
++			try:
++				cfg=targets[arch]
++			except KeyError:
++				continue
++			cfg.evaluate()
++			if cfg.is_valid:
++				compiler,revision=version.rsplit(' ',1)
++				return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu
++	conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys())))
 + at conf
 +def get_msvc_version(conf,compiler,version,target,vcvars):
-+	debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
++	Logs.debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
 +	try:
 +		conf.msvc_cnt+=1
 +	except AttributeError:
@@ -9515,14 +10019,17 @@ Last-Update: 2014-11-28
 +	if'CL'in env:
 +		del(env['CL'])
 +	try:
-+		try:
-+			conf.cmd_and_log(cxx+['/help'],env=env)
-+		except Exception ,e:
-+			debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
-+			debug(str(e))
-+			conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
-+		else:
-+			debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
++		conf.cmd_and_log(cxx+['/help'],env=env)
++	except UnicodeError:
++		st=Utils.ex_stack()
++		if conf.logger:
++			conf.logger.error(st)
++		conf.fatal('msvc: Unicode error - check the code page?')
++	except Exception ,e:
++		Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s',compiler,version,target,str(e))
++		conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)')
++	else:
++		Logs.debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
 +	finally:
 +		conf.env[compiler_name]=''
 +	return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
@@ -9542,7 +10049,7 @@ Last-Update: 2014-11-28
 +			version=Utils.winreg.EnumKey(all_versions,index)
 +		except WindowsError:
 +			break
-+		index=index+1
++		index+=1
 +		if not version_pattern.match(version):
 +			continue
 +		try:
@@ -9550,14 +10057,11 @@ Last-Update: 2014-11-28
 +			path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
 +		except WindowsError:
 +			continue
-+		if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
-+			targets=[]
++		if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
++			targets={}
 +			for target,arch in all_msvc_platforms:
-+				try:
-+					targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
-+				except conf.errors.ConfigurationError:
-+					pass
-+			versions.append(('wsdk '+version[1:],targets))
++				targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd'))
++			versions['wsdk '+version[1:]]=targets
 +def gather_wince_supported_platforms():
 +	supported_wince_platforms=[]
 +	try:
@@ -9569,43 +10073,43 @@ Last-Update: 2014-11-28
 +			ce_sdk=''
 +	if not ce_sdk:
 +		return supported_wince_platforms
-+	ce_index=0
++	index=0
 +	while 1:
 +		try:
-+			sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
++			sdk_device=Utils.winreg.EnumKey(ce_sdk,index)
++			sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
 +		except WindowsError:
 +			break
-+		ce_index=ce_index+1
-+		sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
++		index+=1
 +		try:
 +			path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
 +		except WindowsError:
 +			try:
 +				path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
-+				path,xml=os.path.split(path)
 +			except WindowsError:
 +				continue
++			path,xml=os.path.split(path)
 +		path=str(path)
 +		path,device=os.path.split(path)
 +		if not device:
 +			path,device=os.path.split(path)
++		platforms=[]
 +		for arch,compiler in all_wince_platforms:
-+			platforms=[]
 +			if os.path.isdir(os.path.join(path,device,'Lib',arch)):
 +				platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
-+			if platforms:
-+				supported_wince_platforms.append((device,platforms))
++		if platforms:
++			supported_wince_platforms.append((device,platforms))
 +	return supported_wince_platforms
 +def gather_msvc_detected_versions():
 +	version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
 +	detected_versions=[]
 +	for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')):
++		prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
 +		try:
-+			prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
 +			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
 +		except WindowsError:
++			prefix='SOFTWARE\\Microsoft\\'+vcver
 +			try:
-+				prefix='SOFTWARE\\Microsoft\\'+vcver
 +				all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
 +			except WindowsError:
 +				continue
@@ -9615,67 +10119,83 @@ Last-Update: 2014-11-28
 +				version=Utils.winreg.EnumKey(all_versions,index)
 +			except WindowsError:
 +				break
-+			index=index+1
++			index+=1
 +			match=version_pattern.match(version)
-+			if not match:
-+				continue
-+			else:
++			if match:
 +				versionnumber=float(match.group(1))
-+			detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
++			else:
++				continue
++			detected_versions.append((versionnumber,version+vcvar,prefix+'\\'+version))
 +	def fun(tup):
 +		return tup[0]
 +	detected_versions.sort(key=fun)
 +	return detected_versions
++class target_compiler(object):
++	def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None):
++		self.conf=ctx
++		self.name=None
++		self.is_valid=False
++		self.is_done=False
++		self.compiler=compiler
++		self.cpu=cpu
++		self.version=version
++		self.bat_target=bat_target
++		self.bat=bat
++		self.callback=callback
++	def evaluate(self):
++		if self.is_done:
++			return
++		self.is_done=True
++		try:
++			vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat)
++		except Errors.ConfigurationError:
++			self.is_valid=False
++			return
++		if self.callback:
++			vs=self.callback(self,vs)
++		self.is_valid=True
++		(self.bindirs,self.incdirs,self.libdirs)=vs
++	def __str__(self):
++		return str((self.bindirs,self.incdirs,self.libdirs))
++	def __repr__(self):
++		return repr((self.bindirs,self.incdirs,self.libdirs))
 + at conf
 +def gather_msvc_targets(conf,versions,version,vc_path):
-+	targets=[]
++	targets={}
 +	if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
 +		for target,realtarget in all_msvc_platforms[::-1]:
-+			try:
-+				targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
-+			except conf.errors.ConfigurationError:
-+				pass
++			targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'vcvarsall.bat'))
 +	elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
-+		try:
-+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
-+		except conf.errors.ConfigurationError:
-+			pass
++		targets['x86']=target_compiler(conf,'msvc','x86',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat'))
 +	elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
-+		try:
-+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
-+		except conf.errors.ConfigurationError:
-+			pass
++		targets['x86']=target_compiler(conf,'msvc','x86',version,'',os.path.join(vc_path,'Bin','vcvars32.bat'))
 +	if targets:
-+		versions.append(('msvc '+version,targets))
++		versions['msvc '+version]=targets
 + at conf
 +def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
 +	for device,platforms in supported_platforms:
-+		cetargets=[]
++		targets={}
 +		for platform,compiler,include,lib in platforms:
 +			winCEpath=os.path.join(vc_path,'ce')
 +			if not os.path.isdir(winCEpath):
 +				continue
-+			try:
-+				common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
-+			except conf.errors.ConfigurationError:
-+				continue
 +			if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
-+				bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
++				bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]
 +				incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
 +				libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
-+				cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
-+		if cetargets:
-+			versions.append((device+' '+version,cetargets))
++				def combine_common(obj,compiler_env):
++					(common_bindirs,_1,_2)=compiler_env
++					return(bindirs+common_bindirs,incdirs,libdirs)
++				targets[platform]=target_compiler(conf,'msvc',platform,version,'x86',vsvars,combine_common)
++		if targets:
++			versions[device+' '+version]=targets
 + at conf
 +def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
-+	targets=[]
++	targets={}
 +	for target,realtarget in all_msvc_platforms[::-1]:
-+		try:
-+			targets.append((target,(realtarget,conf.get_msvc_version('winphone',version,target,vsvars))))
-+		except conf.errors.ConfigurationError ,e:
-+			pass
++		targets[target]=target_compiler(conf,'winphone',realtarget,version,target,vsvars)
 +	if targets:
-+		versions.append(('winphone '+version,targets))
++		versions['winphone '+version]=targets
 + at conf
 +def gather_msvc_versions(conf,versions):
 +	vc_paths=[]
@@ -9686,18 +10206,22 @@ Last-Update: 2014-11-28
 +			except WindowsError:
 +				msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
 +			path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
-+			vc_paths.append((version,os.path.abspath(str(path))))
 +		except WindowsError:
 +			continue
++		else:
++			vc_paths.append((version,os.path.abspath(str(path))))
 +	wince_supported_platforms=gather_wince_supported_platforms()
 +	for version,vc_path in vc_paths:
 +		vs_path=os.path.dirname(vc_path)
 +		vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
 +		if wince_supported_platforms and os.path.isfile(vsvars):
 +			conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
++	for version,vc_path in vc_paths:
++		vs_path=os.path.dirname(vc_path)
 +		vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
 +		if os.path.isfile(vsvars):
 +			conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
++			break
 +	for version,vc_path in vc_paths:
 +		vs_path=os.path.dirname(vc_path)
 +		conf.gather_msvc_targets(versions,version,vc_path)
@@ -9717,39 +10241,35 @@ Last-Update: 2014-11-28
 +			version=Utils.winreg.EnumKey(all_versions,index)
 +		except WindowsError:
 +			break
-+		index=index+1
++		index+=1
 +		if not version_pattern.match(version):
 +			continue
-+		targets=[]
++		targets={}
 +		for target,arch in all_icl_platforms:
++			if target=='intel64':targetDir='EM64T_NATIVE'
++			else:targetDir=target
 +			try:
-+				if target=='intel64':targetDir='EM64T_NATIVE'
-+				else:targetDir=target
 +				Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
 +				icl_version=Utils.winreg.OpenKey(all_versions,version)
 +				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+				batch_file=os.path.join(path,'bin','iclvars.bat')
-+				if os.path.isfile(batch_file):
-+					try:
-+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
-+					except conf.errors.ConfigurationError:
-+						pass
 +			except WindowsError:
 +				pass
++			else:
++				batch_file=os.path.join(path,'bin','iclvars.bat')
++				if os.path.isfile(batch_file):
++					targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
 +		for target,arch in all_icl_platforms:
 +			try:
 +				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
 +				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+				batch_file=os.path.join(path,'bin','iclvars.bat')
-+				if os.path.isfile(batch_file):
-+					try:
-+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
-+					except conf.errors.ConfigurationError:
-+						pass
 +			except WindowsError:
 +				continue
++			else:
++				batch_file=os.path.join(path,'bin','iclvars.bat')
++				if os.path.isfile(batch_file):
++					targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
 +		major=version[0:2]
-+		versions.append(('intel '+major,targets))
++		versions['intel '+major]=targets
 + at conf
 +def gather_intel_composer_versions(conf,versions):
 +	version_pattern=re.compile('^...?.?\...?.?.?')
@@ -9766,31 +10286,31 @@ Last-Update: 2014-11-28
 +			version=Utils.winreg.EnumKey(all_versions,index)
 +		except WindowsError:
 +			break
-+		index=index+1
++		index+=1
 +		if not version_pattern.match(version):
 +			continue
-+		targets=[]
++		targets={}
 +		for target,arch in all_icl_platforms:
++			if target=='intel64':targetDir='EM64T_NATIVE'
++			else:targetDir=target
 +			try:
-+				if target=='intel64':targetDir='EM64T_NATIVE'
-+				else:targetDir=target
 +				try:
 +					defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
 +				except WindowsError:
 +					if targetDir=='EM64T_NATIVE':
 +						defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
 +					else:
-+						raise WindowsError
++						raise
 +				uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
 +				Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
 +				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
 +				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
++			except WindowsError:
++				pass
++			else:
 +				batch_file=os.path.join(path,'bin','iclvars.bat')
 +				if os.path.isfile(batch_file):
-+					try:
-+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
-+					except conf.errors.ConfigurationError ,e:
-+						pass
++					targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
 +				compilervars_warning_attr='_compilervars_warning_key'
 +				if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
 +					setattr(conf,compilervars_warning_attr,False)
@@ -9802,34 +10322,23 @@ Last-Update: 2014-11-28
 +							dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe'
 +							if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)):
 +								Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url))
-+			except WindowsError:
-+				pass
 +		major=version[0:2]
-+		versions.append(('intel '+major,targets))
++		versions['intel '+major]=targets
 + at conf
-+def get_msvc_versions(conf):
-+	if not conf.env['MSVC_INSTALLED_VERSIONS']:
-+		lst=[]
-+		conf.gather_icl_versions(lst)
-+		conf.gather_intel_composer_versions(lst)
-+		conf.gather_wsdk_versions(lst)
-+		conf.gather_msvc_versions(lst)
-+		conf.env['MSVC_INSTALLED_VERSIONS']=lst
-+	return conf.env['MSVC_INSTALLED_VERSIONS']
-+ at conf
-+def print_all_msvc_detected(conf):
-+	for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
-+		Logs.info(version)
-+		for target,l in targets:
-+			Logs.info("\t"+target)
-+ at conf
-+def detect_msvc(conf,arch=False):
-+	versions=get_msvc_versions(conf)
-+	return setup_msvc(conf,versions,arch)
++def detect_msvc(self):
++	return self.setup_msvc(self.get_msvc_versions())
++ at conf
++def get_msvc_versions(self):
++	dct={}
++	self.gather_icl_versions(dct)
++	self.gather_intel_composer_versions(dct)
++	self.gather_wsdk_versions(dct)
++	self.gather_msvc_versions(dct)
++	return dct
 + at conf
 +def find_lt_names_msvc(self,libname,is_static=False):
 +	lt_names=['lib%s.la'%libname,'%s.la'%libname,]
-+	for path in self.env['LIBPATH']:
++	for path in self.env.LIBPATH:
 +		for la in lt_names:
 +			laf=os.path.join(path,la)
 +			dll=None
@@ -9868,9 +10377,9 @@ Last-Update: 2014-11-28
 +		if lt_static==True:
 +			return os.path.join(lt_path,lt_libname)
 +	if lt_path!=None:
-+		_libpaths=[lt_path]+self.env['LIBPATH']
++		_libpaths=[lt_path]+self.env.LIBPATH
 +	else:
-+		_libpaths=self.env['LIBPATH']
++		_libpaths=self.env.LIBPATH
 +	static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
 +	dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
 +	libnames=static_libs
@@ -9879,9 +10388,9 @@ Last-Update: 2014-11-28
 +	for path in _libpaths:
 +		for libn in libnames:
 +			if os.path.exists(os.path.join(path,libn)):
-+				debug('msvc: lib found: %s'%os.path.join(path,libn))
++				Logs.debug('msvc: lib found: %s',os.path.join(path,libn))
 +				return re.sub('\.lib$','',libn)
-+	self.fatal("The library %r could not be found"%libname)
++	self.fatal('The library %r could not be found'%libname)
 +	return re.sub('\.lib$','',libname)
 + at conf
 +def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
@@ -9915,19 +10424,17 @@ Last-Update: 2014-11-28
 +	v=conf.env
 +	if v.NO_MSVC_DETECT:
 +		return
++	compiler,version,path,includes,libdirs,cpu=conf.detect_msvc()
 +	if arch:
-+		compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
-+		v['DEST_CPU']=arch
-+	else:
-+		compiler,version,path,includes,libdirs=conf.detect_msvc()
-+	v['PATH']=path
-+	v['INCLUDES']=includes
-+	v['LIBPATH']=libdirs
-+	v['MSVC_COMPILER']=compiler
++		v.DEST_CPU=cpu
++	v.PATH=path
++	v.INCLUDES=includes
++	v.LIBPATH=libdirs
++	v.MSVC_COMPILER=compiler
 +	try:
-+		v['MSVC_VERSION']=float(version)
-+	except Exception:
-+		v['MSVC_VERSION']=float(version[:-3])
++		v.MSVC_VERSION=float(version)
++	except TypeError:
++		v.MSVC_VERSION=float(version[:-3])
 +def _get_prog_names(conf,compiler):
 +	if compiler=='intel':
 +		compiler_name='ICL'
@@ -9943,87 +10450,82 @@ Last-Update: 2014-11-28
 +	if sys.platform=='cygwin':
 +		conf.fatal('MSVC module does not work under cygwin Python!')
 +	v=conf.env
-+	path=v['PATH']
-+	compiler=v['MSVC_COMPILER']
-+	version=v['MSVC_VERSION']
++	path=v.PATH
++	compiler=v.MSVC_COMPILER
++	version=v.MSVC_VERSION
 +	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
 +	v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
-+	cxx=None
-+	if v['CXX']:cxx=v['CXX']
-+	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
 +	cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
 +	env=dict(conf.environ)
 +	if path:env.update(PATH=';'.join(path))
 +	if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
 +		conf.fatal('the msvc compiler could not be identified')
-+	v['CC']=v['CXX']=cxx
-+	v['CC_NAME']=v['CXX_NAME']='msvc'
-+	if not v['LINK_CXX']:
-+		link=conf.find_program(linker_name,path_list=path)
-+		if link:v['LINK_CXX']=link
-+		else:conf.fatal('%s was not found (linker)'%linker_name)
-+		v['LINK']=link
-+	if not v['LINK_CC']:
-+		v['LINK_CC']=v['LINK_CXX']
-+	if not v['AR']:
++	v.CC=v.CXX=cxx
++	v.CC_NAME=v.CXX_NAME='msvc'
++	if not v.LINK_CXX:
++		v.LINK_CXX=conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name)
++	if not v.LINK_CC:
++		v.LINK_CC=v.LINK_CXX
++	if not v.AR:
 +		stliblink=conf.find_program(lib_name,path_list=path,var='AR')
-+		if not stliblink:return
-+		v['ARFLAGS']=['/NOLOGO']
++		if not stliblink:
++			return
++		v.ARFLAGS=['/nologo']
 +	if v.MSVC_MANIFEST:
 +		conf.find_program('MT',path_list=path,var='MT')
-+		v['MTFLAGS']=['/NOLOGO']
++		v.MTFLAGS=['/nologo']
 +	try:
 +		conf.load('winres')
-+	except Errors.WafError:
-+		warn('Resource compiler not found. Compiling resource file is disabled')
++	except Errors.ConfigurationError:
++		Logs.warn('Resource compiler not found. Compiling resource file is disabled')
 + at conf
 +def visual_studio_add_flags(self):
 +	v=self.env
-+	try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
-+	except Exception:pass
-+	try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
-+	except Exception:pass
++	if self.environ.get('INCLUDE'):
++		v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
++	if self.environ.get('LIB'):
++		v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
 + at conf
 +def msvc_common_flags(conf):
 +	v=conf.env
-+	v['DEST_BINFMT']='pe'
++	v.DEST_BINFMT='pe'
 +	v.append_value('CFLAGS',['/nologo'])
 +	v.append_value('CXXFLAGS',['/nologo'])
-+	v['DEFINES_ST']='/D%s'
-+	v['CC_SRC_F']=''
-+	v['CC_TGT_F']=['/c','/Fo']
-+	v['CXX_SRC_F']=''
-+	v['CXX_TGT_F']=['/c','/Fo']
++	v.append_value('LINKFLAGS',['/nologo'])
++	v.DEFINES_ST='/D%s'
++	v.CC_SRC_F=''
++	v.CC_TGT_F=['/c','/Fo']
++	v.CXX_SRC_F=''
++	v.CXX_TGT_F=['/c','/Fo']
 +	if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6):
-+		v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
-+		v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
-+	v['CPPPATH_ST']='/I%s'
-+	v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
-+	v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
-+	v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
-+	v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
-+	v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
-+	v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
-+	v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
-+	v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
-+	v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
-+	v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
-+	v['LIB_ST']='%s.lib'
-+	v['LIBPATH_ST']='/LIBPATH:%s'
-+	v['STLIB_ST']='%s.lib'
-+	v['STLIBPATH_ST']='/LIBPATH:%s'
-+	v.append_value('LINKFLAGS',['/NOLOGO'])
-+	if v['MSVC_MANIFEST']:
++		v.CC_TGT_F=['/FC']+v.CC_TGT_F
++		v.CXX_TGT_F=['/FC']+v.CXX_TGT_F
++	v.CPPPATH_ST='/I%s'
++	v.AR_TGT_F=v.CCLNK_TGT_F=v.CXXLNK_TGT_F='/OUT:'
++	v.CFLAGS_CONSOLE=v.CXXFLAGS_CONSOLE=['/SUBSYSTEM:CONSOLE']
++	v.CFLAGS_NATIVE=v.CXXFLAGS_NATIVE=['/SUBSYSTEM:NATIVE']
++	v.CFLAGS_POSIX=v.CXXFLAGS_POSIX=['/SUBSYSTEM:POSIX']
++	v.CFLAGS_WINDOWS=v.CXXFLAGS_WINDOWS=['/SUBSYSTEM:WINDOWS']
++	v.CFLAGS_WINDOWSCE=v.CXXFLAGS_WINDOWSCE=['/SUBSYSTEM:WINDOWSCE']
++	v.CFLAGS_CRT_MULTITHREADED=v.CXXFLAGS_CRT_MULTITHREADED=['/MT']
++	v.CFLAGS_CRT_MULTITHREADED_DLL=v.CXXFLAGS_CRT_MULTITHREADED_DLL=['/MD']
++	v.CFLAGS_CRT_MULTITHREADED_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DBG=['/MTd']
++	v.CFLAGS_CRT_MULTITHREADED_DLL_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG=['/MDd']
++	v.LIB_ST='%s.lib'
++	v.LIBPATH_ST='/LIBPATH:%s'
++	v.STLIB_ST='%s.lib'
++	v.STLIBPATH_ST='/LIBPATH:%s'
++	if v.MSVC_MANIFEST:
 +		v.append_value('LINKFLAGS',['/MANIFEST'])
-+	v['CFLAGS_cshlib']=[]
-+	v['CXXFLAGS_cxxshlib']=[]
-+	v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
-+	v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
-+	v['implib_PATTERN']='%s.lib'
-+	v['IMPLIB_ST']='/IMPLIB:%s'
-+	v['LINKFLAGS_cstlib']=[]
-+	v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
-+	v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
++	v.CFLAGS_cshlib=[]
++	v.CXXFLAGS_cxxshlib=[]
++	v.LINKFLAGS_cshlib=v.LINKFLAGS_cxxshlib=['/DLL']
++	v.cshlib_PATTERN=v.cxxshlib_PATTERN='%s.dll'
++	v.implib_PATTERN='%s.lib'
++	v.IMPLIB_ST='/IMPLIB:%s'
++	v.LINKFLAGS_cstlib=[]
++	v.cstlib_PATTERN=v.cxxstlib_PATTERN='%s.lib'
++	v.cprogram_PATTERN=v.cxxprogram_PATTERN='%s.exe'
 + at after_method('apply_link')
 + at feature('c','cxx')
 +def apply_flags_msvc(self):
@@ -10042,7 +10544,7 @@ Last-Update: 2014-11-28
 +				pdbnode=self.link_task.outputs[0].change_ext('.pdb')
 +				self.link_task.outputs.append(pdbnode)
 +				if getattr(self,'install_task',None):
-+					self.pdb_install_task=self.bld.install_files(self.install_task.dest,pdbnode,env=self.env)
++					self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode)
 +				break
 + at feature('cprogram','cshlib','cxxprogram','cxxshlib')
 + at after_method('apply_link')
@@ -10051,109 +10553,11 @@ Last-Update: 2014-11-28
 +		out_node=self.link_task.outputs[0]
 +		man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
 +		self.link_task.outputs.append(man_node)
-+		self.link_task.do_manifest=True
-+def exec_mf(self):
-+	env=self.env
-+	mtool=env['MT']
-+	if not mtool:
-+		return 0
-+	self.do_manifest=False
-+	outfile=self.outputs[0].abspath()
-+	manifest=None
-+	for out_node in self.outputs:
-+		if out_node.name.endswith('.manifest'):
-+			manifest=out_node.abspath()
-+			break
-+	if manifest is None:
-+		return 0
-+	mode=''
-+	if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
-+		mode='1'
-+	elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
-+		mode='2'
-+	debug('msvc: embedding manifest in mode %r'%mode)
-+	lst=[]+mtool
-+	lst.extend(Utils.to_list(env['MTFLAGS']))
-+	lst.extend(['-manifest',manifest])
-+	lst.append('-outputresource:%s;%s'%(outfile,mode))
-+	return self.exec_command(lst)
-+def quote_response_command(self,flag):
-+	if flag.find(' ')>-1:
-+		for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
-+			if flag.startswith(x):
-+				flag='%s"%s"'%(x,flag[len(x):])
-+				break
-+		else:
-+			flag='"%s"'%flag
-+	return flag
-+def exec_response_command(self,cmd,**kw):
-+	try:
-+		tmp=None
-+		if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
-+			program=cmd[0]
-+			cmd=[self.quote_response_command(x)for x in cmd]
-+			(fd,tmp)=tempfile.mkstemp()
-+			os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
-+			os.close(fd)
-+			cmd=[program,'@'+tmp]
-+		ret=self.generator.bld.exec_command(cmd,**kw)
-+	finally:
-+		if tmp:
-+			try:
-+				os.remove(tmp)
-+			except OSError:
-+				pass
-+	return ret
-+def exec_command_msvc(self,*k,**kw):
-+	if isinstance(k[0],list):
-+		lst=[]
-+		carry=''
-+		for a in k[0]:
-+			if a=='/Fo'or a=='/doc'or a[-1]==':':
-+				carry=a
-+			else:
-+				lst.append(carry+a)
-+				carry=''
-+		k=[lst]
-+	if self.env['PATH']:
-+		env=dict(self.env.env or os.environ)
-+		env.update(PATH=';'.join(self.env['PATH']))
-+		kw['env']=env
-+	bld=self.generator.bld
-+	try:
-+		if not kw.get('cwd',None):
-+			kw['cwd']=bld.cwd
-+	except AttributeError:
-+		bld.cwd=kw['cwd']=bld.variant_dir
-+	ret=self.exec_response_command(k[0],**kw)
-+	if not ret and getattr(self,'do_manifest',None):
-+		ret=self.exec_mf()
-+	return ret
-+def wrap_class(class_name):
-+	cls=Task.classes.get(class_name,None)
-+	if not cls:
-+		return None
-+	derived_class=type(class_name,(cls,),{})
-+	def exec_command(self,*k,**kw):
-+		if self.env['CC_NAME']=='msvc':
-+			return self.exec_command_msvc(*k,**kw)
-+		else:
-+			return super(derived_class,self).exec_command(*k,**kw)
-+	derived_class.exec_command=exec_command
-+	derived_class.exec_response_command=exec_response_command
-+	derived_class.quote_response_command=quote_response_command
-+	derived_class.exec_command_msvc=exec_command_msvc
-+	derived_class.exec_mf=exec_mf
-+	if hasattr(cls,'hcode'):
-+		derived_class.hcode=cls.hcode
-+	return derived_class
-+for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
-+	wrap_class(k)
++		self.env.DO_MANIFEST=True
 +def make_winapp(self,family):
 +	append=self.env.append_unique
 +	append('DEFINES','WINAPI_FAMILY=%s'%family)
-+	append('CXXFLAGS','/ZW')
-+	append('CXXFLAGS','/TP')
++	append('CXXFLAGS',['/ZW','/TP'])
 +	for lib_path in self.env.LIBPATH:
 +		append('CXXFLAGS','/AI%s'%lib_path)
 + at feature('winphoneapp')
@@ -10161,8 +10565,7 @@ Last-Update: 2014-11-28
 + at after_method('propagate_uselib_vars')
 +def make_winphone_app(self):
 +	make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
-+	conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
-+	conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
++	conf.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib'])
 + at feature('winapp')
 + at after_method('process_use')
 + at after_method('propagate_uselib_vars')
@@ -10182,14 +10585,28 @@ Last-Update: 2014-11-28
 +def apply_nasm_vars(self):
 +	self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
 +def configure(conf):
-+	nasm=conf.find_program(['nasm','yasm'],var='AS')
++	conf.find_program(['nasm','yasm'],var='AS')
 +	conf.env.AS_TGT_F=['-o']
 +	conf.env.ASLNK_TGT_F=['-o']
 +	conf.load('asm')
 +	conf.env.ASMPATH_ST='-I%s'+os.sep
 --- /dev/null
++++ b/waflib/Tools/nobuild.py
+@@ -0,0 +1,11 @@
++#! /usr/bin/env python
++# encoding: utf-8
++# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
++
++from waflib import Task
++def build(bld):
++	def run(self):
++		for x in self.outputs:
++			x.write('')
++	for(name,cls)in Task.classes.items():
++		cls.run=run
+--- /dev/null
 +++ b/waflib/Tools/perl.py
-@@ -0,0 +1,90 @@
+@@ -0,0 +1,84 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -10203,7 +10620,7 @@ Last-Update: 2014-11-28
 +def init_perlext(self):
 +	self.uselib=self.to_list(getattr(self,'uselib',[]))
 +	if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
-+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['perlext_PATTERN']
++	self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.perlext_PATTERN
 + at extension('.xs')
 +def xsubpp_file(self,node):
 +	outnode=node.change_ext('.c')
@@ -10221,14 +10638,8 @@ Last-Update: 2014-11-28
 +	else:
 +		cver=''
 +	self.start_msg('Checking for minimum perl version %s'%cver)
-+	perl=getattr(Options.options,'perlbinary',None)
-+	if not perl:
-+		perl=self.find_program('perl',var='PERL')
-+	if not perl:
-+		self.end_msg("Perl not found",color="YELLOW")
-+		return False
-+	self.env['PERL']=perl
-+	version=self.cmd_and_log(self.env.PERL+["-e",'printf \"%vd\", $^V'])
++	perl=self.find_program('perl',var='PERL',value=getattr(Options.options,'perlbinary',None))
++	version=self.cmd_and_log(perl+["-e",'printf \"%vd\", $^V'])
 +	if not version:
 +		res=False
 +		version="Unknown"
@@ -10236,7 +10647,7 @@ Last-Update: 2014-11-28
 +		ver=tuple(map(int,version.split(".")))
 +		if ver<minver:
 +			res=False
-+	self.end_msg(version,color=res and"GREEN"or"YELLOW")
++	self.end_msg(version,color=res and'GREEN'or'YELLOW')
 +	return res
 + at conf
 +def check_perl_module(self,module):
@@ -10267,22 +10678,22 @@ Last-Update: 2014-11-28
 +			if xsubpp and os.path.isfile(xsubpp[0]):
 +				return xsubpp
 +		return self.find_program('xsubpp')
-+	env['LINKFLAGS_PERLEXT']=cfg_lst('$Config{lddlflags}')
-+	env['INCLUDES_PERLEXT']=cfg_lst('$Config{archlib}/CORE')
-+	env['CFLAGS_PERLEXT']=cfg_lst('$Config{ccflags} $Config{cccdlflags}')
-+	env['EXTUTILS_TYPEMAP']=cfg_lst('$Config{privlib}/ExtUtils/typemap')
-+	env['XSUBPP']=find_xsubpp()
++	env.LINKFLAGS_PERLEXT=cfg_lst('$Config{lddlflags}')
++	env.INCLUDES_PERLEXT=cfg_lst('$Config{archlib}/CORE')
++	env.CFLAGS_PERLEXT=cfg_lst('$Config{ccflags} $Config{cccdlflags}')
++	env.EXTUTILS_TYPEMAP=cfg_lst('$Config{privlib}/ExtUtils/typemap')
++	env.XSUBPP=find_xsubpp()
 +	if not getattr(Options.options,'perlarchdir',None):
-+		env['ARCHDIR_PERL']=cfg_str('$Config{sitearch}')
++		env.ARCHDIR_PERL=cfg_str('$Config{sitearch}')
 +	else:
-+		env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
-+	env['perlext_PATTERN']='%s.'+cfg_str('$Config{dlext}')
++		env.ARCHDIR_PERL=getattr(Options.options,'perlarchdir')
++	env.perlext_PATTERN='%s.'+cfg_str('$Config{dlext}')
 +def options(opt):
 +	opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
 +	opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
 --- /dev/null
 +++ b/waflib/Tools/python.py
-@@ -0,0 +1,379 @@
+@@ -0,0 +1,407 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -10332,9 +10743,9 @@ Last-Update: 2014-11-28
 +	assert(getattr(self,'install_path')),'add features="py"'
 +	if self.install_path:
 +		if self.install_from:
-+			self.bld.install_files(self.install_path,[node],cwd=self.install_from,relative_trick=True)
++			self.add_install_files(install_to=self.install_path,install_from=node,cwd=self.install_from,relative_trick=True)
 +		else:
-+			self.bld.install_files(self.install_path,[node],relative_trick=True)
++			self.add_install_files(install_to=self.install_path,install_from=node,relative_trick=True)
 +	lst=[]
 +	if self.env.PYC:
 +		lst.append('pyc')
@@ -10348,7 +10759,7 @@ Last-Update: 2014-11-28
 +	else:
 +		pyd=node.abspath()
 +	for ext in lst:
-+		if self.env.PYTAG:
++		if self.env.PYTAG and not self.env.NOPYCACHE:
 +			name=node.name[:-3]
 +			pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext))
 +			pyobj.parent.mkdir()
@@ -10357,15 +10768,21 @@ Last-Update: 2014-11-28
 +		tsk=self.create_task(ext,node,pyobj)
 +		tsk.pyd=pyd
 +		if self.install_path:
-+			self.bld.install_files(os.path.dirname(pyd),pyobj,cwd=node.parent.get_bld(),relative_trick=True)
++			self.add_install_files(install_to=os.path.dirname(pyd),install_from=pyobj,cwd=node.parent.get_bld(),relative_trick=True)
 +class pyc(Task.Task):
 +	color='PINK'
++	def __str__(self):
++		node=self.outputs[0]
++		return node.path_from(node.ctx.launch_node())
 +	def run(self):
 +		cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
 +		ret=self.generator.bld.exec_command(cmd)
 +		return ret
 +class pyo(Task.Task):
 +	color='PINK'
++	def __str__(self):
++		node=self.outputs[0]
++		return node.path_from(node.ctx.launch_node())
 +	def run(self):
 +		cmd=[Utils.subst_vars('${PYTHON}',self.env),Utils.subst_vars('${PYFLAGS_OPT}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
 +		ret=self.generator.bld.exec_command(cmd)
@@ -10430,6 +10847,12 @@ Last-Update: 2014-11-28
 +		else:break
 +	return return_values
 + at conf
++def test_pyembed(self,mode,msg='Testing pyembed configuration'):
++	self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg=msg,fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(mode,mode))
++ at conf
++def test_pyext(self,mode,msg='Testing pyext configuration'):
++	self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg=msg,fragment=FRAG,errmsg='Could not build python extensions',features='%s %sshlib pyext'%(mode,mode))
++ at conf
 +def python_cross_compile(self,features='pyembed pyext'):
 +	features=Utils.to_list(features)
 +	if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ):
@@ -10441,30 +10864,30 @@ Last-Update: 2014-11-28
 +			self.env[x]=self.environ[x]
 +	xx=self.env.CXX_NAME and'cxx'or'c'
 +	if'pyext'in features:
-+		flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
++		flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS'))
 +		if flags is None:
 +			self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
 +		else:
 +			self.parse_flags(flags,'PYEXT')
-+		self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg='Testing pyext configuration',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
++		self.test_pyext(xx)
 +	if'pyembed'in features:
-+		flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
++		flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS'))
 +		if flags is None:
 +			self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
 +		else:
 +			self.parse_flags(flags,'PYEMBED')
-+		self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg='Testing pyembed configuration',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
++		self.test_pyembed(xx)
 +	return True
 + at conf
 +def check_python_headers(conf,features='pyembed pyext'):
 +	features=Utils.to_list(features)
 +	assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'"
 +	env=conf.env
-+	if not env['CC_NAME']and not env['CXX_NAME']:
++	if not env.CC_NAME and not env.CXX_NAME:
 +		conf.fatal('load a compiler first (gcc, g++, ..)')
 +	if conf.python_cross_compile(features):
 +		return
-+	if not env['PYTHON_VERSION']:
++	if not env.PYTHON_VERSION:
 +		conf.check_python_version()
 +	pybin=env.PYTHON
 +	if not pybin:
@@ -10480,8 +10903,8 @@ Last-Update: 2014-11-28
 +	x='MACOSX_DEPLOYMENT_TARGET'
 +	if dct[x]:
 +		env[x]=conf.environ[x]=dct[x]
-+	env['pyext_PATTERN']='%s'+dct['SO']
-+	num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
++	env.pyext_PATTERN='%s'+dct['SO']
++	num='.'.join(env.PYTHON_VERSION.split('.')[:2])
 +	conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',msg="python-config",mandatory=False)
 +	if env.PYTHON_CONFIG:
 +		all_flags=[['--cflags','--libs','--ldflags']]
@@ -10491,11 +10914,25 @@ Last-Update: 2014-11-28
 +		if'pyembed'in features:
 +			for flags in all_flags:
 +				conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags)
-+			conf.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
++			try:
++				conf.test_pyembed(xx)
++			except conf.errors.ConfigurationError:
++				if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
++					env.append_unique('LIBPATH_PYEMBED',[dct['LIBDIR']])
++					conf.test_pyembed(xx)
++				else:
++					raise
 +		if'pyext'in features:
 +			for flags in all_flags:
 +				conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags)
-+			conf.check(header_name='Python.h',define_name='HAVE_PYEXT',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
++			try:
++				conf.test_pyext(xx)
++			except conf.errors.ConfigurationError:
++				if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
++					env.append_unique('LIBPATH_PYEXT',[dct['LIBDIR']])
++					conf.test_pyext(xx)
++				else:
++					raise
 +		conf.define('HAVE_PYTHON_H',1)
 +		return
 +	all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
@@ -10504,10 +10941,10 @@ Last-Update: 2014-11-28
 +	conf.parse_flags(all_flags,'PYEXT')
 +	result=None
 +	if not dct["LDVERSION"]:
-+		dct["LDVERSION"]=env['PYTHON_VERSION']
-+	for name in('python'+dct['LDVERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
-+		if not result and env['LIBPATH_PYEMBED']:
-+			path=env['LIBPATH_PYEMBED']
++		dct["LDVERSION"]=env.PYTHON_VERSION
++	for name in('python'+dct['LDVERSION'],'python'+env.PYTHON_VERSION+'m','python'+env.PYTHON_VERSION.replace('.','')):
++		if not result and env.LIBPATH_PYEMBED:
++			path=env.LIBPATH_PYEMBED
 +			conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
 +			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
 +		if not result and dct['LIBDIR']:
@@ -10525,20 +10962,20 @@ Last-Update: 2014-11-28
 +		if result:
 +			break
 +	if result:
-+		env['LIBPATH_PYEMBED']=path
++		env.LIBPATH_PYEMBED=path
 +		env.append_value('LIB_PYEMBED',[name])
 +	else:
 +		conf.to_log("\n\n### LIB NOT FOUND\n")
 +	if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
-+		env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
-+		env['LIB_PYEXT']=env['LIB_PYEMBED']
++		env.LIBPATH_PYEXT=env.LIBPATH_PYEMBED
++		env.LIB_PYEXT=env.LIB_PYEMBED
 +	conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],))
-+	env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
-+	env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
-+	if env['CC_NAME']=='gcc':
++	env.INCLUDES_PYEXT=[dct['INCLUDEPY']]
++	env.INCLUDES_PYEMBED=[dct['INCLUDEPY']]
++	if env.CC_NAME=='gcc':
 +		env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
 +		env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
-+	if env['CXX_NAME']=='gcc':
++	if env.CXX_NAME=='gcc':
 +		env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
 +		env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
 +	if env.CC_NAME=="msvc":
@@ -10552,20 +10989,20 @@ Last-Update: 2014-11-28
 + at conf
 +def check_python_version(conf,minver=None):
 +	assert minver is None or isinstance(minver,tuple)
-+	pybin=conf.env['PYTHON']
++	pybin=conf.env.PYTHON
 +	if not pybin:
 +		conf.fatal('could not find the python executable')
 +	cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
-+	Logs.debug('python: Running python command %r'%cmd)
++	Logs.debug('python: Running python command %r',cmd)
 +	lines=conf.cmd_and_log(cmd).split()
-+	assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
++	assert len(lines)==5,"found %r lines, expected 5: %r"%(len(lines),lines)
 +	pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
 +	result=(minver is None)or(pyver_tuple>=minver)
 +	if result:
 +		pyver='.'.join([str(x)for x in pyver_tuple[:2]])
-+		conf.env['PYTHON_VERSION']=pyver
++		conf.env.PYTHON_VERSION=pyver
 +		if'PYTHONDIR'in conf.env:
-+			pydir=conf.env['PYTHONDIR']
++			pydir=conf.env.PYTHONDIR
 +		elif'PYTHONDIR'in conf.environ:
 +			pydir=conf.environ['PYTHONDIR']
 +		else:
@@ -10575,12 +11012,12 @@ Last-Update: 2014-11-28
 +				python_LIBDEST=None
 +				(pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX])
 +			if python_LIBDEST is None:
-+				if conf.env['LIBDIR']:
-+					python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
++				if conf.env.LIBDIR:
++					python_LIBDEST=os.path.join(conf.env.LIBDIR,'python'+pyver)
 +				else:
-+					python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
++					python_LIBDEST=os.path.join(conf.env.PREFIX,'lib','python'+pyver)
 +		if'PYTHONARCHDIR'in conf.env:
-+			pyarchdir=conf.env['PYTHONARCHDIR']
++			pyarchdir=conf.env.PYTHONARCHDIR
 +		elif'PYTHONARCHDIR'in conf.environ:
 +			pyarchdir=conf.environ['PYTHONARCHDIR']
 +		else:
@@ -10590,14 +11027,14 @@ Last-Update: 2014-11-28
 +		if hasattr(conf,'define'):
 +			conf.define('PYTHONDIR',pydir)
 +			conf.define('PYTHONARCHDIR',pyarchdir)
-+		conf.env['PYTHONDIR']=pydir
-+		conf.env['PYTHONARCHDIR']=pyarchdir
++		conf.env.PYTHONDIR=pydir
++		conf.env.PYTHONARCHDIR=pyarchdir
 +	pyver_full='.'.join(map(str,pyver_tuple[:3]))
 +	if minver is None:
 +		conf.msg('Checking for python version',pyver_full)
 +	else:
 +		minver_str='.'.join(map(str,minver))
-+		conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
++		conf.msg('Checking for python version >= %s'%(minver_str,),pyver_full,color=result and'GREEN'or'YELLOW')
 +	if not result:
 +		conf.fatal('The python version is too old, expecting %r'%(minver,))
 +PYTHON_MODULE_TEMPLATE='''
@@ -10610,505 +11047,63 @@ Last-Update: 2014-11-28
 +'''
 + at conf
 +def check_python_module(conf,module_name,condition=''):
-+	msg="Checking for python module '%s'"%module_name
-+	if condition:
-+		msg='%s (%s)'%(msg,condition)
-+	conf.start_msg(msg)
-+	try:
-+		ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
-+	except Exception:
-+		conf.end_msg(False)
-+		conf.fatal('Could not find the python module %r'%module_name)
-+	ret=ret.strip()
-+	if condition:
-+		conf.end_msg(ret)
-+		if ret=='unknown version':
-+			conf.fatal('Could not check the %s version'%module_name)
-+		from distutils.version import LooseVersion
-+		def num(*k):
-+			if isinstance(k[0],int):
-+				return LooseVersion('.'.join([str(x)for x in k]))
-+			else:
-+				return LooseVersion(k[0])
-+		d={'num':num,'ver':LooseVersion(ret)}
-+		ev=eval(condition,{},d)
-+		if not ev:
-+			conf.fatal('The %s version does not satisfy the requirements'%module_name)
-+	else:
-+		if ret=='unknown version':
-+			conf.end_msg(True)
-+		else:
-+			conf.end_msg(ret)
-+def configure(conf):
-+	v=conf.env
-+	v['PYTHON']=Options.options.python or os.environ.get('PYTHON',sys.executable)
-+	if Options.options.pythondir:
-+		v['PYTHONDIR']=Options.options.pythondir
-+	if Options.options.pythonarchdir:
-+		v['PYTHONARCHDIR']=Options.options.pythonarchdir
-+	conf.find_program('python',var='PYTHON')
-+	v['PYFLAGS']=''
-+	v['PYFLAGS_OPT']='-O'
-+	v['PYC']=getattr(Options.options,'pyc',1)
-+	v['PYO']=getattr(Options.options,'pyo',1)
-+	try:
-+		v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip()
-+	except Errors.WafError:
-+		pass
-+def options(opt):
-+	pyopt=opt.add_option_group("Python Options")
-+	pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]')
-+	pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
-+	pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable)
-+	pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)')
-+	pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
---- /dev/null
-+++ b/waflib/Tools/qt4.py
-@@ -0,0 +1,441 @@
-+#! /usr/bin/env python
-+# encoding: utf-8
-+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
-+
-+try:
-+	from xml.sax import make_parser
-+	from xml.sax.handler import ContentHandler
-+except ImportError:
-+	has_xml=False
-+	ContentHandler=object
-+else:
-+	has_xml=True
-+import os,sys
-+from waflib.Tools import cxx
-+from waflib import Task,Utils,Options,Errors,Context
-+from waflib.TaskGen import feature,after_method,extension
-+from waflib.Configure import conf
-+from waflib import Logs
-+MOC_H=['.h','.hpp','.hxx','.hh']
-+EXT_RCC=['.qrc']
-+EXT_UI=['.ui']
-+EXT_QT4=['.cpp','.cc','.cxx','.C']
-+QT4_LIBS="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner"
-+class qxx(Task.classes['cxx']):
-+	def __init__(self,*k,**kw):
-+		Task.Task.__init__(self,*k,**kw)
-+		self.moc_done=0
-+	def runnable_status(self):
-+		if self.moc_done:
-+			return Task.Task.runnable_status(self)
-+		else:
-+			for t in self.run_after:
-+				if not t.hasrun:
-+					return Task.ASK_LATER
-+			self.add_moc_tasks()
-+			return Task.Task.runnable_status(self)
-+	def create_moc_task(self,h_node,m_node):
-+		try:
-+			moc_cache=self.generator.bld.moc_cache
-+		except AttributeError:
-+			moc_cache=self.generator.bld.moc_cache={}
-+		try:
-+			return moc_cache[h_node]
-+		except KeyError:
-+			tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
-+			tsk.set_inputs(h_node)
-+			tsk.set_outputs(m_node)
-+			if self.generator:
-+				self.generator.tasks.append(tsk)
-+			gen=self.generator.bld.producer
-+			gen.outstanding.insert(0,tsk)
-+			gen.total+=1
-+			return tsk
-+	def moc_h_ext(self):
-+		try:
-+			ext=Options.options.qt_header_ext.split()
-+		except AttributeError:
-+			pass
-+		if not ext:
-+			ext=MOC_H
-+		return ext
-+	def add_moc_tasks(self):
-+		node=self.inputs[0]
-+		bld=self.generator.bld
-+		try:
-+			self.signature()
-+		except KeyError:
-+			pass
-+		else:
-+			delattr(self,'cache_sig')
-+		include_nodes=[node.parent]+self.generator.includes_nodes
-+		moctasks=[]
-+		mocfiles=set([])
-+		for d in bld.raw_deps.get(self.uid(),[]):
-+			if not d.endswith('.moc'):
-+				continue
-+			if d in mocfiles:
-+				continue
-+			mocfiles.add(d)
-+			h_node=None
-+			base2=d[:-4]
-+			for x in include_nodes:
-+				for e in self.moc_h_ext():
-+					h_node=x.find_node(base2+e)
-+					if h_node:
-+						break
-+				if h_node:
-+					m_node=h_node.change_ext('.moc')
-+					break
-+			else:
-+				for k in EXT_QT4:
-+					if base2.endswith(k):
-+						for x in include_nodes:
-+							h_node=x.find_node(base2)
-+							if h_node:
-+								break
-+						if h_node:
-+							m_node=h_node.change_ext(k+'.moc')
-+							break
-+			if not h_node:
-+				raise Errors.WafError('No source found for %r which is a moc file'%d)
-+			task=self.create_moc_task(h_node,m_node)
-+			moctasks.append(task)
-+		self.run_after.update(set(moctasks))
-+		self.moc_done=1
-+class trans_update(Task.Task):
-+	run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
-+	color='BLUE'
-+Task.update_outputs(trans_update)
-+class XMLHandler(ContentHandler):
-+	def __init__(self):
-+		self.buf=[]
-+		self.files=[]
-+	def startElement(self,name,attrs):
-+		if name=='file':
-+			self.buf=[]
-+	def endElement(self,name):
-+		if name=='file':
-+			self.files.append(str(''.join(self.buf)))
-+	def characters(self,cars):
-+		self.buf.append(cars)
-+ at extension(*EXT_RCC)
-+def create_rcc_task(self,node):
-+	rcnode=node.change_ext('_rc.cpp')
-+	self.create_task('rcc',node,rcnode)
-+	cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
-+	try:
-+		self.compiled_tasks.append(cpptask)
-+	except AttributeError:
-+		self.compiled_tasks=[cpptask]
-+	return cpptask
-+ at extension(*EXT_UI)
-+def create_uic_task(self,node):
-+	uictask=self.create_task('ui4',node)
-+	uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
-+ at extension('.ts')
-+def add_lang(self,node):
-+	self.lang=self.to_list(getattr(self,'lang',[]))+[node]
-+ at feature('qt4')
-+ at after_method('apply_link')
-+def apply_qt4(self):
-+	if getattr(self,'lang',None):
-+		qmtasks=[]
-+		for x in self.to_list(self.lang):
-+			if isinstance(x,str):
-+				x=self.path.find_resource(x+'.ts')
-+			qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
-+		if getattr(self,'update',None)and Options.options.trans_qt4:
-+			cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
-+			for x in qmtasks:
-+				self.create_task('trans_update',cxxnodes,x.inputs)
-+		if getattr(self,'langname',None):
-+			qmnodes=[x.outputs[0]for x in qmtasks]
-+			rcnode=self.langname
-+			if isinstance(rcnode,str):
-+				rcnode=self.path.find_or_declare(rcnode+'.qrc')
-+			t=self.create_task('qm2rcc',qmnodes,rcnode)
-+			k=create_rcc_task(self,t.outputs[0])
-+			self.link_task.inputs.append(k.outputs[0])
-+	lst=[]
-+	for flag in self.to_list(self.env['CXXFLAGS']):
-+		if len(flag)<2:continue
-+		f=flag[0:2]
-+		if f in('-D','-I','/D','/I'):
-+			if(f[0]=='/'):
-+				lst.append('-'+flag[1:])
-+			else:
-+				lst.append(flag)
-+	self.env.append_value('MOC_FLAGS',lst)
-+ at extension(*EXT_QT4)
-+def cxx_hook(self,node):
-+	return self.create_compiled_task('qxx',node)
-+class rcc(Task.Task):
-+	color='BLUE'
-+	run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
-+	ext_out=['.h']
-+	def rcname(self):
-+		return os.path.splitext(self.inputs[0].name)[0]
-+	def scan(self):
-+		if not has_xml:
-+			Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
-+			return([],[])
-+		parser=make_parser()
-+		curHandler=XMLHandler()
-+		parser.setContentHandler(curHandler)
-+		fi=open(self.inputs[0].abspath(),'r')
-+		try:
-+			parser.parse(fi)
-+		finally:
-+			fi.close()
-+		nodes=[]
-+		names=[]
-+		root=self.inputs[0].parent
-+		for x in curHandler.files:
-+			nd=root.find_resource(x)
-+			if nd:nodes.append(nd)
-+			else:names.append(x)
-+		return(nodes,names)
-+class moc(Task.Task):
-+	color='BLUE'
-+	run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
-+	def keyword(self):
-+		return"Creating"
-+	def __str__(self):
-+		return self.outputs[0].path_from(self.generator.bld.launch_node())
-+class ui4(Task.Task):
-+	color='BLUE'
-+	run_str='${QT_UIC} ${SRC} -o ${TGT}'
-+	ext_out=['.h']
-+class ts2qm(Task.Task):
-+	color='BLUE'
-+	run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
-+class qm2rcc(Task.Task):
-+	color='BLUE'
-+	after='ts2qm'
-+	def run(self):
-+		txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
-+		code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
-+		self.outputs[0].write(code)
-+def configure(self):
-+	self.find_qt4_binaries()
-+	self.set_qt4_libs_to_check()
-+	self.set_qt4_defines()
-+	self.find_qt4_libraries()
-+	self.add_qt4_rpath()
-+	self.simplify_qt4_libs()
-+ at conf
-+def find_qt4_binaries(self):
-+	env=self.env
-+	opt=Options.options
-+	qtdir=getattr(opt,'qtdir','')
-+	qtbin=getattr(opt,'qtbin','')
-+	paths=[]
-+	if qtdir:
-+		qtbin=os.path.join(qtdir,'bin')
-+	if not qtdir:
-+		qtdir=os.environ.get('QT4_ROOT','')
-+		qtbin=os.environ.get('QT4_BIN',None)or os.path.join(qtdir,'bin')
-+	if qtbin:
-+		paths=[qtbin]
-+	if not qtdir:
-+		paths=os.environ.get('PATH','').split(os.pathsep)
-+		paths.append('/usr/share/qt4/bin/')
-+		try:
-+			lst=Utils.listdir('/usr/local/Trolltech/')
-+		except OSError:
-+			pass
-+		else:
-+			if lst:
-+				lst.sort()
-+				lst.reverse()
-+				qtdir='/usr/local/Trolltech/%s/'%lst[0]
-+				qtbin=os.path.join(qtdir,'bin')
-+				paths.append(qtbin)
-+	cand=None
-+	prev_ver=['4','0','0']
-+	for qmk in('qmake-qt4','qmake4','qmake'):
-+		try:
-+			qmake=self.find_program(qmk,path_list=paths)
-+		except self.errors.ConfigurationError:
-+			pass
-+		else:
-+			try:
-+				version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
-+			except self.errors.WafError:
-+				pass
-+			else:
-+				if version:
-+					new_ver=version.split('.')
-+					if new_ver>prev_ver:
-+						cand=qmake
-+						prev_ver=new_ver
-+	if cand:
-+		self.env.QMAKE=cand
-+	else:
-+		self.fatal('Could not find qmake for qt4')
-+	qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_BINS']).strip()+os.sep
-+	def find_bin(lst,var):
-+		if var in env:
-+			return
-+		for f in lst:
-+			try:
-+				ret=self.find_program(f,path_list=paths)
-+			except self.errors.ConfigurationError:
-+				pass
-+			else:
-+				env[var]=ret
-+				break
-+	find_bin(['uic-qt3','uic3'],'QT_UIC3')
-+	find_bin(['uic-qt4','uic'],'QT_UIC')
-+	if not env.QT_UIC:
-+		self.fatal('cannot find the uic compiler for qt4')
-+	self.start_msg('Checking for uic version')
-+	uicver=self.cmd_and_log(env.QT_UIC+["-version"],output=Context.BOTH)
-+	uicver=''.join(uicver).strip()
-+	uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
-+	self.end_msg(uicver)
-+	if uicver.find(' 3.')!=-1:
-+		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
-+	find_bin(['moc-qt4','moc'],'QT_MOC')
-+	find_bin(['rcc-qt4','rcc'],'QT_RCC')
-+	find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
-+	find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
-+	env['UIC3_ST']='%s -o %s'
-+	env['UIC_ST']='%s -o %s'
-+	env['MOC_ST']='-o'
-+	env['ui_PATTERN']='ui_%s.h'
-+	env['QT_LRELEASE_FLAGS']=['-silent']
-+	env.MOCCPPPATH_ST='-I%s'
-+	env.MOCDEFINES_ST='-D%s'
-+ at conf
-+def find_qt4_libraries(self):
-+	qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT4_LIBDIR",None)
-+	if not qtlibs:
-+		try:
-+			qtlibs=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
-+		except Errors.WafError:
-+			qtdir=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()+os.sep
-+			qtlibs=os.path.join(qtdir,'lib')
-+	self.msg('Found the Qt4 libraries in',qtlibs)
-+	qtincludes=os.environ.get("QT4_INCLUDES",None)or self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
-+	env=self.env
-+	if not'PKG_CONFIG_PATH'in os.environ:
-+		os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib'%(qtlibs,qtlibs)
-+	try:
-+		if os.environ.get("QT4_XCOMPILE",None):
-+			raise self.errors.ConfigurationError()
-+		self.check_cfg(atleast_pkgconfig_version='0.1')
-+	except self.errors.ConfigurationError:
-+		for i in self.qt4_vars:
-+			uselib=i.upper()
-+			if Utils.unversioned_sys_platform()=="darwin":
-+				frameworkName=i+".framework"
-+				qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
-+				if os.path.exists(qtDynamicLib):
-+					env.append_unique('FRAMEWORK_'+uselib,i)
-+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
-+			elif env.DEST_OS!="win32":
-+				qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
-+				qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
-+				if os.path.exists(qtDynamicLib):
-+					env.append_unique('LIB_'+uselib,i)
-+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
-+				elif os.path.exists(qtStaticLib):
-+					env.append_unique('LIB_'+uselib,i)
-+					self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
-+			else:
-+				for k in("lib%s.a","lib%s4.a","%s.lib","%s4.lib"):
-+					lib=os.path.join(qtlibs,k%i)
-+					if os.path.exists(lib):
-+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
-+						self.msg('Checking for %s'%i,lib,'GREEN')
-+						break
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
-+				uselib=i.upper()+"_debug"
-+				for k in("lib%sd.a","lib%sd4.a","%sd.lib","%sd4.lib"):
-+					lib=os.path.join(qtlibs,k%i)
-+					if os.path.exists(lib):
-+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
-+						self.msg('Checking for %s'%i,lib,'GREEN')
-+						break
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
-+	else:
-+		for i in self.qt4_vars_debug+self.qt4_vars:
-+			self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
-+ at conf
-+def simplify_qt4_libs(self):
-+	env=self.env
-+	def process_lib(vars_,coreval):
-+		for d in vars_:
-+			var=d.upper()
-+			if var=='QTCORE':
-+				continue
-+			value=env['LIBPATH_'+var]
-+			if value:
-+				core=env[coreval]
-+				accu=[]
-+				for lib in value:
-+					if lib in core:
-+						continue
-+					accu.append(lib)
-+				env['LIBPATH_'+var]=accu
-+	process_lib(self.qt4_vars,'LIBPATH_QTCORE')
-+	process_lib(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
-+ at conf
-+def add_qt4_rpath(self):
-+	env=self.env
-+	if getattr(Options.options,'want_rpath',False):
-+		def process_rpath(vars_,coreval):
-+			for d in vars_:
-+				var=d.upper()
-+				value=env['LIBPATH_'+var]
-+				if value:
-+					core=env[coreval]
-+					accu=[]
-+					for lib in value:
-+						if var!='QTCORE':
-+							if lib in core:
-+								continue
-+						accu.append('-Wl,--rpath='+lib)
-+					env['RPATH_'+var]=accu
-+		process_rpath(self.qt4_vars,'LIBPATH_QTCORE')
-+		process_rpath(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
-+ at conf
-+def set_qt4_libs_to_check(self):
-+	if not hasattr(self,'qt4_vars'):
-+		self.qt4_vars=QT4_LIBS
-+	self.qt4_vars=Utils.to_list(self.qt4_vars)
-+	if not hasattr(self,'qt4_vars_debug'):
-+		self.qt4_vars_debug=[a+'_debug'for a in self.qt4_vars]
-+	self.qt4_vars_debug=Utils.to_list(self.qt4_vars_debug)
-+ at conf
-+def set_qt4_defines(self):
-+	if sys.platform!='win32':
-+		return
-+	for x in self.qt4_vars:
-+		y=x[2:].upper()
-+		self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
-+		self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
++	msg="Checking for python module %r"%module_name
++	if condition:
++		msg='%s (%s)'%(msg,condition)
++	conf.start_msg(msg)
++	try:
++		ret=conf.cmd_and_log(conf.env.PYTHON+['-c',PYTHON_MODULE_TEMPLATE%module_name])
++	except Exception:
++		conf.end_msg(False)
++		conf.fatal('Could not find the python module %r'%module_name)
++	ret=ret.strip()
++	if condition:
++		conf.end_msg(ret)
++		if ret=='unknown version':
++			conf.fatal('Could not check the %s version'%module_name)
++		from distutils.version import LooseVersion
++		def num(*k):
++			if isinstance(k[0],int):
++				return LooseVersion('.'.join([str(x)for x in k]))
++			else:
++				return LooseVersion(k[0])
++		d={'num':num,'ver':LooseVersion(ret)}
++		ev=eval(condition,{},d)
++		if not ev:
++			conf.fatal('The %s version does not satisfy the requirements'%module_name)
++	else:
++		if ret=='unknown version':
++			conf.end_msg(True)
++		else:
++			conf.end_msg(ret)
++def configure(conf):
++	v=conf.env
++	if Options.options.pythondir:
++		v.PYTHONDIR=Options.options.pythondir
++	if Options.options.pythonarchdir:
++		v.PYTHONARCHDIR=Options.options.pythonarchdir
++	if Options.options.nopycache:
++		v.NOPYCACHE=Options.options.nopycache
++	conf.find_program('python',var='PYTHON',value=Options.options.python or sys.executable)
++	v.PYFLAGS=''
++	v.PYFLAGS_OPT='-O'
++	v.PYC=getattr(Options.options,'pyc',1)
++	v.PYO=getattr(Options.options,'pyo',1)
++	try:
++		v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip()
++	except Errors.WafError:
++		pass
 +def options(opt):
-+	opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
-+	opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
-+	for i in'qtdir qtbin qtlibs'.split():
-+		opt.add_option('--'+i,type='string',default='',dest=i)
-+	opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False)
++	pyopt=opt.add_option_group("Python Options")
++	pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]')
++	pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
++	pyopt.add_option('--nopycache',dest='nopycache',action='store_true',help='Do not use __pycache__ directory to install objects [Default:auto]')
++	pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable)
++	pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)')
++	pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
 --- /dev/null
 +++ b/waflib/Tools/qt5.py
-@@ -0,0 +1,488 @@
+@@ -0,0 +1,492 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -11121,54 +11116,16 @@ Last-Update: 2014-11-28
 +	ContentHandler=object
 +else:
 +	has_xml=True
-+import os,sys
++import os,sys,re
 +from waflib.Tools import cxx
 +from waflib import Task,Utils,Options,Errors,Context
-+from waflib.TaskGen import feature,after_method,extension
++from waflib.TaskGen import feature,after_method,extension,before_method
 +from waflib.Configure import conf
 +from waflib import Logs
 +MOC_H=['.h','.hpp','.hxx','.hh']
 +EXT_RCC=['.qrc']
 +EXT_UI=['.ui']
 +EXT_QT5=['.cpp','.cc','.cxx','.C']
-+QT5_LIBS='''
-+qtmain
-+Qt5Bluetooth
-+Qt5CLucene
-+Qt5Concurrent
-+Qt5Core
-+Qt5DBus
-+Qt5Declarative
-+Qt5DesignerComponents
-+Qt5Designer
-+Qt5Gui
-+Qt5Help
-+Qt5MultimediaQuick_p
-+Qt5Multimedia
-+Qt5MultimediaWidgets
-+Qt5Network
-+Qt5Nfc
-+Qt5OpenGL
-+Qt5Positioning
-+Qt5PrintSupport
-+Qt5Qml
-+Qt5QuickParticles
-+Qt5Quick
-+Qt5QuickTest
-+Qt5Script
-+Qt5ScriptTools
-+Qt5Sensors
-+Qt5SerialPort
-+Qt5Sql
-+Qt5Svg
-+Qt5Test
-+Qt5WebKit
-+Qt5WebKitWidgets
-+Qt5Widgets
-+Qt5WinExtras
-+Qt5X11Extras
-+Qt5XmlPatterns
-+Qt5Xml'''
 +class qxx(Task.classes['cxx']):
 +	def __init__(self,*k,**kw):
 +		Task.Task.__init__(self,*k,**kw)
@@ -11193,22 +11150,15 @@ Last-Update: 2014-11-28
 +			tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
 +			tsk.set_inputs(h_node)
 +			tsk.set_outputs(m_node)
++			tsk.env.append_unique('MOC_FLAGS','-i')
 +			if self.generator:
 +				self.generator.tasks.append(tsk)
 +			gen=self.generator.bld.producer
-+			gen.outstanding.insert(0,tsk)
++			gen.outstanding.appendleft(tsk)
 +			gen.total+=1
 +			return tsk
 +		else:
 +			delattr(self,'cache_sig')
-+	def moc_h_ext(self):
-+		try:
-+			ext=Options.options.qt_header_ext.split()
-+		except AttributeError:
-+			pass
-+		if not ext:
-+			ext=MOC_H
-+		return ext
 +	def add_moc_tasks(self):
 +		node=self.inputs[0]
 +		bld=self.generator.bld
@@ -11220,7 +11170,7 @@ Last-Update: 2014-11-28
 +			delattr(self,'cache_sig')
 +		include_nodes=[node.parent]+self.generator.includes_nodes
 +		moctasks=[]
-+		mocfiles=set([])
++		mocfiles=set()
 +		for d in bld.raw_deps.get(self.uid(),[]):
 +			if not d.endswith('.moc'):
 +				continue
@@ -11229,25 +11179,21 @@ Last-Update: 2014-11-28
 +			mocfiles.add(d)
 +			h_node=None
 +			base2=d[:-4]
-+			for x in include_nodes:
-+				for e in self.moc_h_ext():
-+					h_node=x.find_node(base2+e)
-+					if h_node:
-+						break
-+				if h_node:
-+					m_node=h_node.change_ext('.moc')
-+					break
++			prefix=node.name[:node.name.rfind('.')]
++			if base2==prefix:
++				h_node=node
 +			else:
-+				for k in EXT_QT5:
-+					if base2.endswith(k):
-+						for x in include_nodes:
-+							h_node=x.find_node(base2)
-+							if h_node:
-+								break
++				for x in include_nodes:
++					for e in MOC_H:
++						h_node=x.find_node(base2+e)
 +						if h_node:
-+							m_node=h_node.change_ext(k+'.moc')
 +							break
-+			if not h_node:
++					else:
++						continue
++					break
++			if h_node:
++				m_node=h_node.change_ext('.moc')
++			else:
 +				raise Errors.WafError('No source found for %r which is a moc file'%d)
 +			task=self.create_moc_task(h_node,m_node)
 +			moctasks.append(task)
@@ -11256,7 +11202,6 @@ Last-Update: 2014-11-28
 +class trans_update(Task.Task):
 +	run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
 +	color='BLUE'
-+Task.update_outputs(trans_update)
 +class XMLHandler(ContentHandler):
 +	def __init__(self):
 +		self.buf=[]
@@ -11282,11 +11227,22 @@ Last-Update: 2014-11-28
 + at extension(*EXT_UI)
 +def create_uic_task(self,node):
 +	uictask=self.create_task('ui5',node)
-+	uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
++	uictask.outputs=[node.parent.find_or_declare(self.env.ui_PATTERN%node.name[:-3])]
 + at extension('.ts')
 +def add_lang(self,node):
 +	self.lang=self.to_list(getattr(self,'lang',[]))+[node]
 + at feature('qt5')
++ at before_method('process_source')
++def process_mocs(self):
++	lst=self.to_nodes(getattr(self,'moc',[]))
++	self.source=self.to_list(getattr(self,'source',[]))
++	for x in lst:
++		prefix=x.name[:x.name.rfind('.')]
++		moc_target='moc_%s.%d.cpp'%(prefix,self.idx)
++		moc_node=x.parent.find_or_declare(moc_target)
++		self.source.append(moc_node)
++		self.create_task('moc',x,moc_node)
++ at feature('qt5')
 + at after_method('apply_link')
 +def apply_qt5(self):
 +	if getattr(self,'lang',None):
@@ -11308,7 +11264,7 @@ Last-Update: 2014-11-28
 +			k=create_rcc_task(self,t.outputs[0])
 +			self.link_task.inputs.append(k.outputs[0])
 +	lst=[]
-+	for flag in self.to_list(self.env['CXXFLAGS']):
++	for flag in self.to_list(self.env.CXXFLAGS):
 +		if len(flag)<2:continue
 +		f=flag[0:2]
 +		if f in('-D','-I','/D','/I'):
@@ -11328,7 +11284,7 @@ Last-Update: 2014-11-28
 +		return os.path.splitext(self.inputs[0].name)[0]
 +	def scan(self):
 +		if not has_xml:
-+			Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
++			Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
 +			return([],[])
 +		parser=make_parser()
 +		curHandler=XMLHandler()
@@ -11365,11 +11321,37 @@ Last-Update: 2014-11-28
 +		self.outputs[0].write(code)
 +def configure(self):
 +	self.find_qt5_binaries()
++	self.set_qt5_libs_dir()
 +	self.set_qt5_libs_to_check()
 +	self.set_qt5_defines()
 +	self.find_qt5_libraries()
 +	self.add_qt5_rpath()
 +	self.simplify_qt5_libs()
++	if not has_xml:
++		Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
++	if'COMPILER_CXX'not in self.env:
++		self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?')
++	frag='#include <QApplication>\nint main(int argc, char **argv) {return 0;}\n'
++	uses='QT5CORE QT5WIDGETS QT5GUI'
++	for flag in[[],'-fPIE','-fPIC','-std=c++11',['-std=c++11','-fPIE'],['-std=c++11','-fPIC']]:
++		msg='See if Qt files compile '
++		if flag:
++			msg+='with %s'%flag
++		try:
++			self.check(features='qt5 cxx',use=uses,uselib_store='qt5',cxxflags=flag,fragment=frag,msg=msg)
++		except self.errors.ConfigurationError:
++			pass
++		else:
++			break
++	else:
++		self.fatal('Could not build a simple Qt application')
++	from waflib import Utils
++	if Utils.unversioned_sys_platform()=='freebsd':
++		frag='#include <QApplication>\nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n'
++		try:
++			self.check(features='qt5 cxx cxxprogram',use=uses,fragment=frag,msg='Can we link Qt programs on FreeBSD directly?')
++		except self.errors.ConfigurationError:
++			self.check(features='qt5 cxx cxxprogram',use=uses,uselib_store='qt5',libpath='/usr/local/lib',fragment=frag,msg='Is /usr/local/lib required?')
 + at conf
 +def find_qt5_binaries(self):
 +	env=self.env
@@ -11380,13 +11362,13 @@ Last-Update: 2014-11-28
 +	if qtdir:
 +		qtbin=os.path.join(qtdir,'bin')
 +	if not qtdir:
-+		qtdir=os.environ.get('QT5_ROOT','')
-+		qtbin=os.environ.get('QT5_BIN',None)or os.path.join(qtdir,'bin')
++		qtdir=self.environ.get('QT5_ROOT','')
++		qtbin=self.environ.get('QT5_BIN')or os.path.join(qtdir,'bin')
 +	if qtbin:
 +		paths=[qtbin]
 +	if not qtdir:
-+		paths=os.environ.get('PATH','').split(os.pathsep)
-+		paths.append('/usr/share/qt5/bin/')
++		paths=self.environ.get('PATH','').split(os.pathsep)
++		paths.extend(['/usr/share/qt5/bin','/usr/local/lib/qt5/bin'])
 +		try:
 +			lst=Utils.listdir('/usr/local/Trolltech/')
 +		except OSError:
@@ -11433,7 +11415,7 @@ Last-Update: 2014-11-28
 +		self.env.QMAKE=cand
 +	else:
 +		self.fatal('Could not find qmake for qt5')
-+	self.env.QT_INSTALL_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_BINS']).strip()+os.sep
++	self.env.QT_HOST_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_HOST_BINS']).strip()
 +	paths.insert(0,qtbin)
 +	def find_bin(lst,var):
 +		if var in env:
@@ -11460,83 +11442,85 @@ Last-Update: 2014-11-28
 +	find_bin(['rcc-qt5','rcc'],'QT_RCC')
 +	find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE')
 +	find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE')
-+	env['UIC_ST']='%s -o %s'
-+	env['MOC_ST']='-o'
-+	env['ui_PATTERN']='ui_%s.h'
-+	env['QT_LRELEASE_FLAGS']=['-silent']
++	env.UIC_ST='%s -o %s'
++	env.MOC_ST='-o'
++	env.ui_PATTERN='ui_%s.h'
++	env.QT_LRELEASE_FLAGS=['-silent']
 +	env.MOCCPPPATH_ST='-I%s'
 +	env.MOCDEFINES_ST='-D%s'
 + at conf
-+def find_qt5_libraries(self):
-+	qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT5_LIBDIR",None)
++def set_qt5_libs_dir(self):
++	env=self.env
++	qtlibs=getattr(Options.options,'qtlibs',None)or self.environ.get('QT5_LIBDIR')
 +	if not qtlibs:
 +		try:
-+			qtlibs=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
++			qtlibs=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
 +		except Errors.WafError:
-+			qtdir=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()+os.sep
++			qtdir=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()
 +			qtlibs=os.path.join(qtdir,'lib')
 +	self.msg('Found the Qt5 libraries in',qtlibs)
-+	qtincludes=os.environ.get("QT5_INCLUDES",None)or self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
++	env.QTLIBS=qtlibs
++ at conf
++def find_single_qt5_lib(self,name,uselib,qtlibs,qtincludes,force_static):
++	env=self.env
++	if force_static:
++		exts=('.a','.lib')
++		prefix='STLIB'
++	else:
++		exts=('.so','.lib')
++		prefix='LIB'
++	def lib_names():
++		for x in exts:
++			for k in('','5')if Utils.is_win32 else['']:
++				for p in('lib',''):
++					yield(p,name,k,x)
++		raise StopIteration
++	for tup in lib_names():
++		k=''.join(tup)
++		path=os.path.join(qtlibs,k)
++		if os.path.exists(path):
++			if env.DEST_OS=='win32':
++				libval=''.join(tup[:-1])
++			else:
++				libval=name
++			env.append_unique(prefix+'_'+uselib,libval)
++			env.append_unique('%sPATH_%s'%(prefix,uselib),qtlibs)
++			env.append_unique('INCLUDES_'+uselib,qtincludes)
++			env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,name.replace('Qt5','Qt')))
++			return k
++	return False
++ at conf
++def find_qt5_libraries(self):
 +	env=self.env
-+	if not'PKG_CONFIG_PATH'in os.environ:
-+		os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(qtlibs,qtlibs)
++	qtincludes=self.environ.get('QT5_INCLUDES')or self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
++	force_static=self.environ.get('QT5_FORCE_STATIC')
 +	try:
-+		if os.environ.get("QT5_XCOMPILE",None):
-+			raise self.errors.ConfigurationError()
++		if self.environ.get('QT5_XCOMPILE'):
++			self.fatal('QT5_XCOMPILE Disables pkg-config detection')
 +		self.check_cfg(atleast_pkgconfig_version='0.1')
 +	except self.errors.ConfigurationError:
 +		for i in self.qt5_vars:
 +			uselib=i.upper()
-+			if Utils.unversioned_sys_platform()=="darwin":
-+				frameworkName=i+".framework"
-+				qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
++			if Utils.unversioned_sys_platform()=='darwin':
++				frameworkName=i+'.framework'
++				qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,i)
 +				if os.path.exists(qtDynamicLib):
 +					env.append_unique('FRAMEWORK_'+uselib,i)
 +					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
 +				else:
 +					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
-+			elif env.DEST_OS!="win32":
-+				qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
-+				qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
-+				if os.path.exists(qtDynamicLib):
-+					env.append_unique('LIB_'+uselib,i)
-+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
-+				elif os.path.exists(qtStaticLib):
-+					env.append_unique('LIB_'+uselib,i)
-+					self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
++				env.append_unique('INCLUDES_'+uselib,os.path.join(env.QTLIBS,frameworkName,'Headers'))
 +			else:
-+				for k in("lib%s.a","lib%s5.a","%s.lib","%s5.lib"):
-+					lib=os.path.join(qtlibs,k%i)
-+					if os.path.exists(lib):
-+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
-+						self.msg('Checking for %s'%i,lib,'GREEN')
-+						break
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i.replace('Qt5','Qt')))
-+				uselib=i.upper()+"_debug"
-+				for k in("lib%sd.a","lib%sd5.a","%sd.lib","%sd5.lib"):
-+					lib=os.path.join(qtlibs,k%i)
-+					if os.path.exists(lib):
-+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
-+						self.msg('Checking for %s'%i,lib,'GREEN')
-+						break
-+				else:
-+					self.msg('Checking for %s'%i,False,'YELLOW')
-+				env.append_unique('LIBPATH_'+uselib,qtlibs)
-+				env.append_unique('INCLUDES_'+uselib,qtincludes)
-+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i.replace('Qt5','Qt')))
++				for j in('','d'):
++					k='_DEBUG'if j=='d'else''
++					ret=self.find_single_qt5_lib(i+j,uselib+k,env.QTLIBS,qtincludes,force_static)
++					if not force_static and not ret:
++						ret=self.find_single_qt5_lib(i+j,uselib+k,env.QTLIBS,qtincludes,True)
++					self.msg('Checking for %s'%(i+j),ret,'GREEN'if ret else'YELLOW')
 +	else:
++		path='%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(self.environ.get('PKG_CONFIG_PATH',''),env.QTLIBS,env.QTLIBS)
 +		for i in self.qt5_vars_debug+self.qt5_vars:
-+			self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
++			self.check_cfg(package=i,args='--cflags --libs',mandatory=False,force_static=force_static,pkg_config_path=path)
 + at conf
 +def simplify_qt5_libs(self):
 +	env=self.env
@@ -11577,11 +11561,26 @@ Last-Update: 2014-11-28
 +		process_rpath(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
 + at conf
 +def set_qt5_libs_to_check(self):
-+	if not hasattr(self,'qt5_vars'):
-+		self.qt5_vars=QT5_LIBS
-+	self.qt5_vars=Utils.to_list(self.qt5_vars)
++	self.qt5_vars=Utils.to_list(getattr(self,'qt5_vars',[]))
++	if not self.qt5_vars:
++		dirlst=Utils.listdir(self.env.QTLIBS)
++		pat=self.env.cxxshlib_PATTERN
++		if Utils.is_win32:
++			pat=pat.replace('.dll','.lib')
++		if self.environ.get('QT5_FORCE_STATIC'):
++			pat=self.env.cxxstlib_PATTERN
++		re_qt=re.compile(pat%'(?P<name>Qt5.*)'+'$')
++		for x in dirlst:
++			m=re_qt.match(x)
++			if m:
++				self.qt5_vars.append(m.group('name'))
++		if not self.qt5_vars:
++			self.fatal('cannot find any Qt5 library (%r)'%self.env.QTLIBS)
++	qtextralibs=getattr(Options.options,'qtextralibs',None)
++	if qtextralibs:
++		self.qt5_vars.extend(qtextralibs.split(','))
 +	if not hasattr(self,'qt5_vars_debug'):
-+		self.qt5_vars_debug=[a+'_debug'for a in self.qt5_vars]
++		self.qt5_vars_debug=[a+'_DEBUG'for a in self.qt5_vars]
 +	self.qt5_vars_debug=Utils.to_list(self.qt5_vars_debug)
 + at conf
 +def set_qt5_defines(self):
@@ -11593,23 +11592,23 @@ Last-Update: 2014-11-28
 +		self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
 +def options(opt):
 +	opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
-+	opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
 +	for i in'qtdir qtbin qtlibs'.split():
 +		opt.add_option('--'+i,type='string',default='',dest=i)
-+	opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt5",default=False)
++	opt.add_option('--translate',action='store_true',help='collect translation strings',dest='trans_qt5',default=False)
++	opt.add_option('--qtextralibs',type='string',default='',dest='qtextralibs',help='additional qt libraries on the system to add to default ones, comma separated')
 --- /dev/null
 +++ b/waflib/Tools/ruby.py
-@@ -0,0 +1,103 @@
+@@ -0,0 +1,97 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
 +import os
-+from waflib import Task,Options,Utils
-+from waflib.TaskGen import before_method,feature,after_method,Task,extension
++from waflib import Options,Utils,Task
++from waflib.TaskGen import before_method,feature,extension
 +from waflib.Configure import conf
 + at feature('rubyext')
-+ at before_method('apply_incpaths','apply_lib_vars','apply_bundle','apply_link')
++ at before_method('apply_incpaths','process_source','apply_bundle','apply_link')
 +def init_rubyext(self):
 +	self.install_path='${ARCHDIR_RUBY}'
 +	self.uselib=self.to_list(getattr(self,'uselib',''))
@@ -11618,16 +11617,12 @@ Last-Update: 2014-11-28
 +	if not'RUBYEXT'in self.uselib:
 +		self.uselib.append('RUBYEXT')
 + at feature('rubyext')
-+ at before_method('apply_link','propagate_uselib')
++ at before_method('apply_link','propagate_uselib_vars')
 +def apply_ruby_so_name(self):
-+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['rubyext_PATTERN']
++	self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.rubyext_PATTERN
 + at conf
 +def check_ruby_version(self,minver=()):
-+	if Options.options.rubybinary:
-+		self.env.RUBY=Options.options.rubybinary
-+	else:
-+		self.find_program('ruby',var='RUBY')
-+	ruby=self.env.RUBY
++	ruby=self.find_program('ruby',var='RUBY',value=Options.options.rubybinary)
 +	try:
 +		version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
 +	except Exception:
@@ -11639,12 +11634,10 @@ Last-Update: 2014-11-28
 +		self.fatal('unsupported ruby version %r'%version)
 +	cver=''
 +	if minver:
++		cver='> '+'.'.join(str(x)for x in minver)
 +		if ver<minver:
 +			self.fatal('ruby is too old %r'%ver)
-+		cver='.'.join([str(x)for x in minver])
-+	else:
-+		cver=ver
-+	self.msg('Checking for ruby version %s'%str(minver or''),cver)
++	self.msg('Checking for ruby version %s'%cver,version)
 + at conf
 +def check_ruby_ext_devel(self):
 +	if not self.env.RUBY:
@@ -11656,14 +11649,14 @@ Last-Update: 2014-11-28
 +		return Utils.to_list(self.cmd_and_log(self.env.RUBY+['-rrbconfig','-e',cmd]))
 +	def read_config(key):
 +		return read_out('puts RbConfig::CONFIG[%r]'%key)
-+	ruby=self.env['RUBY']
-+	archdir=read_config('archdir')
-+	cpppath=archdir
++	cpppath=archdir=read_config('archdir')
 +	if version>=(1,9,0):
 +		ruby_hdrdir=read_config('rubyhdrdir')
 +		cpppath+=ruby_hdrdir
++		if version>=(2,0,0):
++			cpppath+=read_config('rubyarchhdrdir')
 +		cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
-+	self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file')
++	self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file',link_header_test=False)
 +	self.env.LIBPATH_RUBYEXT=read_config('libdir')
 +	self.env.LIBPATH_RUBYEXT+=archdir
 +	self.env.INCLUDES_RUBYEXT=cpppath
@@ -11696,7 +11689,7 @@ Last-Update: 2014-11-28
 +	self.end_msg(True)
 + at extension('.rb')
 +def process(self,node):
-+	tsk=self.create_task('run_ruby',node)
++	return self.create_task('run_ruby',node)
 +class run_ruby(Task.Task):
 +	run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
 +def options(opt):
@@ -11710,7 +11703,6 @@ Last-Update: 2014-11-28
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+from waflib import Utils
 +from waflib.Tools import ccroot,ar
 +from waflib.Configure import conf
 + at conf
@@ -11726,26 +11718,27 @@ Last-Update: 2014-11-28
 + at conf
 +def scc_common_flags(conf):
 +	v=conf.env
-+	v['CC_SRC_F']=[]
-+	v['CC_TGT_F']=['-c','-o']
-+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
-+	v['CCLNK_SRC_F']=''
-+	v['CCLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['SONAME_ST']='-Wl,-h,%s'
-+	v['SHLIB_MARKER']='-Bdynamic'
-+	v['STLIB_MARKER']='-Bstatic'
-+	v['cprogram_PATTERN']='%s'
-+	v['CFLAGS_cshlib']=['-Kpic','-DPIC']
-+	v['LINKFLAGS_cshlib']=['-G']
-+	v['cshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cstlib']=['-Bstatic']
-+	v['cstlib_PATTERN']='lib%s.a'
++	v.CC_SRC_F=[]
++	v.CC_TGT_F=['-c','-o','']
++	if not v.LINK_CC:
++		v.LINK_CC=v.CC
++	v.CCLNK_SRC_F=''
++	v.CCLNK_TGT_F=['-o','']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.SONAME_ST='-Wl,-h,%s'
++	v.SHLIB_MARKER='-Bdynamic'
++	v.STLIB_MARKER='-Bstatic'
++	v.cprogram_PATTERN='%s'
++	v.CFLAGS_cshlib=['-xcode=pic32','-DPIC']
++	v.LINKFLAGS_cshlib=['-G']
++	v.cshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cstlib=['-Bstatic']
++	v.cstlib_PATTERN='lib%s.a'
 +def configure(conf):
 +	conf.find_scc()
 +	conf.find_ar()
@@ -11760,7 +11753,6 @@ Last-Update: 2014-11-28
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+from waflib import Utils
 +from waflib.Tools import ccroot,ar
 +from waflib.Configure import conf
 + at conf
@@ -11776,26 +11768,27 @@ Last-Update: 2014-11-28
 + at conf
 +def sxx_common_flags(conf):
 +	v=conf.env
-+	v['CXX_SRC_F']=[]
-+	v['CXX_TGT_F']=['-c','-o']
-+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
-+	v['CXXLNK_SRC_F']=[]
-+	v['CXXLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['SONAME_ST']='-Wl,-h,%s'
-+	v['SHLIB_MARKER']='-Bdynamic'
-+	v['STLIB_MARKER']='-Bstatic'
-+	v['cxxprogram_PATTERN']='%s'
-+	v['CXXFLAGS_cxxshlib']=['-Kpic','-DPIC']
-+	v['LINKFLAGS_cxxshlib']=['-G']
-+	v['cxxshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cxxstlib']=['-Bstatic']
-+	v['cxxstlib_PATTERN']='lib%s.a'
++	v.CXX_SRC_F=[]
++	v.CXX_TGT_F=['-c','-o','']
++	if not v.LINK_CXX:
++		v.LINK_CXX=v.CXX
++	v.CXXLNK_SRC_F=[]
++	v.CXXLNK_TGT_F=['-o','']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.SONAME_ST='-Wl,-h,%s'
++	v.SHLIB_MARKER='-Bdynamic'
++	v.STLIB_MARKER='-Bstatic'
++	v.cxxprogram_PATTERN='%s'
++	v.CXXFLAGS_cxxshlib=['-xcode=pic32','-DPIC']
++	v.LINKFLAGS_cxxshlib=['-G']
++	v.cxxshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cxxstlib=['-Bstatic']
++	v.cxxstlib_PATTERN='lib%s.a'
 +def configure(conf):
 +	conf.find_sxx()
 +	conf.find_ar()
@@ -11805,7 +11798,7 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/tex.py
-@@ -0,0 +1,318 @@
+@@ -0,0 +1,324 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -11823,13 +11816,13 @@ Last-Update: 2014-11-28
 +		path=match.group('file')
 +		if path:
 +			for k in('','.bib'):
-+				Logs.debug('tex: trying %s%s'%(path,k))
++				Logs.debug('tex: trying %s%s',path,k)
 +				fi=node.parent.find_resource(path+k)
 +				if fi:
 +					nodes.append(fi)
 +			else:
-+				Logs.debug('tex: could not find %s'%path)
-+	Logs.debug("tex: found the following bibunit files: %s"%nodes)
++				Logs.debug('tex: could not find %s',path)
++	Logs.debug('tex: found the following bibunit files: %s',nodes)
 +	return nodes
 +exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty']
 +exts_tex=['.ltx','.tex']
@@ -11850,14 +11843,9 @@ Last-Update: 2014-11-28
 +	Execute the program **makeglossaries**
 +	"""
 +	def exec_command(self,cmd,**kw):
-+		bld=self.generator.bld
-+		Logs.info('runner: %r'%cmd)
-+		try:
-+			if not kw.get('cwd',None):
-+				kw['cwd']=bld.cwd
-+		except AttributeError:
-+			bld.cwd=kw['cwd']=bld.variant_dir
-+		return Utils.subprocess.Popen(cmd,**kw).wait()
++		if self.env.PROMPT_LATEX:
++			kw['stdout']=kw['stderr']=None
++		return super(tex,self).exec_command(cmd,**kw)
 +	def scan_aux(self,node):
 +		nodes=[node]
 +		re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
@@ -11867,7 +11855,7 @@ Last-Update: 2014-11-28
 +				path=match.group('file')
 +				found=node.parent.find_or_declare(path)
 +				if found and found not in nodes:
-+					Logs.debug('tex: found aux node '+found.abspath())
++					Logs.debug('tex: found aux node %r',found)
 +					nodes.append(found)
 +					parse_node(found)
 +		parse_node(node)
@@ -11898,7 +11886,7 @@ Last-Update: 2014-11-28
 +						found=None
 +						for k in exts_deps_tex:
 +							for up in self.texinputs_nodes:
-+								Logs.debug('tex: trying %s%s'%(path,k))
++								Logs.debug('tex: trying %s%s',path,k)
 +								found=up.find_resource(path+k)
 +								if found:
 +									break
@@ -11922,20 +11910,26 @@ Last-Update: 2014-11-28
 +		parse_node(node)
 +		for x in nodes:
 +			x.parent.get_bld().mkdir()
-+		Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
++		Logs.debug("tex: found the following : %s and names %s",nodes,names)
 +		return(nodes,names)
 +	def check_status(self,msg,retcode):
 +		if retcode!=0:
-+			raise Errors.WafError("%r command exit status %r"%(msg,retcode))
++			raise Errors.WafError('%r command exit status %r'%(msg,retcode))
++	def info(self,*k,**kw):
++		try:
++			info=self.generator.bld.conf.logger.info
++		except AttributeError:
++			info=Logs.info
++		info(*k,**kw)
 +	def bibfile(self):
 +		for aux_node in self.aux_nodes:
 +			try:
 +				ct=aux_node.read()
 +			except EnvironmentError:
-+				Logs.error('Error reading %s: %r'%aux_node.abspath())
++				Logs.error('Error reading %s: %r',aux_node.abspath())
 +				continue
 +			if g_bibtex_re.findall(ct):
-+				Logs.info('calling bibtex')
++				self.info('calling bibtex')
 +				self.env.env={}
 +				self.env.env.update(os.environ)
 +				self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
@@ -11956,7 +11950,7 @@ Last-Update: 2014-11-28
 +			if bibunits:
 +				fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
 +				if fn:
-+					Logs.info('calling bibtex on bibunits')
++					self.info('calling bibtex on bibunits')
 +				for f in fn:
 +					self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
 +					self.env.SRCFILE=f
@@ -11967,9 +11961,9 @@ Last-Update: 2014-11-28
 +			idx_path=self.idx_node.abspath()
 +			os.stat(idx_path)
 +		except OSError:
-+			Logs.info('index file %s absent, not calling makeindex'%idx_path)
++			self.info('index file %s absent, not calling makeindex',idx_path)
 +		else:
-+			Logs.info('calling makeindex')
++			self.info('calling makeindex')
 +			self.env.SRCFILE=self.idx_node.name
 +			self.env.env={}
 +			self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
@@ -11985,7 +11979,7 @@ Last-Update: 2014-11-28
 +			try:
 +				ct=aux_node.read()
 +			except EnvironmentError:
-+				Logs.error('Error reading %s: %r'%aux_node.abspath())
++				Logs.error('Error reading %s: %r',aux_node.abspath())
 +				continue
 +			if g_glossaries_re.findall(ct):
 +				if not self.env.MAKEGLOSSARIES:
@@ -11998,12 +11992,12 @@ Last-Update: 2014-11-28
 +		return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep
 +	def run(self):
 +		env=self.env
-+		if not env['PROMPT_LATEX']:
++		if not env.PROMPT_LATEX:
 +			env.append_value('LATEXFLAGS','-interaction=batchmode')
 +			env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
 +			env.append_value('XELATEXFLAGS','-interaction=batchmode')
-+		self.cwd=self.inputs[0].parent.get_bld().abspath()
-+		Logs.info('first pass on %s'%self.__class__.__name__)
++		self.cwd=self.inputs[0].parent.get_bld()
++		self.info('first pass on %s',self.__class__.__name__)
 +		cur_hash=self.hash_aux_nodes()
 +		self.call_latex()
 +		self.hash_aux_nodes()
@@ -12019,11 +12013,11 @@ Last-Update: 2014-11-28
 +				Logs.error('No aux.h to process')
 +			if cur_hash and cur_hash==prev_hash:
 +				break
-+			Logs.info('calling %s'%self.__class__.__name__)
++			self.info('calling %s',self.__class__.__name__)
 +			self.call_latex()
 +	def hash_aux_nodes(self):
 +		try:
-+			nodes=self.aux_nodes
++			self.aux_nodes
 +		except AttributeError:
 +			try:
 +				self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
@@ -12059,9 +12053,14 @@ Last-Update: 2014-11-28
 +def apply_tex(self):
 +	if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
 +		self.type='pdflatex'
-+	tree=self.bld
 +	outs=Utils.to_list(getattr(self,'outs',[]))
-+	self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
++	try:
++		self.generator.bld.conf
++	except AttributeError:
++		default_prompt=False
++	else:
++		default_prompt=True
++	self.env.PROMPT_LATEX=getattr(self,'prompt',default_prompt)
 +	deps_lst=[]
 +	if getattr(self,'deps',None):
 +		deps=self.to_list(self.deps)
@@ -12102,9 +12101,9 @@ Last-Update: 2014-11-28
 +						if p:
 +							task.texinputs_nodes.append(p)
 +						else:
-+							Logs.error('Invalid TEXINPUTS folder %s'%x)
++							Logs.error('Invalid TEXINPUTS folder %s',x)
 +					else:
-+						Logs.error('Cannot resolve relative paths in TEXINPUTS %s'%x)
++						Logs.error('Cannot resolve relative paths in TEXINPUTS %s',x)
 +		if self.type=='latex':
 +			if'ps'in outs:
 +				tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
@@ -12123,16 +12122,16 @@ Last-Update: 2014-11-28
 +			self.find_program(p,var=p.upper())
 +		except self.errors.ConfigurationError:
 +			pass
-+	v['DVIPSFLAGS']='-Ppdf'
++	v.DVIPSFLAGS='-Ppdf'
 --- /dev/null
 +++ b/waflib/Tools/vala.py
-@@ -0,0 +1,201 @@
+@@ -0,0 +1,214 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os.path,shutil,re
-+from waflib import Context,Task,Utils,Logs,Options,Errors
++import re
++from waflib import Context,Task,Utils,Logs,Options,Errors,Node
 +from waflib.TaskGen import extension,taskgen_method
 +from waflib.Configure import conf
 +class valac(Task.Task):
@@ -12140,53 +12139,65 @@ Last-Update: 2014-11-28
 +	ext_out=['.h']
 +	def run(self):
 +		cmd=self.env.VALAC+self.env.VALAFLAGS
-+		cmd.extend([a.abspath()for a in self.inputs])
-+		ret=self.exec_command(cmd,cwd=self.outputs[0].parent.abspath())
++		resources=getattr(self,'vala_exclude',[])
++		cmd.extend([a.abspath()for a in self.inputs if a not in resources])
++		ret=self.exec_command(cmd,cwd=self.vala_dir_node.abspath())
 +		if ret:
 +			return ret
-+		for x in self.outputs:
-+			if id(x.parent)!=id(self.outputs[0].parent):
-+				shutil.move(self.outputs[0].parent.abspath()+os.sep+x.name,x.abspath())
 +		if self.generator.dump_deps_node:
 +			self.generator.dump_deps_node.write('\n'.join(self.generator.packages))
 +		return ret
-+valac=Task.update_outputs(valac)
 + at taskgen_method
 +def init_vala_task(self):
 +	self.profile=getattr(self,'profile','gobject')
++	self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
++	self.use=Utils.to_list(getattr(self,'use',[]))
++	if packages and not self.use:
++		self.use=packages[:]
 +	if self.profile=='gobject':
-+		self.uselib=Utils.to_list(getattr(self,'uselib',[]))
-+		if not'GOBJECT'in self.uselib:
-+			self.uselib.append('GOBJECT')
++		if not'GOBJECT'in self.use:
++			self.use.append('GOBJECT')
 +	def addflags(flags):
 +		self.env.append_value('VALAFLAGS',flags)
 +	if self.profile:
 +		addflags('--profile=%s'%self.profile)
++	valatask=self.valatask
++	if hasattr(self,'vala_dir'):
++		if isinstance(self.vala_dir,str):
++			valatask.vala_dir_node=self.path.get_bld().make_node(self.vala_dir)
++			try:
++				valatask.vala_dir_node.mkdir()
++			except OSError:
++				raise self.bld.fatal('Cannot create the vala dir %r'%valatask.vala_dir_node)
++		else:
++			valatask.vala_dir_node=self.vala_dir
++	else:
++		valatask.vala_dir_node=self.path.get_bld()
++	addflags('--directory=%s'%valatask.vala_dir_node.abspath())
 +	if hasattr(self,'thread'):
 +		if self.profile=='gobject':
-+			if not'GTHREAD'in self.uselib:
-+				self.uselib.append('GTHREAD')
++			if not'GTHREAD'in self.use:
++				self.use.append('GTHREAD')
 +		else:
-+			Logs.warn("Profile %s means no threading support"%self.profile)
++			Logs.warn('Profile %s means no threading support',self.profile)
 +			self.thread=False
 +		if self.thread:
 +			addflags('--thread')
-+	valatask=self.valatask
 +	self.is_lib='cprogram'not in self.features
 +	if self.is_lib:
 +		addflags('--library=%s'%self.target)
-+		h_node=self.path.find_or_declare('%s.h'%self.target)
++		h_node=valatask.vala_dir_node.find_or_declare('%s.h'%self.target)
 +		valatask.outputs.append(h_node)
 +		addflags('--header=%s'%h_node.name)
-+		valatask.outputs.append(self.path.find_or_declare('%s.vapi'%self.target))
++		valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi'%self.target))
 +		if getattr(self,'gir',None):
-+			gir_node=self.path.find_or_declare('%s.gir'%self.gir)
++			gir_node=valatask.vala_dir_node.find_or_declare('%s.gir'%self.gir)
 +			addflags('--gir=%s'%gir_node.name)
 +			valatask.outputs.append(gir_node)
 +	self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None))
 +	if self.vala_target_glib:
 +		addflags('--target-glib=%s'%self.vala_target_glib)
-+	addflags(['--define=%s'%x for x in getattr(self,'vala_defines',[])])
++	addflags(['--define=%s'%x for x in Utils.to_list(getattr(self,'vala_defines',[]))])
 +	packages_private=Utils.to_list(getattr(self,'packages_private',[]))
 +	addflags(['--pkg=%s'%x for x in packages_private])
 +	def _get_api_version():
@@ -12199,15 +12210,12 @@ Last-Update: 2014-11-28
 +				api_version=version[0]+".0"
 +		return api_version
 +	self.includes=Utils.to_list(getattr(self,'includes',[]))
-+	self.uselib=self.to_list(getattr(self,'uselib',[]))
 +	valatask.install_path=getattr(self,'install_path','')
 +	valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
-+	valatask.pkg_name=getattr(self,'pkg_name',self.env['PACKAGE'])
++	valatask.pkg_name=getattr(self,'pkg_name',self.env.PACKAGE)
 +	valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
 +	valatask.install_binding=getattr(self,'install_binding',True)
-+	self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
 +	self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
-+	includes=[]
 +	if hasattr(self,'use'):
 +		local_packages=Utils.to_list(self.use)[:]
 +		seen=[]
@@ -12221,58 +12229,56 @@ Last-Update: 2014-11-28
 +			except Errors.WafError:
 +				continue
 +			package_name=package_obj.target
-+			package_node=package_obj.path
-+			package_dir=package_node.path_from(self.path)
 +			for task in package_obj.tasks:
 +				for output in task.outputs:
 +					if output.name==package_name+".vapi":
 +						valatask.set_run_after(task)
 +						if package_name not in packages:
 +							packages.append(package_name)
-+						if package_dir not in vapi_dirs:
-+							vapi_dirs.append(package_dir)
-+						if package_dir not in includes:
-+							includes.append(package_dir)
++						if output.parent not in vapi_dirs:
++							vapi_dirs.append(output.parent)
++						if output.parent not in self.includes:
++							self.includes.append(output.parent)
 +			if hasattr(package_obj,'use'):
 +				lst=self.to_list(package_obj.use)
 +				lst.reverse()
 +				local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
 +	addflags(['--pkg=%s'%p for p in packages])
 +	for vapi_dir in vapi_dirs:
-+		v_node=self.path.find_dir(vapi_dir)
++		if isinstance(vapi_dir,Node.Node):
++			v_node=vapi_dir
++		else:
++			v_node=self.path.find_dir(vapi_dir)
 +		if not v_node:
-+			Logs.warn('Unable to locate Vala API directory: %r'%vapi_dir)
++			Logs.warn('Unable to locate Vala API directory: %r',vapi_dir)
 +		else:
 +			addflags('--vapidir=%s'%v_node.abspath())
-+			addflags('--vapidir=%s'%v_node.get_bld().abspath())
 +	self.dump_deps_node=None
 +	if self.is_lib and self.packages:
-+		self.dump_deps_node=self.path.find_or_declare('%s.deps'%self.target)
++		self.dump_deps_node=valatask.vala_dir_node.find_or_declare('%s.deps'%self.target)
 +		valatask.outputs.append(self.dump_deps_node)
-+	self.includes.append(self.bld.srcnode.abspath())
-+	self.includes.append(self.bld.bldnode.abspath())
-+	for include in includes:
-+		try:
-+			self.includes.append(self.path.find_dir(include).abspath())
-+			self.includes.append(self.path.find_dir(include).get_bld().abspath())
-+		except AttributeError:
-+			Logs.warn("Unable to locate include directory: '%s'"%include)
 +	if self.is_lib and valatask.install_binding:
 +		headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
 +		try:
 +			self.install_vheader.source=headers_list
 +		except AttributeError:
-+			self.install_vheader=self.bld.install_files(valatask.header_path,headers_list,self.env)
++			self.install_vheader=self.add_install_files(install_to=valatask.header_path,install_from=headers_list)
 +		vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
 +		try:
 +			self.install_vapi.source=vapi_list
 +		except AttributeError:
-+			self.install_vapi=self.bld.install_files(valatask.vapi_path,vapi_list,self.env)
++			self.install_vapi=self.add_install_files(install_to=valatask.vapi_path,install_from=vapi_list)
 +		gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
 +		try:
 +			self.install_gir.source=gir_list
 +		except AttributeError:
-+			self.install_gir=self.bld.install_files(getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),gir_list,self.env)
++			self.install_gir=self.add_install_files(install_to=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),install_from=gir_list)
++	if hasattr(self,'vala_resources'):
++		nodes=self.to_nodes(self.vala_resources)
++		valatask.vala_exclude=getattr(valatask,'vala_exclude',[])+nodes
++		valatask.inputs.extend(nodes)
++		for x in nodes:
++			addflags(['--gresources',x.abspath()])
 + at extension('.vala','.gs')
 +def vala_file(self,node):
 +	try:
@@ -12281,7 +12287,8 @@ Last-Update: 2014-11-28
 +		valatask=self.valatask=self.create_task('valac')
 +		self.init_vala_task()
 +	valatask.inputs.append(node)
-+	c_node=node.change_ext('.c')
++	name=node.name[:node.name.rfind('.')]+'.c'
++	c_node=valatask.vala_dir_node.find_or_declare(name)
 +	valatask.outputs.append(c_node)
 +	self.source.append(c_node)
 + at conf
@@ -12292,15 +12299,19 @@ Last-Update: 2014-11-28
 +	except Exception:
 +		valac_version=None
 +	else:
-+		ver=re.search(r'\d+.\d+.\d+',output).group(0).split('.')
++		ver=re.search(r'\d+.\d+.\d+',output).group().split('.')
 +		valac_version=tuple([int(x)for x in ver])
 +	self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
 +	if valac and valac_version<min_version:
 +		self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
-+	self.env['VALAC_VERSION']=valac_version
++	self.env.VALAC_VERSION=valac_version
 +	return valac
 + at conf
 +def check_vala(self,min_version=(0,8,0),branch=None):
++	if self.env.VALA_MINVER:
++		min_version=self.env.VALA_MINVER
++	if self.env.VALA_MINVER_BRANCH:
++		branch=self.env.VALA_MINVER_BRANCH
 +	if not branch:
 +		branch=min_version[:2]
 +	try:
@@ -12309,12 +12320,12 @@ Last-Update: 2014-11-28
 +		find_valac(self,'valac',min_version)
 + at conf
 +def check_vala_deps(self):
-+	if not self.env['HAVE_GOBJECT']:
++	if not self.env.HAVE_GOBJECT:
 +		pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
 +		if getattr(Options.options,'vala_target_glib',None):
 +			pkg_args['atleast_version']=Options.options.vala_target_glib
 +		self.check_cfg(**pkg_args)
-+	if not self.env['HAVE_GTHREAD']:
++	if not self.env.HAVE_GTHREAD:
 +		pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
 +		if getattr(Options.options,'vala_target_glib',None):
 +			pkg_args['atleast_version']=Options.options.vala_target_glib
@@ -12323,27 +12334,72 @@ Last-Update: 2014-11-28
 +	self.load('gnu_dirs')
 +	self.check_vala_deps()
 +	self.check_vala()
-+	self.env.VALAFLAGS=['-C','--quiet']
++	self.add_os_flags('VALAFLAGS')
++	self.env.append_unique('VALAFLAGS',['-C'])
 +def options(opt):
 +	opt.load('gnu_dirs')
 +	valaopts=opt.add_option_group('Vala Compiler Options')
 +	valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
 --- /dev/null
 +++ b/waflib/Tools/waf_unit_test.py
-@@ -0,0 +1,101 @@
+@@ -0,0 +1,143 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os
++import os,sys
 +from waflib.TaskGen import feature,after_method,taskgen_method
 +from waflib import Utils,Task,Logs,Options
++from waflib.Tools import ccroot
 +testlock=Utils.threading.Lock()
++SCRIPT_TEMPLATE="""#! %(python)s
++import subprocess, sys
++cmd = %(cmd)r
++# if you want to debug with gdb:
++#cmd = ['gdb', '-args'] + cmd
++env = %(env)r
++status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str))
++sys.exit(status)
++"""
 + at feature('test')
-+ at after_method('apply_link')
++ at after_method('apply_link','process_use')
 +def make_test(self):
-+	if getattr(self,'link_task',None):
-+		self.create_task('utest',self.link_task.outputs)
++	if not getattr(self,'link_task',None):
++		return
++	tsk=self.create_task('utest',self.link_task.outputs)
++	if getattr(self,'ut_str',None):
++		self.ut_run,lst=Task.compile_fun(self.ut_str,shell=getattr(self,'ut_shell',False))
++		tsk.vars=lst+tsk.vars
++	if getattr(self,'ut_cwd',None):
++		if isinstance(self.ut_cwd,str):
++			if os.path.isabs(self.ut_cwd):
++				self.ut_cwd=self.bld.root.make_node(self.ut_cwd)
++			else:
++				self.ut_cwd=self.path.make_node(self.ut_cwd)
++	else:
++		self.ut_cwd=tsk.inputs[0].parent
++	if not hasattr(self,'ut_paths'):
++		paths=[]
++		for x in self.tmp_use_sorted:
++			try:
++				y=self.bld.get_tgen_by_name(x).link_task
++			except AttributeError:
++				pass
++			else:
++				if not isinstance(y,ccroot.stlink_task):
++					paths.append(y.outputs[0].parent.abspath())
++		self.ut_paths=os.pathsep.join(paths)+os.pathsep
++	if not hasattr(self,'ut_env'):
++		self.ut_env=dct=dict(os.environ)
++		def add_path(var):
++			dct[var]=self.ut_paths+dct.get(var,'')
++		if Utils.is_win32:
++			add_path('PATH')
++		elif Utils.unversioned_sys_platform()=='darwin':
++			add_path('DYLD_LIBRARY_PATH')
++			add_path('LD_LIBRARY_PATH')
++		else:
++			add_path('LD_LIBRARY_PATH')
 + at taskgen_method
 +def add_test_results(self,tup):
 +	Logs.debug("ut: %r",tup)
@@ -12364,46 +12420,42 @@ Last-Update: 2014-11-28
 +			if getattr(Options.options,'all_tests',False):
 +				return Task.RUN_ME
 +		return ret
-+	def add_path(self,dct,path,var):
-+		dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
 +	def get_test_env(self):
-+		try:
-+			fu=getattr(self.generator.bld,'all_test_paths')
-+		except AttributeError:
-+			fu=os.environ.copy()
-+			lst=[]
-+			for g in self.generator.bld.groups:
-+				for tg in g:
-+					if getattr(tg,'link_task',None):
-+						s=tg.link_task.outputs[0].parent.abspath()
-+						if s not in lst:
-+							lst.append(s)
-+			if Utils.is_win32:
-+				self.add_path(fu,lst,'PATH')
-+			elif Utils.unversioned_sys_platform()=='darwin':
-+				self.add_path(fu,lst,'DYLD_LIBRARY_PATH')
-+				self.add_path(fu,lst,'LD_LIBRARY_PATH')
-+			else:
-+				self.add_path(fu,lst,'LD_LIBRARY_PATH')
-+			self.generator.bld.all_test_paths=fu
-+		return fu
++		return self.generator.ut_env
++	def post_run(self):
++		super(utest,self).post_run()
++		if getattr(Options.options,'clear_failed_tests',False)and self.waf_unit_test_results[1]:
++			self.generator.bld.task_sigs[self.uid()]=None
 +	def run(self):
-+		filename=self.inputs[0].abspath()
-+		self.ut_exec=getattr(self.generator,'ut_exec',[filename])
++		if hasattr(self.generator,'ut_run'):
++			return self.generator.ut_run(self)
++		self.ut_exec=getattr(self.generator,'ut_exec',[self.inputs[0].abspath()])
 +		if getattr(self.generator,'ut_fun',None):
 +			self.generator.ut_fun(self)
-+		cwd=getattr(self.generator,'ut_cwd','')or self.inputs[0].parent.abspath()
 +		testcmd=getattr(self.generator,'ut_cmd',False)or getattr(Options.options,'testcmd',False)
 +		if testcmd:
-+			self.ut_exec=(testcmd%self.ut_exec[0]).split(' ')
-+		proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
++			self.ut_exec=(testcmd%' '.join(self.ut_exec)).split(' ')
++		return self.exec_command(self.ut_exec)
++	def exec_command(self,cmd,**kw):
++		Logs.debug('runner: %r',cmd)
++		if getattr(Options.options,'dump_test_scripts',False):
++			global SCRIPT_TEMPLATE
++			script_code=SCRIPT_TEMPLATE%{'python':sys.executable,'env':self.get_test_env(),'cwd':self.get_cwd().abspath(),'cmd':cmd}
++			script_file=self.inputs[0].abspath()+'_run.py'
++			Utils.writef(script_file,script_code)
++			os.chmod(script_file,Utils.O755)
++			if Logs.verbose>1:
++				Logs.info('Test debug file written as %r'%script_file)
++		proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
 +		(stdout,stderr)=proc.communicate()
-+		tup=(filename,proc.returncode,stdout,stderr)
++		self.waf_unit_test_results=tup=(self.inputs[0].abspath(),proc.returncode,stdout,stderr)
 +		testlock.acquire()
 +		try:
 +			return self.generator.add_test_results(tup)
 +		finally:
 +			testlock.release()
++	def get_cwd(self):
++		return self.generator.ut_cwd
 +def summary(bld):
 +	lst=getattr(bld,'utest_results',[])
 +	if lst:
@@ -12431,22 +12483,24 @@ Last-Update: 2014-11-28
 +def options(opt):
 +	opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
 +	opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
++	opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests')
 +	opt.add_option('--testcmd',action='store',default=False,help='Run the unit tests using the test-cmd string'' example "--test-cmd="valgrind --error-exitcode=1'' %s" to run under valgrind',dest='testcmd')
++	opt.add_option('--dump-test-scripts',action='store_true',default=False,help='Create python scripts to help debug tests',dest='dump_test_scripts')
 --- /dev/null
 +++ b/waflib/Tools/winres.py
-@@ -0,0 +1,85 @@
+@@ -0,0 +1,51 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import re,traceback
-+from waflib import Task,Logs,Utils
++import re
++from waflib import Task
 +from waflib.TaskGen import extension
 +from waflib.Tools import c_preproc
 + at extension('.rc')
 +def rc_file(self,node):
 +	obj_ext='.rc.o'
-+	if self.env['WINRC_TGT_F']=='/fo':
++	if self.env.WINRC_TGT_F=='/fo':
 +		obj_ext='.res'
 +	rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
 +	try:
@@ -12455,8 +12509,8 @@ Last-Update: 2014-11-28
 +		self.compiled_tasks=[rctask]
 +re_lines=re.compile('(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|''(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE)
 +class rc_parser(c_preproc.c_parser):
-+	def filter_comments(self,filepath):
-+		code=Utils.readf(filepath)
++	def filter_comments(self,node):
++		code=node.read()
 +		if c_preproc.use_trigraphs:
 +			for(a,b)in c_preproc.trig_def:code=code.split(a).join(b)
 +		code=c_preproc.re_nl.sub('',code)
@@ -12468,61 +12522,27 @@ Last-Update: 2014-11-28
 +			else:
 +				ret.append(('include',m.group(5)))
 +		return ret
-+	def addlines(self,node):
-+		self.currentnode_stack.append(node.parent)
-+		filepath=node.abspath()
-+		self.count_files+=1
-+		if self.count_files>c_preproc.recursion_limit:
-+			raise c_preproc.PreprocError("recursion limit exceeded")
-+		pc=self.parse_cache
-+		Logs.debug('preproc: reading file %r',filepath)
-+		try:
-+			lns=pc[filepath]
-+		except KeyError:
-+			pass
-+		else:
-+			self.lines.extend(lns)
-+			return
-+		try:
-+			lines=self.filter_comments(filepath)
-+			lines.append((c_preproc.POPFILE,''))
-+			lines.reverse()
-+			pc[filepath]=lines
-+			self.lines.extend(lines)
-+		except IOError:
-+			raise c_preproc.PreprocError("could not read the file %s"%filepath)
-+		except Exception:
-+			if Logs.verbose>0:
-+				Logs.error("parsing %s failed"%filepath)
-+				traceback.print_exc()
 +class winrc(Task.Task):
 +	run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
 +	color='BLUE'
 +	def scan(self):
 +		tmp=rc_parser(self.generator.includes_nodes)
 +		tmp.start(self.inputs[0],self.env)
-+		nodes=tmp.nodes
-+		names=tmp.names
-+		if Logs.verbose:
-+			Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(self),nodes,names))
-+		return(nodes,names)
++		return(tmp.nodes,tmp.names)
 +def configure(conf):
 +	v=conf.env
-+	v['WINRC_TGT_F']='-o'
-+	v['WINRC_SRC_F']='-i'
-+	if not conf.env.WINRC:
++	if not v.WINRC:
 +		if v.CC_NAME=='msvc':
-+			conf.find_program('RC',var='WINRC',path_list=v['PATH'])
-+			v['WINRC_TGT_F']='/fo'
-+			v['WINRC_SRC_F']=''
-+		else:
-+			conf.find_program('windres',var='WINRC',path_list=v['PATH'])
-+	if not conf.env.WINRC:
-+		conf.fatal('winrc was not found!')
-+	v['WINRCFLAGS']=[]
++			conf.find_program('RC',var='WINRC',path_list=v.PATH)
++			v.WINRC_TGT_F='/fo'
++			v.WINRC_SRC_F=''
++		else:
++			conf.find_program('windres',var='WINRC',path_list=v.PATH)
++			v.WINRC_TGT_F='-o'
++			v.WINRC_SRC_F='-i'
 --- /dev/null
 +++ b/waflib/Tools/xlc.py
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,44 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -12537,28 +12557,29 @@ Last-Update: 2014-11-28
 + at conf
 +def xlc_common_flags(conf):
 +	v=conf.env
-+	v['CC_SRC_F']=[]
-+	v['CC_TGT_F']=['-c','-o']
-+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
-+	v['CCLNK_SRC_F']=[]
-+	v['CCLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['RPATH_ST']='-Wl,-rpath,%s'
-+	v['SONAME_ST']=[]
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
-+	v['cprogram_PATTERN']='%s'
-+	v['CFLAGS_cshlib']=['-fPIC']
-+	v['LINKFLAGS_cshlib']=['-G','-Wl,-brtl,-bexpfull']
-+	v['cshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cstlib']=[]
-+	v['cstlib_PATTERN']='lib%s.a'
++	v.CC_SRC_F=[]
++	v.CC_TGT_F=['-c','-o']
++	if not v.LINK_CC:
++		v.LINK_CC=v.CC
++	v.CCLNK_SRC_F=[]
++	v.CCLNK_TGT_F=['-o']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.RPATH_ST='-Wl,-rpath,%s'
++	v.SONAME_ST=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.LINKFLAGS_cprogram=['-Wl,-brtl']
++	v.cprogram_PATTERN='%s'
++	v.CFLAGS_cshlib=['-fPIC']
++	v.LINKFLAGS_cshlib=['-G','-Wl,-brtl,-bexpfull']
++	v.cshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cstlib=[]
++	v.cstlib_PATTERN='lib%s.a'
 +def configure(conf):
 +	conf.find_xlc()
 +	conf.find_ar()
@@ -12568,7 +12589,7 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Tools/xlcxx.py
-@@ -0,0 +1,43 @@
+@@ -0,0 +1,44 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -12583,28 +12604,29 @@ Last-Update: 2014-11-28
 + at conf
 +def xlcxx_common_flags(conf):
 +	v=conf.env
-+	v['CXX_SRC_F']=[]
-+	v['CXX_TGT_F']=['-c','-o']
-+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
-+	v['CXXLNK_SRC_F']=[]
-+	v['CXXLNK_TGT_F']=['-o']
-+	v['CPPPATH_ST']='-I%s'
-+	v['DEFINES_ST']='-D%s'
-+	v['LIB_ST']='-l%s'
-+	v['LIBPATH_ST']='-L%s'
-+	v['STLIB_ST']='-l%s'
-+	v['STLIBPATH_ST']='-L%s'
-+	v['RPATH_ST']='-Wl,-rpath,%s'
-+	v['SONAME_ST']=[]
-+	v['SHLIB_MARKER']=[]
-+	v['STLIB_MARKER']=[]
-+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
-+	v['cxxprogram_PATTERN']='%s'
-+	v['CXXFLAGS_cxxshlib']=['-fPIC']
-+	v['LINKFLAGS_cxxshlib']=['-G','-Wl,-brtl,-bexpfull']
-+	v['cxxshlib_PATTERN']='lib%s.so'
-+	v['LINKFLAGS_cxxstlib']=[]
-+	v['cxxstlib_PATTERN']='lib%s.a'
++	v.CXX_SRC_F=[]
++	v.CXX_TGT_F=['-c','-o']
++	if not v.LINK_CXX:
++		v.LINK_CXX=v.CXX
++	v.CXXLNK_SRC_F=[]
++	v.CXXLNK_TGT_F=['-o']
++	v.CPPPATH_ST='-I%s'
++	v.DEFINES_ST='-D%s'
++	v.LIB_ST='-l%s'
++	v.LIBPATH_ST='-L%s'
++	v.STLIB_ST='-l%s'
++	v.STLIBPATH_ST='-L%s'
++	v.RPATH_ST='-Wl,-rpath,%s'
++	v.SONAME_ST=[]
++	v.SHLIB_MARKER=[]
++	v.STLIB_MARKER=[]
++	v.LINKFLAGS_cxxprogram=['-Wl,-brtl']
++	v.cxxprogram_PATTERN='%s'
++	v.CXXFLAGS_cxxshlib=['-fPIC']
++	v.LINKFLAGS_cxxshlib=['-G','-Wl,-brtl,-bexpfull']
++	v.cxxshlib_PATTERN='lib%s.so'
++	v.LINKFLAGS_cxxstlib=[]
++	v.cxxstlib_PATTERN='lib%s.a'
 +def configure(conf):
 +	conf.find_xlcxx()
 +	conf.find_ar()
@@ -12614,13 +12636,28 @@ Last-Update: 2014-11-28
 +	conf.link_add_flags()
 --- /dev/null
 +++ b/waflib/Utils.py
-@@ -0,0 +1,441 @@
+@@ -0,0 +1,597 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
 +
-+import os,sys,errno,traceback,inspect,re,shutil,datetime,gc,platform
-+import subprocess
++import atexit,os,sys,errno,traceback,inspect,re,datetime,platform,base64,signal,functools
++try:
++	import cPickle
++except ImportError:
++	import pickle as cPickle
++if os.name=='posix'and sys.version_info[0]<3:
++	try:
++		import subprocess32 as subprocess
++	except ImportError:
++		import subprocess
++else:
++	import subprocess
++try:
++	TimeoutExpired=subprocess.TimeoutExpired
++except AttributeError:
++	class TimeoutExpired(object):
++		pass
 +from collections import deque,defaultdict
 +try:
 +	import _winreg as winreg
@@ -12631,10 +12668,6 @@ Last-Update: 2014-11-28
 +		winreg=None
 +from waflib import Errors
 +try:
-+	from collections import UserDict
-+except ImportError:
-+	from UserDict import UserDict
-+try:
 +	from hashlib import md5
 +except ImportError:
 +	try:
@@ -12654,49 +12687,78 @@ Last-Update: 2014-11-28
 +		def release(self):
 +			pass
 +	threading.Lock=threading.Thread=Lock
-+else:
-+	run_old=threading.Thread.run
-+	def run(*args,**kwargs):
-+		try:
-+			run_old(*args,**kwargs)
-+		except(KeyboardInterrupt,SystemExit):
-+			raise
-+		except Exception:
-+			sys.excepthook(*sys.exc_info())
-+	threading.Thread.run=run
-+SIG_NIL='iluvcuteoverload'
++SIG_NIL='SIG_NIL_SIG_NIL_'
 +O644=420
 +O755=493
 +rot_chr=['\\','|','/','-']
 +rot_idx=0
-+try:
-+	from collections import OrderedDict as ordered_iter_dict
-+except ImportError:
-+	class ordered_iter_dict(dict):
-+		def __init__(self,*k,**kw):
-+			self.lst=[]
-+			dict.__init__(self,*k,**kw)
-+		def clear(self):
-+			dict.clear(self)
-+			self.lst=[]
-+		def __setitem__(self,key,value):
-+			dict.__setitem__(self,key,value)
-+			try:
-+				self.lst.remove(key)
-+			except ValueError:
-+				pass
-+			self.lst.append(key)
-+		def __delitem__(self,key):
-+			dict.__delitem__(self,key)
-+			try:
-+				self.lst.remove(key)
-+			except ValueError:
-+				pass
-+		def __iter__(self):
-+			for x in self.lst:
-+				yield x
-+		def keys(self):
-+			return self.lst
++class ordered_iter_dict(dict):
++	def __init__(self,*k,**kw):
++		self.lst=deque()
++		dict.__init__(self,*k,**kw)
++	def clear(self):
++		dict.clear(self)
++		self.lst=deque()
++	def __setitem__(self,key,value):
++		if key in dict.keys(self):
++			self.lst.remove(key)
++		dict.__setitem__(self,key,value)
++		self.lst.append(key)
++	def __delitem__(self,key):
++		dict.__delitem__(self,key)
++		try:
++			self.lst.remove(key)
++		except ValueError:
++			pass
++	def __iter__(self):
++		return reversed(self.lst)
++	def keys(self):
++		return reversed(self.lst)
++class lru_node(object):
++	__slots__=('next','prev','key','val')
++	def __init__(self):
++		self.next=self
++		self.prev=self
++		self.key=None
++		self.val=None
++class lru_cache(object):
++	__slots__=('maxlen','table','head')
++	def __init__(self,maxlen=100):
++		self.maxlen=maxlen
++		self.table={}
++		self.head=lru_node()
++		self.head.next=self.head
++		self.head.prev=self.head
++	def __getitem__(self,key):
++		node=self.table[key]
++		if node is self.head:
++			return node.val
++		node.prev.next=node.next
++		node.next.prev=node.prev
++		node.next=self.head.next
++		node.prev=self.head
++		self.head=node.next.prev=node.prev.next=node
++		return node.val
++	def __setitem__(self,key,val):
++		if key in self.table:
++			node=self.table[key]
++			node.val=val
++			self.__getitem__(key)
++		else:
++			if len(self.table)<self.maxlen:
++				node=lru_node()
++				node.prev=self.head
++				node.next=self.head.next
++				node.prev.next=node.next.prev=node
++			else:
++				node=self.head=self.head.next
++				try:
++					del self.table[node.key]
++				except KeyError:
++					pass
++			node.key=key
++			node.val=val
++			self.table[key]=node
 +is_win32=os.sep=='\\'or sys.platform=='win32'
 +def readf(fname,m='r',encoding='ISO8859-1'):
 +	if sys.hexversion>0x3000000 and not'b'in m:
@@ -12776,7 +12838,7 @@ Last-Update: 2014-11-28
 +	try:
 +		fd=os.open(f,flags)
 +	except OSError:
-+		raise IOError('Cannot write to %r'%f)
++		raise OSError('Cannot write to %r'%f)
 +	f=os.fdopen(fd,m)
 +	try:
 +		f.write(data)
@@ -12786,7 +12848,7 @@ Last-Update: 2014-11-28
 +	try:
 +		fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
 +	except OSError:
-+		raise IOError('Cannot read from %r'%fname)
++		raise OSError('Cannot read from %r'%fname)
 +	f=os.fdopen(fd,'rb')
 +	m=md5()
 +	try:
@@ -12826,7 +12888,7 @@ Last-Update: 2014-11-28
 +		try:
 +			import ctypes
 +		except ImportError:
-+			return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
++			return[x+':\\'for x in'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
 +		else:
 +			dlen=4
 +			maxdrives=26
@@ -12854,14 +12916,12 @@ Last-Update: 2014-11-28
 +		return ret
 +	return ver
 +def ex_stack():
-+	exc_type,exc_value,tb=sys.exc_info()
-+	exc_lines=traceback.format_exception(exc_type,exc_value,tb)
-+	return''.join(exc_lines)
-+def to_list(sth):
-+	if isinstance(sth,str):
-+		return sth.split()
++	return traceback.format_exc()
++def to_list(val):
++	if isinstance(val,str):
++		return val.split()
 +	else:
-+		return sth
++		return val
 +def split_path_unix(path):
 +	return path.split('/')
 +def split_path_cygwin(path):
@@ -12870,25 +12930,37 @@ Last-Update: 2014-11-28
 +		ret[0]='/'+ret[0]
 +		return ret
 +	return path.split('/')
-+re_sp=re.compile('[/\\\\]')
++re_sp=re.compile('[/\\\\]+')
 +def split_path_win32(path):
 +	if path.startswith('\\\\'):
-+		ret=re.split(re_sp,path)[2:]
++		ret=re_sp.split(path)[2:]
 +		ret[0]='\\'+ret[0]
 +		return ret
-+	return re.split(re_sp,path)
++	return re_sp.split(path)
++msysroot=None
++def split_path_msys(path):
++	if path.startswith(('/','\\'))and not path.startswith(('\\','\\\\')):
++		global msysroot
++		if not msysroot:
++			msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'iso8859-1')
++			msysroot=msysroot.strip()
++		path=os.path.normpath(msysroot+os.sep+path)
++	return split_path_win32(path)
 +if sys.platform=='cygwin':
 +	split_path=split_path_cygwin
 +elif is_win32:
-+	split_path=split_path_win32
++	if os.environ.get('MSYSTEM'):
++		split_path=split_path_msys
++	else:
++		split_path=split_path_win32
 +else:
 +	split_path=split_path_unix
 +split_path.__doc__="""
-+Split a path by / or \\. This function is not like os.path.split
++Splits a path by / or \\; do not confuse this function with with ``os.path.split``
 +
 +:type  path: string
 +:param path: path to split
-+:return:     list of strings
++:return:     list of string
 +"""
 +def check_dir(path):
 +	if not os.path.isdir(path):
@@ -12907,7 +12979,7 @@ Last-Update: 2014-11-28
 +		return os.path.abspath(name)
 +	else:
 +		env=env or os.environ
-+		for path in env["PATH"].split(os.pathsep):
++		for path in env['PATH'].split(os.pathsep):
 +			path=path.strip('"')
 +			exe_file=os.path.join(path,name)
 +			if is_exe(exe_file):
@@ -12923,22 +12995,36 @@ Last-Update: 2014-11-28
 +	fu=fu.upper()
 +	return fu
 +def h_list(lst):
-+	m=md5()
-+	m.update(str(lst))
-+	return m.digest()
++	return md5(repr(lst)).digest()
 +def h_fun(fun):
 +	try:
 +		return fun.code
 +	except AttributeError:
++		if isinstance(fun,functools.partial):
++			code=list(fun.args)
++			code.extend(sorted(fun.keywords.items()))
++			code.append(h_fun(fun.func))
++			fun.code=h_list(code)
++			return fun.code
 +		try:
 +			h=inspect.getsource(fun)
-+		except IOError:
-+			h="nocode"
++		except EnvironmentError:
++			h='nocode'
 +		try:
 +			fun.code=h
 +		except AttributeError:
 +			pass
 +		return h
++def h_cmd(ins):
++	if isinstance(ins,str):
++		ret=ins
++	elif isinstance(ins,list)or isinstance(ins,tuple):
++		ret=str([h_cmd(x)for x in ins])
++	else:
++		ret=str(h_fun(ins))
++	if sys.hexversion>0x3000000:
++		ret=ret.encode('iso8859-1','xmlcharrefreplace')
++	return ret
 +reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
 +def subst_vars(expr,params):
 +	def repl_var(m):
@@ -12977,6 +13063,8 @@ Last-Update: 2014-11-28
 +		return'darwin'
 +	if s=='win32'or s=='os2':
 +		return s
++	if s=='cli'and os.name=='nt':
++		return'win32'
 +	return re.split('\d+$',s)[0]
 +def nada(*k,**kw):
 +	pass
@@ -12997,18 +13085,6 @@ Last-Update: 2014-11-28
 +		if days or hours or minutes:
 +			result+='%dm'%minutes
 +		return'%s%.3fs'%(result,seconds)
-+if is_win32:
-+	old=shutil.copy2
-+	def copy2(src,dst):
-+		old(src,dst)
-+		shutil.copystat(src,dst)
-+	setattr(shutil,'copy2',copy2)
-+if os.name=='java':
-+	try:
-+		gc.disable()
-+		gc.enable()
-+	except NotImplementedError:
-+		gc.disable=gc.enable
 +def read_la_file(path):
 +	sp=re.compile(r'^([^=]+)=\'(.*)\'$')
 +	dc={}
@@ -13019,26 +13095,17 @@ Last-Update: 2014-11-28
 +		except ValueError:
 +			pass
 +	return dc
-+def nogc(fun):
-+	def f(*k,**kw):
-+		try:
-+			gc.disable()
-+			ret=fun(*k,**kw)
-+		finally:
-+			gc.enable()
-+		return ret
-+	f.__doc__=fun.__doc__
-+	return f
 +def run_once(fun):
 +	cache={}
-+	def wrap(k):
++	def wrap(*k):
 +		try:
 +			return cache[k]
 +		except KeyError:
-+			ret=fun(k)
++			ret=fun(*k)
 +			cache[k]=ret
 +			return ret
 +	wrap.__cache__=cache
++	wrap.__name__=fun.__name__
 +	return wrap
 +def get_registry_app_path(key,filename):
 +	if not winreg:
@@ -13056,6 +13123,117 @@ Last-Update: 2014-11-28
 +			if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'):
 +				return'64'
 +	return''
++def sane_path(p):
++	return os.path.abspath(os.path.expanduser(p))
++process_pool=[]
++def get_process():
++	try:
++		return process_pool.pop()
++	except IndexError:
++		filepath=os.path.dirname(os.path.abspath(__file__))+os.sep+'processor.py'
++		cmd=[sys.executable,'-c',readf(filepath)]
++		return subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,bufsize=0)
++def run_prefork_process(cmd,kwargs,cargs):
++	if not'env'in kwargs:
++		kwargs['env']=dict(os.environ)
++	try:
++		obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs]))
++	except TypeError:
++		return run_regular_process(cmd,kwargs,cargs)
++	proc=get_process()
++	if not proc:
++		return run_regular_process(cmd,kwargs,cargs)
++	proc.stdin.write(obj)
++	proc.stdin.write('\n')
++	proc.stdin.flush()
++	obj=proc.stdout.readline()
++	if not obj:
++		raise OSError('Preforked sub-process %r died'%proc.pid)
++	process_pool.append(proc)
++	ret,out,err,ex,trace=cPickle.loads(base64.b64decode(obj))
++	if ex:
++		if ex=='OSError':
++			raise OSError(trace)
++		elif ex=='ValueError':
++			raise ValueError(trace)
++		elif ex=='TimeoutExpired':
++			exc=TimeoutExpired(cmd,timeout=cargs['timeout'],output=out)
++			exc.stderr=err
++			raise exc
++		else:
++			raise Exception(trace)
++	return ret,out,err
++def lchown(path,user=-1,group=-1):
++	if isinstance(user,str):
++		import pwd
++		entry=pwd.getpwnam(user)
++		if not entry:
++			raise OSError('Unknown user %r'%user)
++		user=entry[2]
++	if isinstance(group,str):
++		import grp
++		entry=grp.getgrnam(group)
++		if not entry:
++			raise OSError('Unknown group %r'%group)
++		group=entry[2]
++	return os.lchown(path,user,group)
++def run_regular_process(cmd,kwargs,cargs={}):
++	proc=subprocess.Popen(cmd,**kwargs)
++	if kwargs.get('stdout')or kwargs.get('stderr'):
++		try:
++			out,err=proc.communicate(**cargs)
++		except TimeoutExpired:
++			if kwargs.get('start_new_session')and hasattr(os,'killpg'):
++				os.killpg(proc.pid,signal.SIGKILL)
++			else:
++				proc.kill()
++			out,err=proc.communicate()
++			exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out)
++			exc.stderr=err
++			raise exc
++		status=proc.returncode
++	else:
++		out,err=(None,None)
++		try:
++			status=proc.wait(**cargs)
++		except TimeoutExpired ,e:
++			if kwargs.get('start_new_session')and hasattr(os,'killpg'):
++				os.killpg(proc.pid,signal.SIGKILL)
++			else:
++				proc.kill()
++			proc.wait()
++			raise e
++	return status,out,err
++def run_process(cmd,kwargs,cargs={}):
++	if kwargs.get('stdout')and kwargs.get('stderr'):
++		return run_prefork_process(cmd,kwargs,cargs)
++	else:
++		return run_regular_process(cmd,kwargs,cargs)
++def alloc_process_pool(n,force=False):
++	global run_process,get_process,alloc_process_pool
++	if not force:
++		n=max(n-len(process_pool),0)
++	try:
++		lst=[get_process()for x in range(n)]
++	except OSError:
++		run_process=run_regular_process
++		get_process=alloc_process_pool=nada
++	else:
++		for x in lst:
++			process_pool.append(x)
++def atexit_pool():
++	for k in process_pool:
++		try:
++			os.kill(k.pid,9)
++		except OSError:
++			pass
++		else:
++			k.wait()
++if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f:
++	atexit.register(atexit_pool)
++if sys.platform=='cli'or not sys.executable:
++	run_process=run_regular_process
++	get_process=alloc_process_pool=nada
 --- /dev/null
 +++ b/waflib/__init__.py
 @@ -0,0 +1,4 @@
@@ -13313,7 +13491,7 @@ Last-Update: 2014-11-28
 +
 --- /dev/null
 +++ b/waflib/extras/compat15.py
-@@ -0,0 +1,279 @@
+@@ -0,0 +1,301 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -13332,12 +13510,16 @@ Last-Update: 2014-11-28
 +sys.modules['Runner']=Runner
 +sys.modules['TaskGen']=TaskGen
 +sys.modules['Utils']=Utils
++sys.modules['Constants']=Context
++Context.SRCDIR=''
++Context.BLDDIR=''
 +from waflib.Tools import c_preproc
 +sys.modules['preproc']=c_preproc
 +from waflib.Tools import c_config
 +sys.modules['config_c']=c_config
 +ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive
 +ConfigSet.ConfigSet.set_variant=Utils.nada
++Utils.pproc=Utils.subprocess
 +Build.BuildContext.add_subdirs=Build.BuildContext.recurse
 +Build.BuildContext.new_task_gen=Build.BuildContext.__call__
 +Build.BuildContext.is_install=0
@@ -13394,7 +13576,7 @@ Last-Update: 2014-11-28
 +		self.all_envs[name]=env
 +	else:
 +		if fromenv:
-+			Logs.warn("The environment %s may have been configured already"%name)
++			Logs.warn('The environment %s may have been configured already',name)
 +	return env
 +Configure.ConfigurationContext.retrieve=retrieve
 +Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse
@@ -13434,21 +13616,31 @@ Last-Update: 2014-11-28
 +def get_curdir(self):
 +	return self.path.abspath()
 +Context.Context.curdir=property(get_curdir,Utils.nada)
++def get_srcdir(self):
++	return self.srcnode.abspath()
++Configure.ConfigurationContext.srcdir=property(get_srcdir,Utils.nada)
++def get_blddir(self):
++	return self.bldnode.abspath()
++Configure.ConfigurationContext.blddir=property(get_blddir,Utils.nada)
++Configure.ConfigurationContext.check_message_1=Configure.ConfigurationContext.start_msg
++Configure.ConfigurationContext.check_message_2=Configure.ConfigurationContext.end_msg
 +rev=Context.load_module
 +def load_module(path,encoding=None):
 +	ret=rev(path,encoding)
 +	if'set_options'in ret.__dict__:
 +		if Logs.verbose:
-+			Logs.warn('compat: rename "set_options" to "options" (%r)'%path)
++			Logs.warn('compat: rename "set_options" to "options" (%r)',path)
 +		ret.options=ret.set_options
 +	if'srcdir'in ret.__dict__:
 +		if Logs.verbose:
-+			Logs.warn('compat: rename "srcdir" to "top" (%r)'%path)
++			Logs.warn('compat: rename "srcdir" to "top" (%r)',path)
 +		ret.top=ret.srcdir
 +	if'blddir'in ret.__dict__:
 +		if Logs.verbose:
-+			Logs.warn('compat: rename "blddir" to "out" (%r)'%path)
++			Logs.warn('compat: rename "blddir" to "out" (%r)',path)
 +		ret.out=ret.blddir
++	Utils.g_module=Context.g_module
++	Options.launch_dir=Context.launch_dir
 +	return ret
 +Context.load_module=load_module
 +old_post=TaskGen.task_gen.post
@@ -13484,8 +13676,8 @@ Last-Update: 2014-11-28
 +	self.includes=self.to_list(getattr(self,'includes',[]))
 +	names=self.to_list(getattr(self,'uselib_local',[]))
 +	get=self.bld.get_tgen_by_name
-+	seen=set([])
-+	seen_uselib=set([])
++	seen=set()
++	seen_uselib=set()
 +	tmp=Utils.deque(names)
 +	if tmp:
 +		if Logs.verbose:
@@ -13565,14 +13757,14 @@ Last-Update: 2014-11-28
 +	self.obj_files.append(file)
 +old_define=Configure.ConfigurationContext.__dict__['define']
 + at Configure.conf
-+def define(self,key,val,quote=True):
-+	old_define(self,key,val,quote)
++def define(self,key,val,quote=True,comment=''):
++	old_define(self,key,val,quote,comment)
 +	if key.startswith('HAVE_'):
 +		self.env[key]=1
 +old_undefine=Configure.ConfigurationContext.__dict__['undefine']
 + at Configure.conf
-+def undefine(self,key):
-+	old_undefine(self,key)
++def undefine(self,key,comment=''):
++	old_undefine(self,key,comment)
 +	if key.startswith('HAVE_'):
 +		self.env[key]=0
 +def set_incdirs(self,val):
@@ -13584,18 +13776,26 @@ Last-Update: 2014-11-28
 +		return[]
 +	destpath=Utils.subst_vars(path,self.env)
 +	if self.is_install>0:
-+		Logs.info('* creating %s'%destpath)
++		Logs.info('* creating %s',destpath)
 +		Utils.check_dir(destpath)
 +	elif self.is_install<0:
-+		Logs.info('* removing %s'%destpath)
++		Logs.info('* removing %s',destpath)
 +		try:
 +			os.remove(destpath)
 +		except OSError:
 +			pass
 +Build.BuildContext.install_dir=install_dir
++repl={'apply_core':'process_source','apply_lib_vars':'process_source','apply_obj_vars':'propagate_uselib_vars','exec_rule':'process_rule'}
++def after(*k):
++	k=[repl.get(key,key)for key in k]
++	return TaskGen.after_method(*k)
++def before(*k):
++	k=[repl.get(key,key)for key in k]
++	return TaskGen.before_method(*k)
++TaskGen.before=before
 --- /dev/null
 +++ b/waflib/fixpy2.py
-@@ -0,0 +1,53 @@
+@@ -0,0 +1,54 @@
 +#! /usr/bin/env python
 +# encoding: utf-8
 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -13643,9 +13843,68 @@ Last-Update: 2014-11-28
 +def r1(code):
 +	code=code.replace(',e:',',e:')
 +	code=code.replace("",'')
-+	code=code.replace('','')
-+	return code
++	return code.replace('','')
 + at subst('Runner.py')
 +def r4(code):
-+	code=code.replace('next(self.biter)','self.biter.next()')
-+	return code
++	return code.replace('next(self.biter)','self.biter.next()')
++ at subst('Context.py')
++def r5(code):
++	return code.replace("('Execution failure: %s'%str(e),ex=e)","('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]")
+--- /dev/null
++++ b/waflib/processor.py
+@@ -0,0 +1,55 @@
++#! /usr/bin/env python
++# encoding: utf-8
++# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
++
++import os,sys,traceback,base64,signal
++try:
++	import cPickle
++except ImportError:
++	import pickle as cPickle
++try:
++	import subprocess32 as subprocess
++except ImportError:
++	import subprocess
++try:
++	TimeoutExpired=subprocess.TimeoutExpired
++except AttributeError:
++	class TimeoutExpired(object):
++		pass
++def run():
++	txt=sys.stdin.readline().strip()
++	if not txt:
++		sys.exit(1)
++	[cmd,kwargs,cargs]=cPickle.loads(base64.b64decode(txt))
++	cargs=cargs or{}
++	ret=1
++	out,err,ex,trace=(None,None,None,None)
++	try:
++		proc=subprocess.Popen(cmd,**kwargs)
++		try:
++			out,err=proc.communicate(**cargs)
++		except TimeoutExpired:
++			if kwargs.get('start_new_session')and hasattr(os,'killpg'):
++				os.killpg(proc.pid,signal.SIGKILL)
++			else:
++				proc.kill()
++			out,err=proc.communicate()
++			exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out)
++			exc.stderr=err
++			raise exc
++		ret=proc.returncode
++	except Exception ,e:
++		exc_type,exc_value,tb=sys.exc_info()
++		exc_lines=traceback.format_exception(exc_type,exc_value,tb)
++		trace=str(cmd)+'\n'+''.join(exc_lines)
++		ex=e.__class__.__name__
++	tmp=[ret,out,err,ex,trace]
++	obj=base64.b64encode(cPickle.dumps(tmp))
++	sys.stdout.write(obj.decode())
++	sys.stdout.write('\n')
++	sys.stdout.flush()
++while 1:
++	try:
++		run()
++	except KeyboardInterrupt:
++		break

-- 
mpv packaging



More information about the pkg-multimedia-commits mailing list