shithub: aubio

Download patch

ref: 904702d027b3e5e51e28a12383eecea0b55611da
parent: 55255070cdc7f914525c08d5689fa5c9dc9e7045
author: Paul Brossier <piem@piem.org>
date: Sat Mar 14 14:06:10 EDT 2015

waf, waflib: update to 1.8.7

--- a/waf
+++ b/waf
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 # encoding: ISO8859-1
-# Thomas Nagy, 2005-2012
+# Thomas Nagy, 2005-2015
 
 """
 Redistribution and use in source and binary forms, with or without
@@ -30,13 +30,15 @@
 POSSIBILITY OF SUCH DAMAGE.
 """
 
-import os, sys
+import os, sys, inspect
 
-VERSION="1.7.15"
-REVISION="de1cb53b86321cda764be4b3c38c3d20"
+VERSION="1.8.7"
+REVISION="073060339ba56c09e143ed641610cbec"
+GIT="x"
 INSTALL=''
-C1='#+'
-C2='#&'
+C1='#/'
+C2='#-'
+C3='#+'
 cwd = os.getcwd()
 join = os.path.join
 
@@ -53,8 +55,8 @@
 	print(('\033[91mError: %s\033[0m' % m))
 	sys.exit(1)
 
-def unpack_wafdir(dir):
-	f = open(sys.argv[0],'rb')
+def unpack_wafdir(dir, src):
+	f = open(src,'rb')
 	c = 'corrupt archive (%d)'
 	while 1:
 		line = f.readline()
@@ -65,13 +67,13 @@
 			if f.readline() != b('#<==\n'): err(c % 2)
 			break
 	if not txt: err(c % 3)
-	txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r'))
+	txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00'))
 
 	import shutil, tarfile
 	try: shutil.rmtree(dir)
 	except OSError: pass
 	try:
-		for x in ['Tools', 'extras']:
+		for x in ('Tools', 'extras'):
 			os.makedirs(join(dir, 'waflib', x))
 	except OSError:
 		err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir)
@@ -100,7 +102,7 @@
 	finally:
 		t.close()
 
-	for x in ['Tools', 'extras']:
+	for x in ('Tools', 'extras'):
 		os.chmod(join('waflib',x), 493)
 
 	if sys.hexversion<0x300000f:
@@ -127,8 +129,8 @@
 		pass
 
 def find_lib():
-	name = sys.argv[0]
-	base = os.path.dirname(os.path.abspath(name))
+	src = os.path.abspath(inspect.getfile(inspect.getmodule(err)))
+	base, name = os.path.split(src)
 
 	#devs use $WAFDIR
 	w=test(os.environ.get('WAFDIR', ''))
@@ -141,7 +143,7 @@
 		err('waf-light requires waflib -> export WAFDIR=/folder')
 
 	dirname = '%s-%s-%s' % (WAF, VERSION, REVISION)
-	for i in [INSTALL,'/usr','/usr/local','/opt']:
+	for i in (INSTALL,'/usr','/usr/local','/opt'):
 		w = test(i + '/lib/' + dirname)
 		if w: return w
 
@@ -151,7 +153,7 @@
 	if w: return w
 
 	#unpack
-	unpack_wafdir(dir)
+	unpack_wafdir(dir, src)
 	return dir
 
 wafdir = find_lib()
--- a/waflib/Build.py
+++ b/waflib/Build.py
@@ -2,7 +2,7 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,errno,re,shutil
+import os,sys,errno,re,shutil,stat
 try:
 	import cPickle
 except ImportError:
@@ -31,7 +31,7 @@
 		self.out_dir=kw.get('out_dir',Context.out_dir)
 		self.cache_dir=kw.get('cache_dir',None)
 		if not self.cache_dir:
-			self.cache_dir=self.out_dir+os.sep+CACHE_DIR
+			self.cache_dir=os.path.join(self.out_dir,CACHE_DIR)
 		self.all_envs={}
 		self.task_sigs={}
 		self.node_deps={}
@@ -42,8 +42,6 @@
 		self.jobs=Options.options.jobs
 		self.targets=Options.options.targets
 		self.keep=Options.options.keep
-		self.cache_global=Options.cache_global
-		self.nocache=Options.options.nocache
 		self.progress_bar=Options.options.progress_bar
 		self.deps_man=Utils.defaultdict(list)
 		self.current_group=0
@@ -109,23 +107,19 @@
 		self.recurse([self.run_dir])
 		self.pre_build()
 		self.timer=Utils.Timer()
-		if self.progress_bar:
-			sys.stderr.write(Logs.colors.cursor_off)
 		try:
 			self.compile()
 		finally:
-			if self.progress_bar==1:
+			if self.progress_bar==1 and sys.stderr.isatty():
 				c=len(self.returned_tasks)or 1
-				self.to_log(self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL))
-				print('')
-				sys.stdout.flush()
-				sys.stderr.write(Logs.colors.cursor_on)
+				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)
 		self.post_build()
 	def restore(self):
 		try:
 			env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
-		except(IOError,OSError):
+		except EnvironmentError:
 			pass
 		else:
 			if env['version']<Context.HEXVERSION:
@@ -253,6 +247,8 @@
 		except KeyError:
 			raise Errors.WafError('Could not find a task generator for the name %r'%name)
 	def progress_line(self,state,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]
@@ -265,7 +261,7 @@
 		if cols<7:cols=7
 		ratio=((cols*state)//total)-1
 		bar=('='*ratio+'>').ljust(cols)
-		msg=Utils.indicator%(left,bar,right)
+		msg=Logs.indicator%(left,bar,right)
 		return msg
 	def declare_chain(self,*k,**kw):
 		return TaskGen.declare_chain(*k,**kw)
@@ -325,6 +321,7 @@
 			for i in range(len(self.groups)):
 				if id(g)==id(self.groups[i]):
 					self.current_group=i
+					break
 		else:
 			self.current_group=idx
 	def total(self):
@@ -473,16 +470,16 @@
 				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,self.chmod)
+			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,self.chmod)
+		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)
+		self.generator.bld.do_link(src,destfile,tsk=self)
 class InstallContext(BuildContext):
 	'''installs the targets on the system'''
 	cmd='install'
@@ -490,7 +487,12 @@
 		super(InstallContext,self).__init__(**kw)
 		self.uninstall=[]
 		self.is_install=INSTALL
-	def do_install(self,src,tgt,chmod=Utils.O644):
+	def copy_fun(self,src,tgt,**kw):
+		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))
@@ -510,19 +512,22 @@
 		if not self.progress_bar:
 			Logs.info('+ install %s (from %s)'%(tgt,srclbl))
 		try:
+			os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode))
+		except EnvironmentError:
+			pass
+		try:
 			os.remove(tgt)
 		except OSError:
 			pass
 		try:
-			shutil.copy2(src,tgt)
-			os.chmod(tgt,chmod)
+			self.copy_fun(src,tgt,**kw)
 		except IOError:
 			try:
 				os.stat(src)
-			except(OSError,IOError):
+			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):
+	def do_link(self,src,tgt,**kw):
 		d,_=os.path.split(tgt)
 		Utils.check_dir(d)
 		link=False
@@ -545,11 +550,12 @@
 			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):
+	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:
@@ -560,18 +566,19 @@
 		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):
+	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):
+	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)
@@ -579,6 +586,7 @@
 		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
@@ -591,7 +599,14 @@
 	def __init__(self,**kw):
 		super(UninstallContext,self).__init__(**kw)
 		self.is_install=UNINSTALL
-	def do_install(self,src,tgt,chmod=Utils.O644):
+	def rm_empty_dirs(self,tgt):
+		while tgt:
+			tgt=os.path.dirname(tgt)
+			try:
+				os.rmdir(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)
@@ -604,13 +619,8 @@
 					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))
-		while tgt:
-			tgt=os.path.dirname(tgt)
-			try:
-				os.rmdir(tgt)
-			except OSError:
-				break
-	def do_link(self,src,tgt):
+		self.rm_empty_dirs(tgt)
+	def do_link(self,src,tgt,**kw):
 		try:
 			if not self.progress_bar:
 				Logs.info('- remove %s'%tgt)
@@ -617,12 +627,7 @@
 			os.remove(tgt)
 		except OSError:
 			pass
-		while tgt:
-			tgt=os.path.dirname(tgt)
-			try:
-				os.rmdir(tgt)
-			except OSError:
-				break
+		self.rm_empty_dirs(tgt)
 	def execute(self):
 		try:
 			def runnable_status(self):
@@ -754,5 +759,3 @@
 			else:
 				return pattern.match(node.abspath())
 		return match
-BuildContext.store=Utils.nogc(BuildContext.store)
-BuildContext.restore=Utils.nogc(BuildContext.restore)
--- a/waflib/ConfigSet.py
+++ b/waflib/ConfigSet.py
@@ -89,9 +89,9 @@
 		self.table[key]=value
 		return value
 	def append_value(self,var,val):
-		current_value=self._get_list_value_for_modification(var)
 		if isinstance(val,str):
 			val=[val]
+		current_value=self._get_list_value_for_modification(var)
 		current_value.extend(val)
 	def prepend_value(self,var,val):
 		if isinstance(val,str):
--- a/waflib/Configure.py
+++ b/waflib/Configure.py
@@ -2,14 +2,8 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,shlex,sys,time
+import os,shlex,sys,time,re,shutil
 from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
-try:
-	from urllib import request
-except ImportError:
-	from urllib import urlopen
-else:
-	urlopen=request.urlopen
 BREAK='break'
 CONTINUE='continue'
 WAF_CONFIG_LOG='config.log'
@@ -18,37 +12,6 @@
 # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
 # using %(args)s
 #'''
-def download_check(node):
-	pass
-def download_tool(tool,force=False,ctx=None):
-	for x in Utils.to_list(Context.remote_repo):
-		for sub in Utils.to_list(Context.remote_locs):
-			url='/'.join((x,sub,tool+'.py'))
-			try:
-				web=urlopen(url)
-				try:
-					if web.getcode()!=200:
-						continue
-				except AttributeError:
-					pass
-			except Exception:
-				continue
-			else:
-				tmp=ctx.root.make_node(os.sep.join((Context.waf_dir,'waflib','extras',tool+'.py')))
-				tmp.write(web.read(),'wb')
-				Logs.warn('Downloaded %s from %s'%(tool,url))
-				download_check(tmp)
-				try:
-					module=Context.load_tool(tool)
-				except Exception:
-					Logs.warn('The tool %s from %s is unusable'%(tool,url))
-					try:
-						tmp.delete()
-					except Exception:
-						pass
-					continue
-				return module
-	raise Errors.WafError('Could not load the Waf tool')
 class ConfigurationContext(Context.Context):
 	'''configures the project'''
 	cmd='configure'
@@ -96,6 +59,7 @@
 			out=getattr(Context.g_module,Context.OUT,None)
 		if not out:
 			out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
+		out=os.path.realpath(out)
 		self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
 		self.bldnode.mkdir()
 		if not os.path.isdir(self.bldnode.abspath()):
@@ -139,11 +103,11 @@
 		env['files']=self.files
 		env['environ']=dict(self.environ)
 		if not self.env.NO_LOCK_IN_RUN:
-			env.store(Context.run_dir+os.sep+Options.lockfile)
+			env.store(os.path.join(Context.run_dir,Options.lockfile))
 		if not self.env.NO_LOCK_IN_TOP:
-			env.store(Context.top_dir+os.sep+Options.lockfile)
+			env.store(os.path.join(Context.top_dir,Options.lockfile))
 		if not self.env.NO_LOCK_IN_OUT:
-			env.store(Context.out_dir+os.sep+Options.lockfile)
+			env.store(os.path.join(Context.out_dir,Options.lockfile))
 	def prepare_env(self,env):
 		if not env.PREFIX:
 			if Options.options.prefix or Utils.is_win32:
@@ -151,9 +115,15 @@
 			else:
 				env.PREFIX=''
 		if not env.BINDIR:
-			env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
+			if Options.options.bindir:
+				env.BINDIR=os.path.abspath(os.path.expanduser(Options.options.bindir))
+			else:
+				env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
 		if not env.LIBDIR:
-			env.LIBDIR=Utils.subst_vars('${PREFIX}/lib',env)
+			if Options.options.libdir:
+				env.LIBDIR=os.path.abspath(os.path.expanduser(Options.options.libdir))
+			else:
+				env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env)
 	def store(self):
 		n=self.cachedir.make_node('build.config.py')
 		n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
@@ -162,7 +132,7 @@
 		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,download=True):
+	def load(self,input,tooldir=None,funs=None):
 		tools=Utils.to_list(input)
 		if tooldir:tooldir=Utils.to_list(tooldir)
 		for tool in tools:
@@ -173,14 +143,9 @@
 			self.tool_cache.append(mag)
 			module=None
 			try:
-				module=Context.load_tool(tool,tooldir)
+				module=Context.load_tool(tool,tooldir,ctx=self)
 			except ImportError ,e:
-				if Options.options.download:
-					module=download_tool(tool,ctx=self)
-					if not module:
-						self.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s'%(tool,sys.path,e))
-				else:
-					self.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s'%(tool,sys.path,e))
+				self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,sys.path,e))
 			except Exception ,e:
 				self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
 				self.to_log(Utils.ex_stack())
@@ -243,14 +208,14 @@
 			return[cmd]
 	return cmd
 @conf
-def check_waf_version(self,mini='1.6.99',maxi='1.8.0'):
-	self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)))
+def check_waf_version(self,mini='1.7.99',maxi='1.9.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:
 		self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
 	if Utils.num2ver(maxi)<ver:
 		self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
-	self.end_msg('ok')
+	self.end_msg('ok',**kw)
 @conf
 def find_file(self,filename,path_list=[]):
 	for n in Utils.to_list(filename):
@@ -262,56 +227,153 @@
 @conf
 def find_program(self,filename,**kw):
 	exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
-	environ=kw.get('environ',os.environ)
+	environ=kw.get('environ',getattr(self,'environ',os.environ))
 	ret=''
 	filename=Utils.to_list(filename)
+	msg=kw.get('msg',', '.join(filename))
 	var=kw.get('var','')
 	if not var:
-		var=filename[0].upper()
-	if self.env[var]:
-		ret=self.env[var]
-	elif var in environ:
-		ret=environ[var]
+		var=re.sub(r'[-.]','_',filename[0].upper())
 	path_list=kw.get('path_list','')
-	if not ret:
-		if path_list:
-			path_list=Utils.to_list(path_list)
+	if path_list:
+		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:
-			path_list=environ.get('PATH','').split(os.pathsep)
-		if not isinstance(filename,list):
-			filename=[filename]
-		for a in exts.split(','):
-			if ret:
-				break
-			for b in filename:
-				if ret:
-					break
-				for c in path_list:
-					if ret:
-						break
-					x=os.path.expanduser(os.path.join(c,b+a))
-					if os.path.isfile(x):
-						ret=x
-	if not ret and Utils.winreg:
-		ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
-	if not ret and Utils.winreg:
-		ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
-	self.msg('Checking for program '+','.join(filename),ret or False)
-	self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
+			ret=self.cmd_to_list(filename)
+	elif self.env[var]:
+		ret=self.env[var]
+		ret=self.cmd_to_list(ret)
+	else:
+		if not ret:
+			ret=self.find_binary(filename,exts.split(','),path_list)
+		if not ret and Utils.winreg:
+			ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
+		if not ret and Utils.winreg:
+			ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
+		ret=self.cmd_to_list(ret)
+	if ret:
+		if len(ret)==1:
+			retmsg=ret[0]
+		else:
+			retmsg=ret
+	else:
+		retmsg=False
+	self.msg("Checking for program '%s'"%msg,retmsg,**kw)
+	if not kw.get('quiet',None):
+		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 %s'%','.join(filename))
-	if var:
+		self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename)
+	interpreter=kw.get('interpreter',None)
+	if interpreter is None:
+		if not Utils.check_exe(ret[0],env=environ):
+			self.fatal('Program %r is not executable'%ret)
 		self.env[var]=ret
+	else:
+		self.env[var]=self.env[interpreter]+ret
 	return ret
 @conf
-def find_perl_program(self,filename,path_list=[],var=None,environ=None,exts=''):
+def find_binary(self,filenames,exts,paths):
+	for f in filenames:
+		for ext in exts:
+			exe_name=f+ext
+			if os.path.isabs(exe_name):
+				if os.path.isfile(exe_name):
+					return exe_name
+			else:
+				for path in paths:
+					x=os.path.expanduser(os.path.join(path,exe_name))
+					if os.path.isfile(x):
+						return x
+	return None
+@conf
+def run_build(self,*k,**kw):
+	lst=[str(v)for(p,v)in kw.items()if p!='env']
+	h=Utils.h_list(lst)
+	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
 	try:
-		app=self.find_program(filename,path_list=path_list,var=var,environ=environ,exts=exts)
-	except Exception:
-		self.find_program('perl',var='PERL')
-		app=self.find_file(filename,os.environ['PATH'].split(os.pathsep))
-		if not app:
+		os.makedirs(dir)
+	except OSError:
+		pass
+	try:
+		os.stat(dir)
+	except OSError:
+		self.fatal('cannot use the configuration test folder %r'%dir)
+	cachemode=getattr(Options.options,'confcache',None)
+	if cachemode==1:
+		try:
+			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build'))
+		except OSError:
+			pass
+		except IOError:
+			pass
+		else:
+			ret=proj['cache_run_build']
+			if isinstance(ret,str)and ret.startswith('Test does not build'):
+				self.fatal(ret)
+			return ret
+	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)
+	bld.init_dirs()
+	bld.progress_bar=0
+	bld.targets='*'
+	bld.logger=self.logger
+	bld.all_envs.update(self.all_envs)
+	bld.env=kw['env']
+	bld.kw=kw
+	bld.conf=self
+	kw['build_fun'](bld)
+	ret=-1
+	try:
+		try:
+			bld.compile()
+		except Errors.WafError:
+			ret='Test does not build: %s'%Utils.ex_stack()
+			self.fatal(ret)
+		else:
+			ret=getattr(bld,'retval',0)
+	finally:
+		if cachemode==1:
+			proj=ConfigSet.ConfigSet()
+			proj['cache_run_build']=ret
+			proj.store(os.path.join(dir,'cache_run_build'))
+		else:
+			shutil.rmtree(dir)
+	return ret
+@conf
+def ret_msg(self,msg,args):
+	if isinstance(msg,str):
+		return msg
+	return msg(args)
+@conf
+def test(self,*k,**kw):
+	if not'env'in kw:
+		kw['env']=self.env.derive()
+	if kw.get('validate',None):
+		kw['validate'](kw)
+	self.start_msg(kw['msg'],**kw)
+	ret=None
+	try:
+		ret=self.run_build(*k,**kw)
+	except self.errors.ConfigurationError:
+		self.end_msg(kw['errmsg'],'YELLOW',**kw)
+		if Logs.verbose>1:
 			raise
-		if var:
-			self.env[var]=Utils.to_list(self.env['PERL'])+[app]
-	self.msg('Checking for %r'%filename,app)
+		else:
+			self.fatal('The configuration failed')
+	else:
+		kw['success']=ret
+	if kw.get('post_check',None):
+		ret=kw['post_check'](kw)
+	if ret:
+		self.end_msg(kw['errmsg'],'YELLOW',**kw)
+		self.fatal('The configuration failed %r'%ret)
+	else:
+		self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
+	return ret
--- a/waflib/Context.py
+++ b/waflib/Context.py
@@ -2,12 +2,12 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,imp,sys
+import os,re,imp,sys
 from waflib import Utils,Errors,Logs
 import waflib.Node
-HEXVERSION=0x1070f00
-WAFVERSION="1.7.15"
-WAFREVISION="f63ac9793de2d4eaae884e55d4ff70a761dcbab2"
+HEXVERSION=0x1080700
+WAFVERSION="1.8.7"
+WAFREVISION="e5056b9ade7bb224f53baab13a0ce136344ab602"
 ABI=98
 DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
 APPNAME='APPNAME'
@@ -71,6 +71,14 @@
 		self.logger=None
 	def __hash__(self):
 		return id(self)
+	def finalize(self):
+		try:
+			logger=self.logger
+		except AttributeError:
+			pass
+		else:
+			Logs.free_logger(logger)
+			delattr(self,'logger')
 	def load(self,tool_list,*k,**kw):
 		tools=Utils.to_list(tool_list)
 		path=Utils.to_list(kw.get('tooldir',''))
@@ -90,7 +98,7 @@
 		self.cur_script=self.stack_path.pop()
 		if self.cur_script:
 			self.path=self.cur_script.parent
-	def recurse(self,dirs,name=None,mandatory=True,once=True):
+	def recurse(self,dirs,name=None,mandatory=True,once=True,encoding=None):
 		try:
 			cache=self.recurse_cache
 		except AttributeError:
@@ -105,7 +113,7 @@
 				cache[node]=True
 				self.pre_recurse(node)
 				try:
-					function_code=node.read('rU')
+					function_code=node.read('rU',encoding)
 					exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
 				finally:
 					self.post_recurse(node)
@@ -116,7 +124,7 @@
 					cache[tup]=True
 					self.pre_recurse(node)
 					try:
-						wscript_module=load_module(node.abspath())
+						wscript_module=load_module(node.abspath(),encoding=encoding)
 						user_function=getattr(wscript_module,(name or self.fun),None)
 						if not user_function:
 							if not mandatory:
@@ -140,6 +148,8 @@
 			kw['stdout']=subprocess.PIPE
 		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)
@@ -156,7 +166,7 @@
 			if self.logger:
 				self.logger.debug('out: %s'%out)
 			else:
-				sys.stdout.write(out)
+				Logs.info(out,extra={'stream':sys.stdout,'c1':''})
 		if err:
 			if not isinstance(err,str):
 				err=err.decode(sys.stdout.encoding or'iso8859-1')
@@ -163,7 +173,7 @@
 			if self.logger:
 				self.logger.error('err: %s'%err)
 			else:
-				sys.stderr.write(err)
+				Logs.info(err,extra={'stream':sys.stderr,'c1':''})
 		return ret
 	def cmd_and_log(self,cmd,**kw):
 		subprocess=Utils.subprocess
@@ -179,6 +189,8 @@
 			del kw['output']
 		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])
 		kw['stdout']=kw['stderr']=subprocess.PIPE
 		if quiet is None:
 			self.to_log(cmd)
@@ -222,12 +234,24 @@
 		else:
 			sys.stderr.write(str(msg))
 			sys.stderr.flush()
-	def msg(self,msg,result,color=None):
-		self.start_msg(msg)
+	def msg(self,*k,**kw):
+		try:
+			msg=kw['msg']
+		except KeyError:
+			msg=k[0]
+		self.start_msg(msg,**kw)
+		try:
+			result=kw['result']
+		except KeyError:
+			result=k[1]
+		color=kw.get('color',None)
 		if not isinstance(color,str):
 			color=result and'GREEN'or'YELLOW'
-		self.end_msg(result,color)
-	def start_msg(self,msg):
+		self.end_msg(result,color,**kw)
+	def start_msg(self,*k,**kw):
+		if kw.get('quiet',None):
+			return
+		msg=kw.get('msg',None)or k[0]
 		try:
 			if self.in_msg:
 				self.in_msg+=1
@@ -242,10 +266,13 @@
 		for x in(self.line_just*'-',msg):
 			self.to_log(x)
 		Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
-	def end_msg(self,result,color=None):
+	def end_msg(self,*k,**kw):
+		if kw.get('quiet',None):
+			return
 		self.in_msg-=1
 		if self.in_msg:
 			return
+		result=kw.get('result',None)or k[0]
 		defcolor='GREEN'
 		if result==True:
 			msg='ok'
@@ -255,15 +282,39 @@
 		else:
 			msg=str(result)
 		self.to_log(msg)
-		Logs.pprint(color or defcolor,msg)
+		try:
+			color=kw['color']
+		except KeyError:
+			if len(k)>1 and k[1]in Logs.colors_lst:
+				color=k[1]
+			else:
+				color=defcolor
+		Logs.pprint(color,msg)
 	def load_special_tools(self,var,ban=[]):
 		global waf_dir
-		lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
-		for x in lst:
-			if not x.name in ban:
-				load_tool(x.name.replace('.py',''))
+		if os.path.isdir(waf_dir):
+			lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
+			for x in lst:
+				if not x.name in ban:
+					load_tool(x.name.replace('.py',''))
+		else:
+			from zipfile import PyZipFile
+			waflibs=PyZipFile(waf_dir)
+			lst=waflibs.namelist()
+			for x in lst:
+				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):
+						doban=True
+				if not doban:
+					f=f.replace('.py','')
+					load_tool(f)
 cache_modules={}
-def load_module(path):
+def load_module(path,encoding=None):
 	try:
 		return cache_modules[path]
 	except KeyError:
@@ -270,8 +321,8 @@
 		pass
 	module=imp.new_module(WSCRIPT_FILE)
 	try:
-		code=Utils.readf(path,m='rU')
-	except(IOError,OSError):
+		code=Utils.readf(path,m='rU',encoding=encoding)
+	except EnvironmentError:
 		raise Errors.WafError('Could not read the file %r'%path)
 	module_dir=os.path.dirname(path)
 	sys.path.insert(0,module_dir)
@@ -279,11 +330,9 @@
 	sys.path.remove(module_dir)
 	cache_modules[path]=module
 	return module
-def load_tool(tool,tooldir=None):
+def load_tool(tool,tooldir=None,ctx=None):
 	if tool=='java':
 		tool='javaw'
-	elif tool=='compiler_cc':
-		tool='compiler_c'
 	else:
 		tool=tool.replace('++','xx')
 	if tooldir:
@@ -298,19 +347,14 @@
 			for d in tooldir:
 				sys.path.remove(d)
 	else:
-		global waf_dir
-		try:
-			os.stat(os.path.join(waf_dir,'waflib','extras',tool+'.py'))
-		except OSError:
+		for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
 			try:
-				os.stat(os.path.join(waf_dir,'waflib','Tools',tool+'.py'))
-			except OSError:
-				d=tool
-			else:
-				d='waflib.Tools.%s'%tool
-		else:
-			d='waflib.extras.%s'%tool
-		__import__(d)
-		ret=sys.modules[d]
+				__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
--- a/waflib/Logs.py
+++ b/waflib/Logs.py
@@ -2,41 +2,13 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,re,traceback,sys
-_nocolor=os.environ.get('NOCOLOR','no')not in('no','0','false')
-try:
-	if not _nocolor:
-		import waflib.ansiterm
-except ImportError:
-	pass
-try:
-	import threading
-except ImportError:
-	if not'JOBS'in os.environ:
-		os.environ['JOBS']='1'
-else:
-	wlock=threading.Lock()
-	class sync_stream(object):
-		def __init__(self,stream):
-			self.stream=stream
-			self.encoding=self.stream.encoding
-		def write(self,txt):
-			try:
-				wlock.acquire()
-				self.stream.write(txt)
-				self.stream.flush()
-			finally:
-				wlock.release()
-		def fileno(self):
-			return self.stream.fileno()
-		def flush(self):
-			self.stream.flush()
-		def isatty(self):
-			return self.stream.isatty()
-	if not os.environ.get('NOSYNC',False):
-		if id(sys.stdout)==id(sys.__stdout__):
-			sys.stdout=sync_stream(sys.stdout)
-			sys.stderr=sync_stream(sys.stderr)
+import os,re,traceback,sys,types
+from waflib import Utils,ansiterm
+if not os.environ.get('NOSYNC',False):
+	if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
+		sys.stdout=ansiterm.AnsiTerm(sys.stdout)
+	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"
@@ -43,31 +15,25 @@
 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','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',}
-got_tty=not os.environ.get('TERM','dumb')in['dumb','emacs']
-if got_tty:
-	try:
-		got_tty=sys.stderr.isatty()and sys.stdout.isatty()
-	except AttributeError:
-		got_tty=False
-if(not got_tty and os.environ.get('TERM','dumb')!='msys')or _nocolor:
-	colors_lst['USE']=False
-def get_term_cols():
-	return 80
-try:
-	import struct,fcntl,termios
-except ImportError:
-	pass
-else:
-	if got_tty:
-		def get_term_cols_real():
-			dummy_lines,cols=struct.unpack("HHHH",fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[:2]
-			return cols
-		try:
-			get_term_cols_real()
-		except Exception:
-			pass
+indicator='\r\x1b[K%s%s%s'
+def enable_colors(use):
+	if use==1:
+		if not(sys.stderr.isatty()or sys.stdout.isatty()):
+			use=0
+		if Utils.is_win32:
+			term=os.environ.get('TERM','')
 		else:
-			get_term_cols=get_term_cols_real
+			term=os.environ.get('TERM','dumb')
+		if term in('dumb','emacs'):
+			use=0
+	if use>=1:
+		os.environ['TERM']='vt100'
+	colors_lst['USE']=use
+try:
+	get_term_cols=ansiterm.get_term_cols
+except AttributeError:
+	def get_term_cols():
+		return 80
 get_term_cols.__doc__="""
 	Get the console width in characters.
 
@@ -88,16 +54,8 @@
 	def __init__(self,name=None):
 		pass
 	def filter(self,rec):
-		rec.c1=colors.PINK
-		rec.c2=colors.NORMAL
 		rec.zone=rec.module
 		if rec.levelno>=logging.INFO:
-			if rec.levelno>=logging.ERROR:
-				rec.c1=colors.RED
-			elif rec.levelno>=logging.WARNING:
-				rec.c1=colors.YELLOW
-			else:
-				rec.c1=colors.GREEN
 			return True
 		m=re_log.match(rec.msg)
 		if m:
@@ -108,16 +66,70 @@
 		elif not verbose>2:
 			return False
 		return True
+class log_handler(logging.StreamHandler):
+	def emit(self,record):
+		try:
+			try:
+				self.stream=record.stream
+			except AttributeError:
+				if record.levelno>=logging.WARNING:
+					record.stream=self.stream=sys.stderr
+				else:
+					record.stream=self.stream=sys.stdout
+			self.emit_override(record)
+			self.flush()
+		except(KeyboardInterrupt,SystemExit):
+			raise
+		except:
+			self.handleError(record)
+	def emit_override(self,record,**kw):
+		self.terminator=getattr(record,'terminator','\n')
+		stream=self.stream
+		if hasattr(types,"UnicodeType"):
+			msg=self.formatter.format(record)
+			fs='%s'+self.terminator
+			try:
+				if(isinstance(msg,unicode)and getattr(stream,'encoding',None)):
+					fs=fs.decode(stream.encoding)
+					try:
+						stream.write(fs%msg)
+					except UnicodeEncodeError:
+						stream.write((fs%msg).encode(stream.encoding))
+				else:
+					stream.write(fs%msg)
+			except UnicodeError:
+				stream.write((fs%msg).encode("UTF-8"))
+		else:
+			logging.StreamHandler.emit(self,record)
 class formatter(logging.Formatter):
 	def __init__(self):
 		logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT)
 	def format(self,rec):
-		if rec.levelno>=logging.WARNING or rec.levelno==logging.INFO:
-			try:
-				msg=rec.msg.decode('utf-8')
-			except Exception:
-				msg=rec.msg
-			return'%s%s%s'%(rec.c1,msg,rec.c2)
+		try:
+			msg=rec.msg.decode('utf-8')
+		except Exception:
+			msg=rec.msg
+		use=colors_lst['USE']
+		if(use==1 and rec.stream.isatty())or use==2:
+			c1=getattr(rec,'c1',None)
+			if c1 is None:
+				c1=''
+				if rec.levelno>=logging.ERROR:
+					c1=colors.RED
+				elif rec.levelno>=logging.WARNING:
+					c1=colors.YELLOW
+				elif rec.levelno>=logging.INFO:
+					c1=colors.GREEN
+			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)
+		if rec.levelno>=logging.INFO:
+			return msg
+		rec.msg=msg
+		rec.c1=colors.PINK
+		rec.c2=colors.NORMAL
 		return logging.Formatter.format(self,rec)
 log=None
 def debug(*k,**kw):
@@ -150,7 +162,7 @@
 	log=logging.getLogger('waflib')
 	log.handlers=[]
 	log.filters=[]
-	hdlr=logging.StreamHandler()
+	hdlr=log_handler()
 	hdlr.setFormatter(formatter())
 	log.addHandler(hdlr)
 	log.addFilter(log_filter())
@@ -163,7 +175,7 @@
 	logger.addHandler(hdlr)
 	logger.setLevel(logging.DEBUG)
 	return logger
-def make_mem_logger(name,to_log,size=10000):
+def make_mem_logger(name,to_log,size=8192):
 	from logging.handlers import MemoryHandler
 	logger=logging.getLogger(name)
 	hdlr=MemoryHandler(size,target=to_log)
@@ -173,5 +185,12 @@
 	logger.memhandler=hdlr
 	logger.setLevel(logging.DEBUG)
 	return logger
-def pprint(col,str,label='',sep='\n'):
-	sys.stderr.write("%s%s%s %s%s"%(colors(col),str,colors.NORMAL,label,sep))
+def free_logger(logger):
+	try:
+		for x in logger.handlers:
+			x.close()
+			logger.removeHandler(x)
+	except Exception ,e:
+		pass
+def pprint(col,msg,label='',sep='\n'):
+	info("%s%s%s %s"%(colors(col),msg,colors.NORMAL,label),extra={'terminator':sep})
--- a/waflib/Node.py
+++ b/waflib/Node.py
@@ -46,9 +46,12 @@
 re_sp=re.compile('[/\\\\]')
 def split_path_win32(path):
 	if path.startswith('\\\\'):
-		ret=re.split(re_sp,path)[2:]
-		ret[0]='\\'+ret[0]
-		return ret
+		if path.startswith('\\\\?'):
+			path=path[4:]
+		else:
+			ret=re.split(re_sp,path)[2:]
+			ret[0]='\\\\'+ret[0]
+			return ret
 	return re.split(re_sp,path)
 if sys.platform=='cygwin':
 	split_path=split_path_cygwin
@@ -55,6 +58,7 @@
 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')
 	def __init__(self,name,parent):
 		self.name=name
@@ -67,7 +71,7 @@
 		self.name=data[0]
 		self.parent=data[1]
 		if data[2]is not None:
-			self.children=data[2]
+			self.children=self.dict_class(data[2])
 		if data[3]is not None:
 			self.sig=data[3]
 	def __getstate__(self):
@@ -90,13 +94,16 @@
 		os.chmod(self.abspath(),val)
 	def delete(self):
 		try:
-			if hasattr(self,'children'):
-				shutil.rmtree(self.abspath())
-			else:
-				os.remove(self.abspath())
-		except OSError:
-			pass
-		self.evict()
+			try:
+				if hasattr(self,'children'):
+					shutil.rmtree(self.abspath())
+				else:
+					os.remove(self.abspath())
+			except OSError ,e:
+				if os.path.exists(self.abspath()):
+					raise e
+		finally:
+			self.evict()
 	def evict(self):
 		del self.parent.children[self.name]
 	def suffix(self):
@@ -130,7 +137,7 @@
 			try:
 				self.children
 			except AttributeError:
-				self.children={}
+				self.children=self.dict_class()
 		self.cache_isdir=True
 	def find_node(self,lst):
 		if isinstance(lst,str):
@@ -143,7 +150,7 @@
 			try:
 				ch=cur.children
 			except AttributeError:
-				cur.children={}
+				cur.children=self.dict_class()
 			else:
 				try:
 					cur=cur.children[x]
@@ -182,7 +189,7 @@
 					cur=cur.children[x]
 					continue
 			else:
-				cur.children={}
+				cur.children=self.dict_class()
 			cur=self.__class__(x,cur)
 		return cur
 	def search_node(self,lst):
@@ -218,8 +225,12 @@
 			up+=1
 			c1=c1.parent
 			c2=c2.parent
-		for i in range(up):
-			lst.append('..')
+		if c1.parent:
+			for i in range(up):
+				lst.append('..')
+		else:
+			if os.sep=='/'and lst:
+				lst.append('')
 		lst.reverse()
 		return os.sep.join(lst)or'.'
 	def abspath(self):
@@ -256,7 +267,7 @@
 		try:
 			lst=set(self.children.keys())
 		except AttributeError:
-			self.children={}
+			self.children=self.dict_class()
 		else:
 			if remove:
 				for x in lst-set(dircont):
@@ -433,8 +444,6 @@
 		else:
 			name=name[:-len(ext_in)]+ext
 		return self.parent.find_or_declare([name])
-	def nice_path(self,env=None):
-		return self.path_from(self.ctx.launch_node())
 	def bldpath(self):
 		return self.path_from(self.ctx.bldnode)
 	def srcpath(self):
@@ -449,9 +458,6 @@
 		return self.srcpath()
 	def bld_dir(self):
 		return self.parent.bldpath()
-	def bld_base(self):
-		s=os.path.splitext(self.name)[0]
-		return self.bld_dir()+os.sep+s
 	def get_bld_sig(self):
 		try:
 			return self.cache_sig
@@ -461,7 +467,6 @@
 			self.sig=Utils.h_file(self.abspath())
 		self.cache_sig=ret=self.sig
 		return ret
-	search=search_node
 pickle_lock=Utils.threading.Lock()
 class Nod3(Node):
 	pass
--- a/waflib/Options.py
+++ b/waflib/Options.py
@@ -7,58 +7,26 @@
 cmds='distclean configure build install clean uninstall check dist distcheck'.split()
 options={}
 commands=[]
+envvars=[]
 lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
-try:cache_global=os.path.abspath(os.environ['WAFCACHE'])
-except KeyError:cache_global=''
 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))
 		self.formatter.width=Logs.get_term_cols()
-		p=self.add_option
 		self.ctx=ctx
-		jobs=ctx.jobs()
-		p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
-		p('-k','--keep',dest='keep',default=0,action='count',help='keep running happily even if errors are found')
-		p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
-		p('--nocache',dest='nocache',default=False,action='store_true',help='ignore the WAFCACHE (if set)')
-		p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
-		gr=optparse.OptionGroup(self,'configure options')
-		self.add_option_group(gr)
-		gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
-		gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
-		default_prefix=os.environ.get('PREFIX')
-		if not default_prefix:
-			if platform=='win32':
-				d=tempfile.gettempdir()
-				default_prefix=d[0].upper()+d[1:]
-			else:
-				default_prefix='/usr/local/'
-		gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
-		gr.add_option('--download',dest='download',default=False,action='store_true',help='try to download the tools if missing')
-		gr=optparse.OptionGroup(self,'build and install options')
-		self.add_option_group(gr)
-		gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
-		gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
-		gr=optparse.OptionGroup(self,'step options')
-		self.add_option_group(gr)
-		gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
-		default_destdir=os.environ.get('DESTDIR','')
-		gr=optparse.OptionGroup(self,'install/uninstall options')
-		self.add_option_group(gr)
-		gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
-		gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
-		gr.add_option('--distcheck-args',help='arguments to pass to distcheck',default=None,action='store')
+	def print_usage(self,file=None):
+		return self.print_help(file)
 	def get_usage(self):
 		cmds_str={}
 		for cls in Context.classes:
-			if not cls.cmd or cls.cmd=='options':
+			if not cls.cmd or cls.cmd=='options'or cls.cmd.startswith('_'):
 				continue
 			s=cls.__doc__ or''
 			cmds_str[cls.cmd]=s
 		if Context.g_module:
 			for(k,v)in Context.g_module.__dict__.items():
-				if k in['options','init','shutdown']:
+				if k in('options','init','shutdown'):
 					continue
 				if type(v)is type(Context.create_context):
 					if v.__doc__ and not k.startswith('_'):
@@ -81,6 +49,41 @@
 		super(OptionsContext,self).__init__(**kw)
 		self.parser=opt_parser(self)
 		self.option_groups={}
+		jobs=self.jobs()
+		p=self.add_option
+		color=os.environ.get('NOCOLOR','')and'no'or'auto'
+		p('-c','--color',dest='colors',default=color,action='store',help='whether to use colors (yes/no/auto) [default: auto]',choices=('yes','no','auto'))
+		p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
+		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)')
+		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')
+		gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
+		default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX'))
+		if not default_prefix:
+			if platform=='win32':
+				d=tempfile.gettempdir()
+				default_prefix=d[0].upper()+d[1:]
+			else:
+				default_prefix='/usr/local/'
+		gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
+		gr.add_option('--bindir',dest='bindir',help='bindir')
+		gr.add_option('--libdir',dest='libdir',help='libdir')
+		gr=self.add_option_group('Build and installation options')
+		self.option_groups['build and install options']=gr
+		gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
+		gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
+		gr=self.add_option_group('Step options')
+		self.option_groups['step options']=gr
+		gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
+		default_destdir=os.environ.get('DESTDIR','')
+		gr=self.add_option_group('Installation and uninstallation options')
+		self.option_groups['install/uninstall options']=gr
+		gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
+		gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
+		gr.add_option('--distcheck-args',metavar='ARGS',help='arguments to pass to distcheck',default=None,action='store')
 	def jobs(self):
 		count=int(os.environ.get('JOBS',0))
 		if count<1:
@@ -123,13 +126,19 @@
 					return group
 			return None
 	def parse_args(self,_args=None):
-		global options,commands
+		global options,commands,envvars
 		(options,leftover_args)=self.parser.parse_args(args=_args)
-		commands=leftover_args
+		for arg in leftover_args:
+			if'='in arg:
+				envvars.append(arg)
+			else:
+				commands.append(arg)
 		if options.destdir:
 			options.destdir=os.path.abspath(os.path.expanduser(options.destdir))
 		if options.verbose>=1:
 			self.load('errcheck')
+		colors={'yes':2,'auto':1,'no':0}[options.colors]
+		Logs.enable_colors(colors)
 	def execute(self):
 		super(OptionsContext,self).execute()
 		self.parse_args()
--- a/waflib/Runner.py
+++ b/waflib/Runner.py
@@ -109,10 +109,6 @@
 		self.count-=1
 		self.dirty=True
 		return tsk
-	def error_handler(self,tsk):
-		if not self.bld.keep:
-			self.stop=True
-		self.error.append(tsk)
 	def add_task(self,tsk):
 		try:
 			self.pool
@@ -143,6 +139,31 @@
 			for x in pool:
 				put_pool(x)
 			self.pool=[]
+	def skip(self,tsk):
+		tsk.hasrun=Task.SKIPPED
+	def error_handler(self,tsk):
+		if not self.bld.keep:
+			self.stop=True
+		self.error.append(tsk)
+	def task_status(self,tsk):
+		try:
+			return tsk.runnable_status()
+		except Exception:
+			self.processed+=1
+			tsk.err_msg=Utils.ex_stack()
+			if not self.stop and self.bld.keep:
+				self.skip(tsk)
+				if self.bld.keep==1:
+					if Logs.verbose>1 or not self.error:
+						self.error.append(tsk)
+					self.stop=True
+				else:
+					if Logs.verbose>1:
+						self.error.append(tsk)
+				return Task.EXCEPTION
+			tsk.hasrun=Task.EXCEPTION
+			self.error_handler(tsk)
+			return Task.EXCEPTION
 	def start(self):
 		self.total=self.bld.total()
 		while not self.stop:
@@ -158,31 +179,8 @@
 				continue
 			if self.stop:
 				break
-			try:
-				st=tsk.runnable_status()
-			except Exception:
-				self.processed+=1
-				tsk.err_msg=Utils.ex_stack()
-				if not self.stop and self.bld.keep:
-					tsk.hasrun=Task.SKIPPED
-					if self.bld.keep==1:
-						if Logs.verbose>1 or not self.error:
-							self.error.append(tsk)
-						self.stop=True
-					else:
-						if Logs.verbose>1:
-							self.error.append(tsk)
-					continue
-				tsk.hasrun=Task.EXCEPTION
-				self.error_handler(tsk)
-				continue
-			if st==Task.ASK_LATER:
-				self.postpone(tsk)
-			elif st==Task.SKIP_ME:
-				self.processed+=1
-				tsk.hasrun=Task.SKIPPED
-				self.add_more_tasks(tsk)
-			else:
+			st=self.task_status(tsk)
+			if st==Task.RUN_ME:
 				tsk.position=(self.processed,self.total)
 				self.count+=1
 				tsk.master=self
@@ -191,6 +189,12 @@
 					tsk.process()
 				else:
 					self.add_task(tsk)
+			if st==Task.ASK_LATER:
+				self.postpone(tsk)
+			elif st==Task.SKIP_ME:
+				self.processed+=1
+				self.skip(tsk)
+				self.add_more_tasks(tsk)
 		while self.error and self.count:
 			self.get_out()
 		assert(self.count==0 or self.stop)
--- a/waflib/Scripting.py
+++ b/waflib/Scripting.py
@@ -18,14 +18,20 @@
 		ctx.curdir=current_directory
 		ctx.parse_args()
 		sys.exit(0)
+	if len(sys.argv)>1:
+		potential_wscript=os.path.join(current_directory,sys.argv[1])
+		if os.path.basename(potential_wscript)=='wscript'and os.path.isfile(potential_wscript):
+			current_directory=os.path.normpath(os.path.dirname(potential_wscript))
+			sys.argv.pop(1)
 	Context.waf_dir=wafdir
 	Context.launch_dir=current_directory
 	no_climb=os.environ.get('NOCLIMB',None)
 	if not no_climb:
 		for k in no_climb_commands:
-			if k in sys.argv:
-				no_climb=True
-				break
+			for y in sys.argv:
+				if y.startswith(k):
+					no_climb=True
+					break
 	cur=current_directory
 	while cur:
 		lst=os.listdir(cur)
@@ -37,7 +43,7 @@
 			except Exception:
 				pass
 			else:
-				for x in[env.run_dir,env.top_dir,env.out_dir]:
+				for x in(env.run_dir,env.top_dir,env.out_dir):
 					if Utils.is_win32:
 						if cur==x:
 							load=True
@@ -84,7 +90,7 @@
 		Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
 		sys.exit(1)
 	try:
-		set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE)
+		set_main_module(os.path.join(Context.run_dir,Context.WSCRIPT_FILE))
 	except Errors.WafError ,e:
 		Logs.pprint('RED',e.verbose_msg)
 		Logs.error(str(e))
@@ -115,7 +121,7 @@
 		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(update,dist,distclean,distcheck,update):
 		set_def(k)
 	if not'init'in Context.g_module.__dict__:
 		Context.g_module.init=Utils.nada
@@ -125,11 +131,13 @@
 		Context.g_module.options=Utils.nada
 def parse_options():
 	Context.create_context('options').execute()
+	for var in Options.envvars:
+		(name,value)=var.split('=',1)
+		os.environ[name.strip()]=value
 	if not Options.commands:
 		Options.commands=[default_cmd]
 	Options.commands=[x for x in Options.commands if x!='options']
 	Logs.verbose=Options.options.verbose
-	Logs.init_log()
 	if Options.options.zones:
 		Logs.zones=Options.options.zones.split(',')
 		if not Logs.verbose:
@@ -143,7 +151,10 @@
 	ctx.log_timer=Utils.Timer()
 	ctx.options=Options.options
 	ctx.cmd=cmd_name
-	ctx.execute()
+	try:
+		ctx.execute()
+	finally:
+		ctx.finalize()
 	return ctx
 def run_commands():
 	parse_options()
@@ -162,12 +173,12 @@
 	for(root,dirs,files)in os.walk(dirname):
 		for f in files:
 			if _can_distclean(f):
-				fname=root+os.sep+f
+				fname=os.path.join(root,f)
 				try:
 					os.remove(fname)
 				except OSError:
 					Logs.warn('Could not remove %r'%fname)
-	for x in[Context.DBFILE,'config.log']:
+	for x in(Context.DBFILE,'config.log'):
 		try:
 			os.remove(x)
 		except OSError:
@@ -193,15 +204,16 @@
 					pass
 				except OSError ,e:
 					if e.errno!=errno.ENOENT:
-						Logs.warn('project %r cannot be removed'%proj[Context.OUT])
+						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']):
+				p=os.path.join(k,Options.lockfile)
 				try:
-					os.remove(os.path.join(k,Options.lockfile))
+					os.remove(p)
 				except OSError ,e:
 					if e.errno!=errno.ENOENT:
-						Logs.warn('file %r cannot be removed'%f)
+						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):
@@ -225,7 +237,7 @@
 		node=self.base_path.make_node(arch_name)
 		try:
 			node.delete()
-		except Exception:
+		except OSError:
 			pass
 		files=self.get_files()
 		if self.algo.startswith('tar.'):
@@ -241,7 +253,7 @@
 				zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
 			zip.close()
 		else:
-			self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
+			self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip')
 		try:
 			from hashlib import sha1 as sha
 		except ImportError:
@@ -290,10 +302,11 @@
 		try:
 			return self.excl
 		except AttributeError:
-			self.excl=Node.exclude_regs+' **/waf-1.7.* **/.waf-1.7* **/waf3-1.7.* **/.waf3-1.7* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
-			nd=self.root.find_node(Context.out_dir)
-			if nd:
-				self.excl+=' '+nd.path_from(self.base_path)
+			self.excl=Node.exclude_regs+' **/waf-1.8.* **/.waf-1.8* **/waf3-1.8.* **/.waf3-1.8* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
+			if Context.out_dir:
+				nd=self.root.find_node(Context.out_dir)
+				if nd:
+					self.excl+=' '+nd.path_from(self.base_path)
 			return self.excl
 	def get_files(self):
 		try:
@@ -369,6 +382,8 @@
 		if do_config:
 			Options.commands.insert(0,self.cmd)
 			Options.commands.insert(0,'configure')
+			if Configure.autoconfig=='clobber':
+				Options.options.__dict__=env.options
 			return
 		return execute_method(self)
 	return execute
--- a/waflib/Task.py
+++ b/waflib/Task.py
@@ -2,7 +2,7 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,shutil,re,tempfile
+import os,re,sys
 from waflib import Utils,Logs,Errors
 NOT_RUN=0
 MISSING=1
@@ -37,24 +37,6 @@
 	lst = [x for x in lst if x]
 	return tsk.exec_command(lst, cwd=wd, env=env.env or None)
 '''
-def cache_outputs(cls):
-	m1=cls.run
-	def run(self):
-		bld=self.generator.bld
-		if bld.cache_global and not bld.nocache:
-			if self.can_retrieve_cache():
-				return 0
-		return m1(self)
-	cls.run=run
-	m2=cls.post_run
-	def post_run(self):
-		bld=self.generator.bld
-		ret=m2(self)
-		if bld.cache_global and not bld.nocache:
-			self.put_files_cache()
-		return ret
-	cls.post_run=post_run
-	return cls
 classes={}
 class store_task_type(type):
 	def __init__(cls,name,bases,dict):
@@ -67,6 +49,7 @@
 			if getattr(cls,'run_str',None):
 				(f,dvars)=compile_fun(cls.run_str,cls.shell)
 				cls.hcode=cls.run_str
+				cls.orig_run_str=cls.run_str
 				cls.run_str=None
 				cls.run=f
 				cls.vars=list(set(cls.vars+dvars))
@@ -73,8 +56,8 @@
 				cls.vars.sort()
 			elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
 				cls.hcode=Utils.h_fun(cls.run)
-			if not getattr(cls,'nocache',None):
-				cls=cache_outputs(cls)
+			if sys.hexversion>0x3000000:
+				cls.hcode=cls.hcode.encode('iso8859-1','xmlcharrefreplace')
 			getattr(cls,'register',classes)[name]=cls
 evil=store_task_type('evil',(object,),{})
 class TaskBase(evil):
@@ -94,10 +77,14 @@
 		return'\n\t{task %r: %s %s}'%(self.__class__.__name__,id(self),str(getattr(self,'fun','')))
 	def __str__(self):
 		if hasattr(self,'fun'):
-			return'executing: %s\n'%self.fun.__name__
-		return self.__class__.__name__+'\n'
+			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):
 		bld=self.generator.bld
 		try:
@@ -150,7 +137,20 @@
 	def post_run(self):
 		pass
 	def log_display(self,bld):
-		bld.to_log(self.display())
+		if self.generator.bld.progress_bar==3:
+			return
+		s=self.display()
+		if s:
+			if bld.logger:
+				logger=bld.logger
+			else:
+				logger=Logs
+			if self.generator.bld.progress_bar==1:
+				c1=Logs.colors.cursor_off
+				c2=Logs.colors.cursor_on
+				logger.info(s,extra={'stream':sys.stderr,'terminator':'','c1':c1,'c2':c2})
+			else:
+				logger.info(s,extra={'terminator':'','c1':'','c2':''})
 	def display(self):
 		col1=Logs.colors(self.color)
 		col2=Logs.colors.NORMAL
@@ -178,8 +178,11 @@
 			return None
 		total=master.total
 		n=len(str(total))
-		fs='[%%%dd/%%%dd] %%s%%s%%s'%(n,n)
-		return fs%(cur(),total,col1,s,col2)
+		fs='[%%%dd/%%%dd] %%s%%s%%s%%s\n'%(n,n)
+		kw=self.keyword()
+		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)
@@ -207,6 +210,8 @@
 			return'invalid status for task in %r: %r'%(name,self.hasrun)
 	def colon(self,var1,var2):
 		tmp=self.env[var1]
+		if not tmp:
+			return[]
 		if isinstance(var2,str):
 			it=self.env[var2]
 		else:
@@ -214,8 +219,6 @@
 		if isinstance(tmp,str):
 			return[tmp%x for x in it]
 		else:
-			if Logs.verbose and not tmp and it:
-				Logs.warn('Missing env variable %r for task %r (generator %r)'%(var1,self,self.generator))
 			lst=[]
 			for y in it:
 				lst.extend(tmp)
@@ -232,12 +235,33 @@
 		self.dep_nodes=[]
 		self.run_after=set([])
 	def __str__(self):
-		env=self.env
-		src_str=' '.join([a.nice_path()for a in self.inputs])
-		tgt_str=' '.join([a.nice_path()for a in self.outputs])
+		name=self.__class__.__name__
+		if self.outputs:
+			if(name.endswith('lib')or name.endswith('program'))or not self.inputs:
+				node=self.outputs[0]
+				return node.path_from(node.ctx.launch_node())
+		if not(self.inputs or self.outputs):
+			return self.__class__.__name__
+		if len(self.inputs)==1:
+			node=self.inputs[0]
+			return node.path_from(node.ctx.launch_node())
+		src_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.inputs])
+		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\n'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
+		return'%s: %s%s%s'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
+	def keyword(self):
+		name=self.__class__.__name__
+		if name.endswith('lib')or name.endswith('program'):
+			return'Linking'
+		if len(self.inputs)==1 and len(self.outputs)==1:
+			return'Compiling'
+		if not self.inputs:
+			if self.outputs:
+				return'Creating'
+			else:
+				return'Running'
+		return'Processing'
 	def __repr__(self):
 		try:
 			ins=",".join([x.name for x in self.inputs])
@@ -361,9 +385,11 @@
 			try:
 				if prev==self.compute_sig_implicit_deps():
 					return prev
-			except Exception:
+			except Errors.TaskNotReady:
+				raise
+			except EnvironmentError:
 				for x in bld.node_deps.get(self.uid(),[]):
-					if x.is_child_of(bld.srcnode):
+					if not x.is_bld():
 						try:
 							os.stat(x.abspath())
 						except OSError:
@@ -419,71 +445,20 @@
 			for tsk in self.run_after:
 				if not tsk.hasrun:
 					raise Errors.TaskNotReady('not ready')
-	def can_retrieve_cache(self):
-		if not getattr(self,'outputs',None):
-			return None
-		sig=self.signature()
-		ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
-		dname=os.path.join(self.generator.bld.cache_global,ssig)
+if sys.hexversion>0x3000000:
+	def uid(self):
 		try:
-			t1=os.stat(dname).st_mtime
-		except OSError:
-			return None
-		for node in self.outputs:
-			orig=os.path.join(dname,node.name)
-			try:
-				shutil.copy2(orig,node.abspath())
-				os.utime(orig,None)
-			except(OSError,IOError):
-				Logs.debug('task: failed retrieving file')
-				return None
-		try:
-			t2=os.stat(dname).st_mtime
-		except OSError:
-			return None
-		if t1!=t2:
-			return None
-		for node in self.outputs:
-			node.sig=sig
-			if self.generator.bld.progress_bar<1:
-				self.generator.bld.to_log('restoring from cache %r\n'%node.abspath())
-		self.cached=True
-		return True
-	def put_files_cache(self):
-		if getattr(self,'cached',None):
-			return None
-		if not getattr(self,'outputs',None):
-			return None
-		sig=self.signature()
-		ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
-		dname=os.path.join(self.generator.bld.cache_global,ssig)
-		tmpdir=tempfile.mkdtemp(prefix=self.generator.bld.cache_global+os.sep+'waf')
-		try:
-			shutil.rmtree(dname)
-		except Exception:
-			pass
-		try:
-			for node in self.outputs:
-				dest=os.path.join(tmpdir,node.name)
-				shutil.copy2(node.abspath(),dest)
-		except(OSError,IOError):
-			try:
-				shutil.rmtree(tmpdir)
-			except Exception:
-				pass
-		else:
-			try:
-				os.rename(tmpdir,dname)
-			except OSError:
-				try:
-					shutil.rmtree(tmpdir)
-				except Exception:
-					pass
-			else:
-				try:
-					os.chmod(dname,Utils.O755)
-				except Exception:
-					pass
+			return self.uid_
+		except AttributeError:
+			m=Utils.md5()
+			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()
+			return self.uid_
+	uid.__doc__=Task.uid.__doc__
+	Task.uid=uid
 def is_before(t1,t2):
 	to_list=Utils.to_list
 	for k in to_list(t2.ext_in):
@@ -578,6 +553,7 @@
 	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)
--- a/waflib/TaskGen.py
+++ b/waflib/TaskGen.py
@@ -5,8 +5,9 @@
 import copy,re,os
 from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
 feats=Utils.defaultdict(set)
+HEADER_EXTS=['.h','.hpp','.hxx','.hh']
 class task_gen(object):
-	mappings={}
+	mappings=Utils.ordered_iter_dict()
 	prec=Utils.defaultdict(list)
 	def __init__(self,*k,**kw):
 		self.source=''
@@ -36,7 +37,7 @@
 	def __repr__(self):
 		lst=[]
 		for x in self.__dict__.keys():
-			if x not in['env','bld','compiled_tasks','tasks']:
+			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_name(self):
@@ -111,27 +112,29 @@
 		return True
 	def get_hook(self,node):
 		name=node.name
-		for k in self.mappings:
-			if name.endswith(k):
-				return self.mappings[k]
+		if self.mappings:
+			for k in self.mappings:
+				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 (did you forget to load a waf tool?)"%(node,task_gen.mappings.keys()))
-	def create_task(self,name,src=None,tgt=None):
+		raise Errors.WafError("File %r has no mapping in %r (have you forgotten to load a waf tool?)"%(node,task_gen.mappings.keys()))
+	def create_task(self,name,src=None,tgt=None,**kw):
 		task=Task.classes[name](env=self.env.derive(),generator=self)
 		if src:
 			task.set_inputs(src)
 		if tgt:
 			task.set_outputs(tgt)
+		task.__dict__.update(kw)
 		self.tasks.append(task)
 		return task
 	def clone(self,env):
 		newobj=self.bld()
 		for x in self.__dict__:
-			if x in['env','bld']:
+			if x in('env','bld'):
 				continue
-			elif x in['path','features']:
+			elif x in('path','features'):
 				setattr(newobj,x,getattr(self,x))
 			else:
 				setattr(newobj,x,copy.copy(getattr(self,x)))
@@ -153,7 +156,7 @@
 			_ext_in=ext_in[0]
 		tsk=self.create_task(name,node)
 		cnt=0
-		keys=list(self.mappings.keys())+list(self.__class__.mappings.keys())
+		keys=set(self.mappings.keys())|set(self.__class__.mappings.keys())
 		for x in ext:
 			k=node.change_ext(x,ext_in=_ext_in)
 			tsk.outputs.append(k)
@@ -212,7 +215,7 @@
 	tmp=[]
 	path=path or self.path
 	find=path.find_resource
-	if isinstance(lst,self.path.__class__):
+	if isinstance(lst,Node.Node):
 		lst=[lst]
 	for x in Utils.to_list(lst):
 		if isinstance(x,str):
@@ -262,7 +265,7 @@
 			Task.update_outputs(cls)
 		if getattr(self,'always',None):
 			Task.always_run(cls)
-		for x in['after','before','ext_in','ext_out']:
+		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
@@ -307,11 +310,11 @@
 				os.chmod(self.outputs[0].abspath(),self.generator.chmod)
 			return None
 		if getattr(self.generator,'fun',None):
-			self.generator.fun(self)
+			return self.generator.fun(self)
 		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:
+			if code is not None:
 				self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
 			return
 		code=code.replace('%','%%')
@@ -329,8 +332,12 @@
 		except AttributeError:
 			d={}
 			for x in lst:
-				tmp=getattr(self.generator,x,'')or self.env.get_flat(x)or self.env.get_flat(x.upper())
-				d[x]=str(tmp)
+				tmp=getattr(self.generator,x,'')or self.env[x]or self.env[x.upper()]
+				try:
+					tmp=''.join(tmp)
+				except TypeError:
+					tmp=str(tmp)
+				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
@@ -397,8 +404,12 @@
 			if val:
 				has_constraints=True
 				setattr(tsk,k,val)
-		if not has_constraints and b.name.endswith('.h'):
-			tsk.before=[k for k in('c','cxx')if k in Task.classes]
+		if not has_constraints:
+			global HEADER_EXTS
+			for xt in HEADER_EXTS:
+				if b.name.endswith(xt):
+					tsk.before=[k for k in('c','cxx')if k in Task.classes]
+					break
 		inst_to=getattr(self,'install_path',None)
 		if inst_to:
 			self.bld.install_files(inst_to,b,chmod=getattr(self,'chmod',Utils.O644))
--- a/waflib/Tools/ar.py
+++ b/waflib/Tools/ar.py
@@ -8,4 +8,6 @@
 	conf.load('ar')
 def configure(conf):
 	conf.find_program('ar',var='AR')
-	conf.env.ARFLAGS='rcs'
+	conf.add_os_flags('ARFLAGS')
+	if not conf.env.ARFLAGS:
+		conf.env.ARFLAGS=['rcs']
--- a/waflib/Tools/asm.py
+++ b/waflib/Tools/asm.py
@@ -9,7 +9,7 @@
 from waflib.TaskGen import extension,feature
 class asm(Task.Task):
 	color='BLUE'
-	run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
+	run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
 @extension('.s','.S','.asm','.ASM','.spp','.SPP')
 def asm_hook(self,node):
 	return self.create_compiled_task('asm',node)
--- a/waflib/Tools/c.py
+++ b/waflib/Tools/c.py
@@ -7,9 +7,11 @@
 from waflib.Tools.ccroot import link_task,stlink_task
 @TaskGen.extension('.c')
 def c_hook(self,node):
+	if not self.env.CC and self.env.CXX:
+		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}'
+	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()}'
 	vars=['CCDEPS']
 	ext_in=['.h']
 	scan=c_preproc.scan
--- a/waflib/Tools/c_aliases.py
+++ b/waflib/Tools/c_aliases.py
@@ -29,9 +29,9 @@
 		feats.append('java')
 	if'java'in exts:
 		return'java'
-	if type in['program','shlib','stlib']:
+	if type in('program','shlib','stlib'):
 		for x in feats:
-			if x in['cxx','d','c']:
+			if x in('cxx','d','c'):
 				feats.append(x+type)
 	return feats
 def set_features(kw,_type):
--- a/waflib/Tools/c_config.py
+++ b/waflib/Tools/c_config.py
@@ -43,15 +43,19 @@
 MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'msys','_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',}
 @conf
-def parse_flags(self,line,uselib_store,env=None,force_static=False):
+def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None):
 	assert(isinstance(line,str))
 	env=env or self.env
-	app=env.append_value
-	appu=env.append_unique
-	lex=shlex.shlex(line,posix=False)
+	if posix is None:
+		posix=True
+		if'\\'in line:
+			posix=('\\ 'in line)or('\\\\'in line)
+	lex=shlex.shlex(line,posix=posix)
 	lex.whitespace_split=True
 	lex.commenters=''
 	lst=list(lex)
+	app=env.append_value
+	appu=env.append_unique
 	uselib=uselib_store
 	while lst:
 		x=lst.pop(0)
@@ -60,7 +64,7 @@
 		if st=='-I'or st=='/I':
 			if not ot:ot=lst.pop(0)
 			appu('INCLUDES_'+uselib,[ot])
-		elif st=='-include':
+		elif st=='-i':
 			tmp=[x,lst.pop(0)]
 			app('CFLAGS',tmp)
 			app('CXXFLAGS',tmp)
@@ -84,6 +88,12 @@
 			appu('FRAMEWORK_'+uselib,[lst.pop(0)])
 		elif x.startswith('-F'):
 			appu('FRAMEWORKPATH_'+uselib,[x[2:]])
+		elif x=='-Wl,-rpath':
+			app('RPATH_'+uselib,lst.pop(0))
+		elif x.startswith('-Wl,-R'):
+			app('RPATH_'+uselib,x[6:])
+		elif x.startswith('-Wl,-rpath,'):
+			app('RPATH_'+uselib,x[11:])
 		elif x.startswith('-Wl'):
 			app('LINKFLAGS_'+uselib,[x])
 		elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
@@ -91,7 +101,7 @@
 			app('CXXFLAGS_'+uselib,[x])
 		elif x.startswith('-bundle'):
 			app('LINKFLAGS_'+uselib,[x])
-		elif x.startswith('-undefined'):
+		elif x.startswith('-undefined')or x.startswith('-Xlinker'):
 			arg=lst.pop(0)
 			app('LINKFLAGS_'+uselib,[x,arg])
 		elif x.startswith('-arch')or x.startswith('-isysroot'):
@@ -102,11 +112,6 @@
 		elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
 			appu('LINKFLAGS_'+uselib,[x])
 @conf
-def ret_msg(self,f,kw):
-	if isinstance(f,str):
-		return f
-	return f(kw)
-@conf
 def validate_cfg(self,kw):
 	if not'path'in kw:
 		if not self.env.PKGCONFIG:
@@ -132,14 +137,25 @@
 			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'uselib_store'in kw:
+		self.undefine(kw['define_name'])
 	if not'msg'in kw:
 		kw['msg']='Checking for %r'%(kw['package']or kw['path'])
 @conf
 def exec_cfg(self,kw):
+	path=Utils.to_list(kw['path'])
 	def define_it():
-		self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
+		pkgname=kw.get('uselib_store',kw['package'].upper())
+		if kw.get('global_define'):
+			self.define(self.have_define(kw['package']),1,False)
+		else:
+			self.env.append_unique('DEFINES_%s'%pkgname,"%s=1"%self.have_define(pkgname))
+		self.env[self.have_define(pkgname)]=1
 	if'atleast_pkgconfig_version'in kw:
-		cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+		cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
 		self.cmd_and_log(cmd)
 		if not'okmsg'in kw:
 			kw['okmsg']='yes'
@@ -147,22 +163,22 @@
 	for x in cfg_ver:
 		y=x.replace('-','_')
 		if y in kw:
-			self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']])
+			self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']])
 			if not'okmsg'in kw:
 				kw['okmsg']='yes'
 			define_it()
 			break
 	if'modversion'in kw:
-		version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']]).strip()
+		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)
 		return version
-	lst=[kw['path']]
+	lst=[]+path
 	defi=kw.get('define_variable',None)
 	if not defi:
 		defi=self.env.PKG_CONFIG_DEFINES or{}
 	for key,val in defi.items():
 		lst.append('--define-variable=%s=%s'%(key,val))
-	static=False
+	static=kw.get('force_static',False)
 	if'args'in kw:
 		args=Utils.to_list(kw['args'])
 		if'--static'in args or'--static-libs'in args:
@@ -184,7 +200,7 @@
 	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)
+	self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static,posix=kw.get('posix',None))
 	return ret
 @conf
 def check_cfg(self,*k,**kw):
@@ -194,24 +210,37 @@
 		kw['args']=' '.join(lst[1:])
 	self.validate_cfg(kw)
 	if'msg'in kw:
-		self.start_msg(kw['msg'])
+		self.start_msg(kw['msg'],**kw)
 	ret=None
 	try:
 		ret=self.exec_cfg(kw)
 	except self.errors.WafError:
 		if'errmsg'in kw:
-			self.end_msg(kw['errmsg'],'YELLOW')
+			self.end_msg(kw['errmsg'],'YELLOW',**kw)
 		if Logs.verbose>1:
 			raise
 		else:
 			self.fatal('The configuration failed')
 	else:
+		if not ret:
+			ret=True
 		kw['success']=ret
 		if'okmsg'in kw:
-			self.end_msg(self.ret_msg(kw['okmsg'],kw))
+			self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
 	return ret
+def build_fun(bld):
+	if bld.kw['compile_filename']:
+		node=bld.srcnode.make_node(bld.kw['compile_filename'])
+		node.write(bld.kw['code'])
+	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):
+		bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
 @conf
 def validate_c(self,kw):
+	if not'build_fun'in kw:
+		kw['build_fun']=build_fun
 	if not'env'in kw:
 		kw['env']=self.env.derive()
 	env=kw['env']
@@ -306,7 +335,7 @@
 			kw['msg']='Checking for code snippet'
 		if not'errmsg'in kw:
 			kw['errmsg']='no'
-	for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
+	for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')):
 		if flagsname in kw:
 			if not'msg'in kw:
 				kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
@@ -368,12 +397,12 @@
 @conf
 def check(self,*k,**kw):
 	self.validate_c(kw)
-	self.start_msg(kw['msg'])
+	self.start_msg(kw['msg'],**kw)
 	ret=None
 	try:
-		ret=self.run_c_code(*k,**kw)
+		ret=self.run_build(*k,**kw)
 	except self.errors.ConfigurationError:
-		self.end_msg(kw['errmsg'],'YELLOW')
+		self.end_msg(kw['errmsg'],'YELLOW',**kw)
 		if Logs.verbose>1:
 			raise
 		else:
@@ -382,10 +411,10 @@
 		kw['success']=ret
 	ret=self.post_check(*k,**kw)
 	if not ret:
-		self.end_msg(kw['errmsg'],'YELLOW')
+		self.end_msg(kw['errmsg'],'YELLOW',**kw)
 		self.fatal('The configuration failed %r'%ret)
 	else:
-		self.end_msg(self.ret_msg(kw['okmsg'],kw))
+		self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
 	return ret
 class test_exec(Task.Task):
 	color='PINK'
@@ -408,65 +437,7 @@
 @after_method('apply_link')
 def test_exec_fun(self):
 	self.create_task('test_exec',self.link_task.outputs[0])
-CACHE_RESULTS=1
-COMPILE_ERRORS=2
 @conf
-def run_c_code(self,*k,**kw):
-	lst=[str(v)for(p,v)in kw.items()if p!='env']
-	h=Utils.h_list(lst)
-	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
-	try:
-		os.makedirs(dir)
-	except OSError:
-		pass
-	try:
-		os.stat(dir)
-	except OSError:
-		self.fatal('cannot use the configuration test folder %r'%dir)
-	cachemode=getattr(Options.options,'confcache',None)
-	if cachemode==CACHE_RESULTS:
-		try:
-			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
-		except OSError:
-			pass
-		else:
-			ret=proj['cache_run_c_code']
-			if isinstance(ret,str)and ret.startswith('Test does not build'):
-				self.fatal(ret)
-			return ret
-	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)
-	bld.init_dirs()
-	bld.progress_bar=0
-	bld.targets='*'
-	if kw['compile_filename']:
-		node=bld.srcnode.make_node(kw['compile_filename'])
-		node.write(kw['code'])
-	bld.logger=self.logger
-	bld.all_envs.update(self.all_envs)
-	bld.env=kw['env']
-	o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
-	for k,v in kw.items():
-		setattr(o,k,v)
-	self.to_log("==>\n%s\n<=="%kw['code'])
-	bld.targets='*'
-	ret=-1
-	try:
-		try:
-			bld.compile()
-		except Errors.WafError:
-			ret='Test does not build: %s'%Utils.ex_stack()
-			self.fatal(ret)
-		else:
-			ret=getattr(bld,'retval',0)
-	finally:
-		proj=ConfigSet.ConfigSet()
-		proj['cache_run_c_code']=ret
-		proj.store(os.path.join(dir,'cache_run_c_code'))
-	return ret
-@conf
 def check_cxx(self,*k,**kw):
 	kw['compiler']='cxx'
 	return self.check(*k,**kw)
@@ -529,9 +500,7 @@
 def have_define(self,key):
 	return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
 @conf
-def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
-	if env:
-		Logs.warn('Cannot pass env to write_config_header')
+def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''):
 	if not configfile:configfile=WAF_CONFIG_H
 	waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
 	node=top and self.bldnode or self.path.get_bld()
@@ -554,12 +523,16 @@
 		for x in self.env[INCKEYS]:
 			lst.append('#include <%s>'%x)
 	if defines:
-		for x in self.env[DEFKEYS]:
-			if self.is_defined(x):
-				val=self.get_define(x)
-				lst.append('#define %s %s'%(define_prefix+x,val))
-			else:
-				lst.append('/* #undef %s */'%(define_prefix+x))
+		tbl={}
+		for k in self.env['DEFINES']:
+			a,_,b=k.partition('=')
+			tbl[a]=b
+		for k in self.env[DEFKEYS]:
+			try:
+				txt='#define %s%s %s'%(define_prefix,k,tbl[k])
+			except KeyError:
+				txt='/* #undef %s%s */'%(define_prefix,k)
+			lst.append(txt)
 	return"\n".join(lst)
 @conf
 def cc_add_flags(conf):
@@ -584,7 +557,7 @@
 		conf.env.DEST_OS=Utils.unversioned_sys_platform()
 	conf.load('cxx')
 @conf
-def get_cc_version(conf,cc,gcc=False,icc=False):
+def get_cc_version(conf,cc,gcc=False,icc=False,clang=False):
 	cmd=cc+['-dM','-E','-']
 	env=conf.env.env or None
 	try:
@@ -602,8 +575,12 @@
 			conf.fatal('Could not determine the compiler type')
 	if icc and out.find('__INTEL_COMPILER')<0:
 		conf.fatal('Not icc/icpc')
+	if clang and out.find('__clang__')<0:
+		conf.fatal('Not clang/clang++')
+	if not clang and out.find('__clang__')>=0:
+		conf.fatal('Could not find g++, if renamed try eg: CXX=g++48 waf configure')
 	k={}
-	if icc or gcc:
+	if icc or gcc or clang:
 		out=out.splitlines()
 		for line in out:
 			lst=shlex.split(line)
@@ -645,9 +622,15 @@
 			conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
 		else:
 			if isD('__clang__'):
-				conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
+				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__'])
 			else:
-				conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+				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)
 	return k
 @conf
 def get_xlc_version(conf,cc):
@@ -687,7 +670,7 @@
 @conf
 def add_as_needed(self):
 	if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
-		self.env.append_unique('LINKFLAGS','--as-needed')
+		self.env.append_unique('LINKFLAGS','-Wl,--as-needed')
 class cfgtask(Task.TaskBase):
 	def display(self):
 		return''
@@ -708,12 +691,10 @@
 			return 1
 @conf
 def multicheck(self,*k,**kw):
-	self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
+	self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw)
 	class par(object):
 		def __init__(self):
 			self.keep=False
-			self.cache_global=Options.cache_global
-			self.nocache=Options.options.nocache
 			self.returned_tasks=[]
 			self.task_sigs={}
 		def total(self):
@@ -741,6 +722,6 @@
 		x.logger.memhandler.flush()
 	for x in tasks:
 		if x.hasrun!=Task.SUCCESS:
-			self.end_msg(kw.get('errmsg','no'),color='YELLOW')
+			self.end_msg(kw.get('errmsg','no'),color='YELLOW',**kw)
 			self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
-	self.end_msg('ok')
+	self.end_msg('ok',**kw)
--- a/waflib/Tools/c_preproc.py
+++ b/waflib/Tools/c_preproc.py
@@ -15,7 +15,7 @@
 	standard_includes=[]
 use_trigraphs=0
 strict_quotes=0
-g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',}
+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_mac=re.compile("^[a-zA-Z_]\w*")
 re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
@@ -71,17 +71,17 @@
 	elif d=='*':c=a*b
 	elif d=='/':c=a/b
 	elif d=='^':c=a^b
-	elif d=='|':c=a|b
-	elif d=='||':c=int(a or b)
-	elif d=='&':c=a&b
-	elif d=='&&':c=int(a and b)
 	elif d=='==':c=int(a==b)
-	elif d=='!=':c=int(a!=b)
+	elif d=='|'or d=='bitor':c=a|b
+	elif d=='||'or d=='or':c=int(a or b)
+	elif d=='&'or d=='bitand':c=a&b
+	elif d=='&&'or d=='and':c=int(a and b)
+	elif d=='!='or d=='not_eq':c=int(a!=b)
+	elif d=='^'or d=='xor':c=int(a^b)
 	elif d=='<=':c=int(a<=b)
 	elif d=='<':c=int(a<b)
 	elif d=='>':c=int(a>b)
 	elif d=='>=':c=int(a>=b)
-	elif d=='^':c=int(a^b)
 	elif d=='<<':c=a<<b
 	elif d=='>>':c=a>>b
 	else:c=0
@@ -381,7 +381,8 @@
 			return'"',toks[0][1]
 	else:
 		if toks[0][1]=='<'and toks[-1][1]=='>':
-			return stringize(toks).lstrip('<').rstrip('>')
+			ret='<',stringize(toks).lstrip('<').rstrip('>')
+			return ret
 	raise PreprocError("could not parse include %s."%txt)
 def parse_char(txt):
 	if not txt:raise PreprocError("attempted to parse a null char")
@@ -410,7 +411,9 @@
 			v=m(name)
 			if v:
 				if name==IDENT:
-					try:v=g_optrans[v];name=OP
+					try:
+						g_optrans[v];
+						name=OP
 					except KeyError:
 						if v.lower()=="true":
 							v=1
@@ -472,6 +475,9 @@
 			nd[tup]=ret
 			return ret
 	def tryfind(self,filename):
+		if filename.endswith('.moc'):
+			self.names.append(filename)
+			return None
 		self.curfile=filename
 		found=self.cached_find_resource(self.currentnode_stack[-1],filename)
 		for n in self.nodepaths:
@@ -480,8 +486,7 @@
 			found=self.cached_find_resource(n,filename)
 		if found and not found in self.ban_includes:
 			self.nodes.append(found)
-			if filename[-4:]!='.moc':
-				self.addlines(found)
+			self.addlines(found)
 		else:
 			if not filename in self.names:
 				self.names.append(filename)
@@ -519,8 +524,7 @@
 		try:
 			self.parse_cache=bld.parse_cache
 		except AttributeError:
-			bld.parse_cache={}
-			self.parse_cache=bld.parse_cache
+			self.parse_cache=bld.parse_cache={}
 		self.current_file=node
 		self.addlines(node)
 		if env['DEFINES']:
--- a/waflib/Tools/ccroot.py
+++ b/waflib/Tools/ccroot.py
@@ -75,12 +75,15 @@
 				if self.env.DEST_BINFMT=='pe':
 					name=name+'-'+nums[0]
 				elif self.env.DEST_OS=='openbsd':
-					pattern='%s.%s.%s'%(pattern,nums[0],nums[1])
+					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)
 		self.set_outputs(target)
 class stlink_task(link_task):
 	run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+	chmod=Utils.O644
 def rm_tgt(cls):
 	old=cls.run
 	def wrap(self):
@@ -111,7 +114,7 @@
 	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)
+		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)
 @taskgen_method
 def use_rec(self,name,**kw):
 	if name in self.tmp_use_not or name in self.tmp_use_seen:
@@ -139,6 +142,8 @@
 			y.tmp_use_var='STLIB'
 	p=self.tmp_use_prec
 	for x in self.to_list(getattr(y,'use',[])):
+		if self.env["STLIB_"+x]:
+			continue
 		try:
 			p[x].append(name)
 		except KeyError:
@@ -190,11 +195,11 @@
 		y=self.bld.get_tgen_by_name(x)
 		var=y.tmp_use_var
 		if var and link_task:
-			if var=='LIB'or y.tmp_use_stlib:
+			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)
-				self.env.append_value(var+'PATH',[tmp_path])
+				self.env.append_unique(var+'PATH',[tmp_path])
 		else:
 			if y.tmp_use_objects:
 				self.add_objects_from_tgen(y)
@@ -205,11 +210,11 @@
 	for x in names:
 		try:
 			y=self.bld.get_tgen_by_name(x)
-		except Exception:
+		except Errors.WafError:
 			if not self.env['STLIB_'+x]and not x in self.uselib:
 				self.uselib.append(x)
 		else:
-			for k in self.to_list(getattr(y,'uselib',[])):
+			for k in self.to_list(getattr(y,'use',[])):
 				if not self.env['STLIB_'+k]and not k in self.uselib:
 					self.uselib.append(k)
 @taskgen_method
@@ -238,16 +243,17 @@
 def propagate_uselib_vars(self):
 	_vars=self.get_uselib_vars()
 	env=self.env
-	for x in _vars:
-		y=x.lower()
-		env.append_unique(x,self.to_list(getattr(self,y,[])))
-	for x in self.features:
-		for var in _vars:
-			compvar='%s_%s'%(var,x)
-			env.append_value(var,env[compvar])
-	for x in self.to_list(getattr(self,'uselib',[])):
-		for v in _vars:
-			env.append_value(v,env[v+'_'+x])
+	app=env.append_value
+	feature_uselib=self.features+self.to_list(getattr(self,'uselib',[]))
+	for var in _vars:
+		y=var.lower()
+		val=getattr(self,y,[])
+		if val:
+			app(var,self.to_list(val))
+		for x in feature_uselib:
+			val=env['%s_%s'%(var,x)]
+			if val:
+				app(var,val)
 @feature('cshlib','cxxshlib','fcshlib')
 @after_method('apply_link')
 def apply_implib(self):
@@ -271,14 +277,19 @@
 			self.link_task.dep_nodes.append(node)
 		else:
 			self.link_task.inputs.append(node)
-	try:
-		inst_to=self.install_path
-	except AttributeError:
-		inst_to=self.link_task.__class__.inst_to
-	if not inst_to:
-		return
-	self.implib_install_task=self.bld.install_as('${LIBDIR}/%s'%implib.name,implib,self.env)
-re_vnum=re.compile('^([1-9]\\d*|0)[.]([1-9]\\d*|0)[.]([1-9]\\d*|0)$')
+	if getattr(self,'install_task',None):
+		try:
+			inst_to=self.install_path_implib
+		except AttributeError:
+			try:
+				inst_to=self.install_path
+			except AttributeError:
+				inst_to='${IMPLIBDIR}'
+				self.install_task.dest='${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)
+re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)[.]([1-9]\\d*|0))?$')
 @feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
 @after_method('apply_link','propagate_uselib_vars')
 def apply_vnum(self):
@@ -300,7 +311,10 @@
 		v=self.env.SONAME_ST%name2
 		self.env.append_value('LINKFLAGS',v.split())
 	if self.env.DEST_OS!='openbsd':
-		self.create_task('vnum',node,[node.parent.find_or_declare(name2),node.parent.find_or_declare(name3)])
+		outs=[node.parent.find_or_declare(name3)]
+		if name2!=name3:
+			outs.append(node.parent.find_or_declare(name2))
+		self.create_task('vnum',node,outs)
 	if getattr(self,'install_task',None):
 		self.install_task.hasrun=Task.SKIP_ME
 		bld=self.bld
@@ -311,9 +325,12 @@
 			self.vnum_install_task=(t1,)
 		else:
 			t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
-			t2=bld.symlink_as(path+os.sep+name2,name3)
 			t3=bld.symlink_as(path+os.sep+libname,name3)
-			self.vnum_install_task=(t1,t2,t3)
+			if name2!=name3:
+				t2=bld.symlink_as(path+os.sep+name2,name3)
+				self.vnum_install_task=(t1,t2,t3)
+			else:
+				self.vnum_install_task=(t1,t3)
 	if'-dynamiclib'in self.env['LINKFLAGS']:
 		try:
 			inst_to=self.install_path
@@ -327,6 +344,8 @@
 	color='CYAN'
 	quient=True
 	ext_in=['.bin']
+	def keyword(self):
+		return'Symlinking'
 	def run(self):
 		for x in self.outputs:
 			path=x.abspath()
--- /dev/null
+++ b/waflib/Tools/clang.py
@@ -1,0 +1,20 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+@conf
+def find_clang(conf):
+	cc=conf.find_program('clang',var='CC')
+	conf.get_cc_version(cc,clang=True)
+	conf.env.CC_NAME='clang'
+def configure(conf):
+	conf.find_clang()
+	conf.find_ar()
+	conf.gcc_common_flags()
+	conf.gcc_modifier_platform()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
--- /dev/null
+++ b/waflib/Tools/clangxx.py
@@ -1,0 +1,20 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+@conf
+def find_clangxx(conf):
+	cxx=conf.find_program('clang++',var='CXX')
+	conf.get_cc_version(cxx,clang=True)
+	conf.env.CXX_NAME='clang'
+def configure(conf):
+	conf.find_clangxx()
+	conf.find_ar()
+	conf.gxx_common_flags()
+	conf.gxx_modifier_platform()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
--- a/waflib/Tools/compiler_c.py
+++ b/waflib/Tools/compiler_c.py
@@ -2,17 +2,21 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,imp,types
+import os,sys,imp,types,re
 from waflib.Tools import ccroot
 from waflib import Utils,Configure
 from waflib.Logs import debug
-c_compiler={'win32':['msvc','gcc'],'cygwin':['gcc'],'darwin':['gcc'],'aix':['xlc','gcc'],'linux':['gcc','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'gnu':['gcc'],'java':['gcc','msvc','icc'],'default':['gcc'],}
+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'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['gcc','clang'],}
+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
+	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 test_for_compiler.split():
+	for compiler in re.split('[ ,]+',test_for_compiler):
 		conf.env.stash()
-		conf.start_msg('Checking for %r (c compiler)'%compiler)
+		conf.start_msg('Checking for %r (C compiler)'%compiler)
 		try:
 			conf.load(compiler)
 		except conf.errors.ConfigurationError ,e:
@@ -26,14 +30,11 @@
 				break
 			conf.end_msg(False)
 	else:
-		conf.fatal('could not configure a c compiler!')
+		conf.fatal('could not configure a C compiler!')
 def options(opt):
+	test_for_compiler=default_compilers()
 	opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
-	global c_compiler
-	build_platform=Utils.unversioned_sys_platform()
-	possible_compiler_list=c_compiler[build_platform in c_compiler and build_platform or'default']
-	test_for_compiler=' '.join(possible_compiler_list)
-	cc_compiler_opts=opt.add_option_group("C Compiler Options")
-	cc_compiler_opts.add_option('--check-c-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C-Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_c_compiler")
+	cc_compiler_opts=opt.add_option_group('Configuration options')
+	cc_compiler_opts.add_option('--check-c-compiler',default=None,help='list of C compilers to try [%s]'%test_for_compiler,dest="check_c_compiler")
 	for x in test_for_compiler.split():
 		opt.load('%s'%x)
--- a/waflib/Tools/compiler_cxx.py
+++ b/waflib/Tools/compiler_cxx.py
@@ -2,17 +2,21 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,imp,types
+import os,sys,imp,types,re
 from waflib.Tools import ccroot
 from waflib import Utils,Configure
 from waflib.Logs import debug
-cxx_compiler={'win32':['msvc','g++'],'cygwin':['g++'],'darwin':['g++'],'aix':['xlc++','g++'],'linux':['g++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'gnu':['g++'],'java':['g++','msvc','icpc'],'default':['g++']}
+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++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['g++','clang++']}
+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
+	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 test_for_compiler.split():
+	for compiler in re.split('[ ,]+',test_for_compiler):
 		conf.env.stash()
-		conf.start_msg('Checking for %r (c++ compiler)'%compiler)
+		conf.start_msg('Checking for %r (C++ compiler)'%compiler)
 		try:
 			conf.load(compiler)
 		except conf.errors.ConfigurationError ,e:
@@ -26,14 +30,11 @@
 				break
 			conf.end_msg(False)
 	else:
-		conf.fatal('could not configure a c++ compiler!')
+		conf.fatal('could not configure a C++ compiler!')
 def options(opt):
+	test_for_compiler=default_compilers()
 	opt.load_special_tools('cxx_*.py')
-	global cxx_compiler
-	build_platform=Utils.unversioned_sys_platform()
-	possible_compiler_list=cxx_compiler[build_platform in cxx_compiler and build_platform or'default']
-	test_for_compiler=' '.join(possible_compiler_list)
-	cxx_compiler_opts=opt.add_option_group('C++ Compiler Options')
-	cxx_compiler_opts.add_option('--check-cxx-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_cxx_compiler")
+	cxx_compiler_opts=opt.add_option_group('Configuration options')
+	cxx_compiler_opts.add_option('--check-cxx-compiler',default=None,help='list of C++ compilers to try [%s]'%test_for_compiler,dest="check_cxx_compiler")
 	for x in test_for_compiler.split():
 		opt.load('%s'%x)
--- a/waflib/Tools/compiler_d.py
+++ b/waflib/Tools/compiler_d.py
@@ -2,12 +2,19 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,imp,types
+import os,sys,imp,types,re
 from waflib import Utils,Configure,Options,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):
-	for compiler in conf.options.dcheck.split(','):
+	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)
+		conf.start_msg('Checking for %r (D compiler)'%compiler)
 		try:
 			conf.load(compiler)
 		except conf.errors.ConfigurationError ,e:
@@ -21,9 +28,10 @@
 				break
 			conf.end_msg(False)
 	else:
-		conf.fatal('no suitable d compiler was found')
+		conf.fatal('could not configure a D compiler!')
 def options(opt):
-	d_compiler_opts=opt.add_option_group('D Compiler Options')
-	d_compiler_opts.add_option('--check-d-compiler',default='gdc,dmd,ldc2',action='store',help='check for the compiler [Default:gdc,dmd,ldc2]',dest='dcheck')
-	for d_compiler in['gdc','dmd','ldc2']:
-		opt.load('%s'%d_compiler)
+	test_for_compiler=default_compilers()
+	d_compiler_opts=opt.add_option_group('Configuration options')
+	d_compiler_opts.add_option('--check-d-compiler',default=None,help='list of D compilers to try [%s]'%test_for_compiler,dest='check_d_compiler')
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
--- a/waflib/Tools/compiler_fc.py
+++ b/waflib/Tools/compiler_fc.py
@@ -2,21 +2,20 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,imp,types
+import os,sys,imp,types,re
 from waflib import Utils,Configure,Options,Logs,Errors
 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 __list_possible_compiler(platform):
-	try:
-		return fc_compiler[platform]
-	except KeyError:
-		return fc_compiler["default"]
+def default_compilers():
+	build_platform=Utils.unversioned_sys_platform()
+	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_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 test_for_compiler.split():
+	for compiler in re.split('[ ,]+',test_for_compiler):
 		conf.env.stash()
-		conf.start_msg('Checking for %r (fortran compiler)'%compiler)
+		conf.start_msg('Checking for %r (Fortran compiler)'%compiler)
 		try:
 			conf.load(compiler)
 		except conf.errors.ConfigurationError ,e:
@@ -30,14 +29,11 @@
 				break
 			conf.end_msg(False)
 	else:
-		conf.fatal('could not configure a fortran compiler!')
+		conf.fatal('could not configure a Fortran compiler!')
 def options(opt):
+	test_for_compiler=default_compilers()
 	opt.load_special_tools('fc_*.py')
-	build_platform=Utils.unversioned_sys_platform()
-	detected_platform=Options.platform
-	possible_compiler_list=__list_possible_compiler(detected_platform)
-	test_for_compiler=' '.join(possible_compiler_list)
-	fortran_compiler_opts=opt.add_option_group("Fortran Compiler Options")
-	fortran_compiler_opts.add_option('--check-fortran-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following Fortran Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_fc")
-	for compiler in test_for_compiler.split():
-		opt.load('%s'%compiler)
+	fortran_compiler_opts=opt.add_option_group('Configuration options')
+	fortran_compiler_opts.add_option('--check-fortran-compiler',default=None,help='list of Fortran compiler to try [%s]'%test_for_compiler,dest="check_fortran_compiler")
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
--- a/waflib/Tools/cxx.py
+++ b/waflib/Tools/cxx.py
@@ -11,7 +11,7 @@
 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}'
+	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()}'
 	vars=['CXXDEPS']
 	ext_in=['.h']
 	scan=c_preproc.scan
--- a/waflib/Tools/dmd.py
+++ b/waflib/Tools/dmd.py
@@ -8,9 +8,9 @@
 @conf
 def find_dmd(conf):
 	conf.find_program(['dmd','dmd2','ldc'],var='D')
-	out=conf.cmd_and_log([conf.env.D,'--help'])
+	out=conf.cmd_and_log(conf.env.D+['--help'])
 	if out.find("D Compiler v")==-1:
-		out=conf.cmd_and_log([conf.env.D,'-version'])
+		out=conf.cmd_and_log(conf.env.D+['-version'])
 		if out.find("based on DMD v1.")==-1:
 			conf.fatal("detected compiler is not dmd/ldc")
 @conf
@@ -40,7 +40,7 @@
 def configure(conf):
 	conf.find_dmd()
 	if sys.platform=='win32':
-		out=conf.cmd_and_log([conf.env.D,'--help'])
+		out=conf.cmd_and_log(conf.env.D+['--help'])
 		if out.find("D Compiler v2.")>-1:
 			conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
 	conf.load('ar')
--- a/waflib/Tools/fc.py
+++ b/waflib/Tools/fc.py
@@ -89,8 +89,6 @@
 class fcshlib(fcprogram):
 	inst_to='${LIBDIR}'
 class fcprogram_test(fcprogram):
-	def can_retrieve_cache(self):
-		return False
 	def runnable_status(self):
 		ret=super(fcprogram_test,self).runnable_status()
 		if ret==Task.SKIP_ME:
--- a/waflib/Tools/fc_config.py
+++ b/waflib/Tools/fc_config.py
@@ -2,10 +2,10 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import re,shutil,os,sys,string,shlex
+import re,os,sys,shlex
 from waflib.Configure import conf
-from waflib.TaskGen import feature,after_method,before_method
-from waflib import Build,Utils
+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'
 @conf
@@ -115,7 +115,7 @@
 @conf
 def check_fortran_verbose_flag(self,*k,**kw):
 	self.start_msg('fortran link verbose flag')
-	for x in['-v','--verbose','-verbose','-V']:
+	for x in('-v','--verbose','-verbose','-V'):
 		try:
 			self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
 		except self.errors.ConfigurationError:
@@ -148,6 +148,25 @@
 	return final_flags
 SPACE_OPTS=re.compile('^-[LRuYz]$')
 NOSPACE_OPTS=re.compile('^-[RL]')
+def _parse_flink_token(lexer,token,tmp_flags):
+	if _match_ignore(token):
+		pass
+	elif token.startswith('-lkernel32')and sys.platform=='cygwin':
+		tmp_flags.append(token)
+	elif SPACE_OPTS.match(token):
+		t=lexer.get_token()
+		if t.startswith('P,'):
+			t=t[2:]
+		for opt in t.split(os.pathsep):
+			tmp_flags.append('-L%s'%opt)
+	elif NOSPACE_OPTS.match(token):
+		tmp_flags.append(token)
+	elif POSIX_LIB_FLAGS.match(token):
+		tmp_flags.append(token)
+	else:
+		pass
+	t=lexer.get_token()
+	return t
 def _parse_flink_line(line,final_flags):
 	lexer=shlex.shlex(line,posix=True)
 	lexer.whitespace_split=True
@@ -154,26 +173,7 @@
 	t=lexer.get_token()
 	tmp_flags=[]
 	while t:
-		def parse(token):
-			if _match_ignore(token):
-				pass
-			elif token.startswith('-lkernel32')and sys.platform=='cygwin':
-				tmp_flags.append(token)
-			elif SPACE_OPTS.match(token):
-				t=lexer.get_token()
-				if t.startswith('P,'):
-					t=t[2:]
-				for opt in t.split(os.pathsep):
-					tmp_flags.append('-L%s'%opt)
-			elif NOSPACE_OPTS.match(token):
-				tmp_flags.append(token)
-			elif POSIX_LIB_FLAGS.match(token):
-				tmp_flags.append(token)
-			else:
-				pass
-			t=lexer.get_token()
-			return t
-		t=parse(t)
+		t=_parse_flink_token(lexer,t,tmp_flags)
 	final_flags.extend(tmp_flags)
 	return final_flags
 @conf
@@ -240,9 +240,9 @@
 	bld(features='fc fcstlib',source='test.f',target='test')
 	bld(features='c fcprogram',source='main.c',target='app',use='test')
 def mangling_schemes():
-	for u in['_','']:
-		for du in['','_']:
-			for c in["lower","upper"]:
+	for u in('_',''):
+		for du in('','_'):
+			for c in("lower","upper"):
 				yield(u,du,c)
 def mangle_name(u,du,c,name):
 	return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
@@ -274,7 +274,7 @@
 	self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
 @conf
 def detect_openmp(self):
-	for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
+	for x in('-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:
--- a/waflib/Tools/flex.py
+++ b/waflib/Tools/flex.py
@@ -28,5 +28,5 @@
 def configure(conf):
 	conf.find_program('flex',var='FLEX')
 	conf.env.FLEXFLAGS=['-t']
-	if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX):
+	if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX[0]):
 		conf.env.FLEX_MSYS=True
--- a/waflib/Tools/g95.py
+++ b/waflib/Tools/g95.py
@@ -9,7 +9,6 @@
 @conf
 def find_g95(conf):
 	fc=conf.find_program('g95',var='FC')
-	fc=conf.cmd_to_list(fc)
 	conf.get_g95_version(fc)
 	conf.env.FC_NAME='G95'
 @conf
--- a/waflib/Tools/gcc.py
+++ b/waflib/Tools/gcc.py
@@ -2,15 +2,15 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.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
 @conf
 def find_gcc(conf):
 	cc=conf.find_program(['gcc','cc'],var='CC')
-	cc=conf.cmd_to_list(cc)
 	conf.get_cc_version(cc,gcc=True)
 	conf.env.CC_NAME='gcc'
-	conf.env.CC=cc
 @conf
 def gcc_common_flags(conf):
 	v=conf.env
--- a/waflib/Tools/gdc.py
+++ b/waflib/Tools/gdc.py
@@ -8,8 +8,8 @@
 @conf
 def find_gdc(conf):
 	conf.find_program('gdc',var='D')
-	out=conf.cmd_and_log([conf.env.D,'--version'])
-	if out.find("gdc ")==-1:
+	out=conf.cmd_and_log(conf.env.D+['--version'])
+	if out.find("gdc")==-1:
 		conf.fatal("detected compiler is not gdc")
 @conf
 def common_flags_gdc(conf):
--- a/waflib/Tools/gfortran.py
+++ b/waflib/Tools/gfortran.py
@@ -9,7 +9,6 @@
 @conf
 def find_gfortran(conf):
 	fc=conf.find_program(['gfortran','g77'],var='FC')
-	fc=conf.cmd_to_list(fc)
 	conf.get_gfortran_version(fc)
 	conf.env.FC_NAME='GFORTRAN'
 @conf
--- a/waflib/Tools/glib2.py
+++ b/waflib/Tools/glib2.py
@@ -3,8 +3,9 @@
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
 import os
-from waflib import Task,Utils,Options,Errors,Logs
-from waflib.TaskGen import taskgen_method,before_method,after_method,feature
+from waflib import Context,Task,Utils,Options,Errors,Logs
+from waflib.TaskGen import taskgen_method,before_method,after_method,feature,extension
+from waflib.Configure import conf
 @taskgen_method
 def add_marshal_file(self,filename,prefix):
 	if not hasattr(self,'marshal_list'):
@@ -98,14 +99,6 @@
 	if type(filename_list)!='list':
 		filename_list=[filename_list]
 	self.settings_enum_files=filename_list
-def r_change_ext(self,ext):
-	name=self.name
-	k=name.rfind('.')
-	if k>=0:
-		name=name[:k]+ext
-	else:
-		name=name+ext
-	return self.parent.find_or_declare([name])
 @feature('glib2')
 def process_settings(self):
 	enums_tgt_node=[]
@@ -136,7 +129,7 @@
 		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]
-		target_node=r_change_ext(schema_node,'.xml.valid')
+		target_node=schema_node.change_ext('.xml.valid')
 		schema_task.set_outputs(target_node)
 		schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
 	def compile_schemas_callback(bld):
@@ -155,10 +148,69 @@
 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'
-def configure(conf):
+@extension('.gresource.xml')
+def process_gresource_source(self,node):
+	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
+	h_node=node.change_ext('_xml.h')
+	c_node=node.change_ext('_xml.c')
+	self.create_task('glib_gresource_source',node,[h_node,c_node])
+	self.source.append(c_node)
+@feature('gresource')
+def process_gresource_bundle(self):
+	for i in self.to_list(self.source):
+		node=self.path.find_resource(i)
+		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)
+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['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)
+		nodes=[]
+		names=[]
+		for dep in output.splitlines():
+			if dep:
+				node=bld.bldnode.find_node(dep)
+				if node:
+					nodes.append(node)
+				else:
+					names.append(dep)
+		return(nodes,names)
+class glib_gresource_source(glib_gresource_base):
+	vars=['GLIB_COMPILE_RESOURCES']
+	fun_h=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[0].abspath()} --generate-header ${SRC}')
+	fun_c=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[1].abspath()} --generate-source ${SRC}')
+	ext_out=['.h']
+	def run(self):
+		return self.fun_h[0](self)or self.fun_c[0](self)
+class glib_gresource_bundle(glib_gresource_base):
+	run_str=glib_gresource_base.base_cmd+' --target=${TGT} ${SRC}'
+	shell=True
+@conf
+def find_glib_genmarshal(conf):
 	conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
-	conf.find_perl_program('glib-mkenums',var='GLIB_MKENUMS')
-	conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS',mandatory=False)
+@conf
+def find_glib_mkenums(conf):
+	if not conf.env.PERL:
+		conf.find_program('perl',var='PERL')
+	conf.find_program('glib-mkenums',interpreter='PERL',var='GLIB_MKENUMS')
+@conf
+def find_glib_compile_schemas(conf):
+	conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS')
 	def getstr(varname):
 		return getattr(Options.options,varname,getattr(conf.env,varname,''))
 	gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
@@ -169,5 +221,14 @@
 			datadir=os.path.join(prefix,'share')
 		gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
 	conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
+@conf
+def find_glib_compile_resources(conf):
+	conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES')
+def configure(conf):
+	conf.find_glib_genmarshal()
+	conf.find_glib_mkenums()
+	conf.find_glib_compile_schemas(mandatory=False)
+	conf.find_glib_compile_resources(mandatory=False)
 def options(opt):
-	opt.add_option('--gsettingsschemadir',help='GSettings schema location [Default: ${datadir}/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
+	gr=opt.add_option_group('Installation directories')
+	gr.add_option('--gsettingsschemadir',help='GSettings schema location [DATADIR/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
--- a/waflib/Tools/gnu_dirs.py
+++ b/waflib/Tools/gnu_dirs.py
@@ -2,29 +2,30 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os
+import os,re
 from waflib import Utils,Options,Context
-_options=[x.split(', ')for x in'''
-bindir, user executables, ${EXEC_PREFIX}/bin
-sbindir, system admin executables, ${EXEC_PREFIX}/sbin
-libexecdir, program executables, ${EXEC_PREFIX}/libexec
-sysconfdir, read-only single-machine data, ${PREFIX}/etc
-sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
-localstatedir, modifiable single-machine data, ${PREFIX}/var
-libdir, object code libraries, ${EXEC_PREFIX}/lib
-includedir, C header files, ${PREFIX}/include
-oldincludedir, C header files for non-gcc, /usr/include
-datarootdir, read-only arch.-independent data root, ${PREFIX}/share
-datadir, read-only architecture-independent data, ${DATAROOTDIR}
-infodir, info documentation, ${DATAROOTDIR}/info
+gnuopts='''
+bindir, user commands, ${EXEC_PREFIX}/bin
+sbindir, system binaries, ${EXEC_PREFIX}/sbin
+libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec
+sysconfdir, host-specific configuration, ${PREFIX}/etc
+sharedstatedir, architecture-independent variable data, ${PREFIX}/com
+localstatedir, variable data, ${PREFIX}/var
+libdir, object code libraries, ${EXEC_PREFIX}/lib%s
+includedir, header files, ${PREFIX}/include
+oldincludedir, header files for non-GCC compilers, /usr/include
+datarootdir, architecture-independent data root, ${PREFIX}/share
+datadir, architecture-independent data, ${DATAROOTDIR}
+infodir, GNU "info" documentation, ${DATAROOTDIR}/info
 localedir, locale-dependent data, ${DATAROOTDIR}/locale
-mandir, man documentation, ${DATAROOTDIR}/man
+mandir, manual pages, ${DATAROOTDIR}/man
 docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
-htmldir, html documentation, ${DOCDIR}
-dvidir, dvi documentation, ${DOCDIR}
-pdfdir, pdf documentation, ${DOCDIR}
-psdir, ps documentation, ${DOCDIR}
-'''.split('\n')if x]
+htmldir, HTML documentation, ${DOCDIR}
+dvidir, DVI documentation, ${DOCDIR}
+pdfdir, PDF documentation, ${DOCDIR}
+psdir, PostScript documentation, ${DOCDIR}
+'''%Utils.lib64()
+_options=[x.split(', ')for x in gnuopts.splitlines()if x]
 def configure(conf):
 	def get_param(varname,default):
 		return getattr(Options.options,varname,'')or default
@@ -45,10 +46,10 @@
 				except TypeError:
 					complete=False
 	if not complete:
-		lst=[name for name,_,_ in _options if not env[name.upper()]]
+		lst=[x for x,_,_ in _options if not env[x.upper()]]
 		raise conf.errors.WafError('Variable substitution failure %r'%lst)
 def options(opt):
-	inst_dir=opt.add_option_group('Installation directories','By default, "waf install" will put the files in\
+	inst_dir=opt.add_option_group('Installation prefix','By default, "waf install" will put the files in\
  "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
  than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
 	for k in('--prefix','--destdir'):
@@ -56,10 +57,10 @@
 		if option:
 			opt.parser.remove_option(k)
 			inst_dir.add_option(option)
-	inst_dir.add_option('--exec-prefix',help='installation prefix [Default: ${PREFIX}]',default='',dest='EXEC_PREFIX')
-	dirs_options=opt.add_option_group('Pre-defined installation directories','')
+	inst_dir.add_option('--exec-prefix',help='installation prefix for binaries [PREFIX]',default='',dest='EXEC_PREFIX')
+	dirs_options=opt.add_option_group('Installation directories')
 	for name,help,default in _options:
 		option_name='--'+name
 		str_default=default
-		str_help='%s [Default: %s]'%(help,str_default)
+		str_help='%s [%s]'%(help,re.sub(r'\$\{([^}]+)\}',r'\1',str_default))
 		dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
--- a/waflib/Tools/gxx.py
+++ b/waflib/Tools/gxx.py
@@ -2,15 +2,15 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.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
 @conf
 def find_gxx(conf):
 	cxx=conf.find_program(['g++','c++'],var='CXX')
-	cxx=conf.cmd_to_list(cxx)
 	conf.get_cc_version(cxx,gcc=True)
 	conf.env.CXX_NAME='gcc'
-	conf.env.CXX=cxx
 @conf
 def gxx_common_flags(conf):
 	v=conf.env
--- a/waflib/Tools/icc.py
+++ b/waflib/Tools/icc.py
@@ -9,17 +9,9 @@
 def find_icc(conf):
 	if sys.platform=='cygwin':
 		conf.fatal('The Intel compiler does not work on Cygwin')
-	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('icc',var='CC')
-	if not cc:cc=conf.find_program('ICL',var='CC')
-	if not cc:conf.fatal('Intel C Compiler (icc) was not found')
-	cc=conf.cmd_to_list(cc)
+	cc=conf.find_program(['icc','ICL'],var='CC')
 	conf.get_cc_version(cc,icc=True)
-	v['CC']=cc
-	v['CC_NAME']='icc'
+	conf.env.CC_NAME='icc'
 def configure(conf):
 	conf.find_icc()
 	conf.find_ar()
--- a/waflib/Tools/icpc.py
+++ b/waflib/Tools/icpc.py
@@ -9,16 +9,9 @@
 def find_icpc(conf):
 	if sys.platform=='cygwin':
 		conf.fatal('The Intel compiler does not work on Cygwin')
-	v=conf.env
-	cxx=None
-	if v['CXX']:cxx=v['CXX']
-	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
-	if not cxx:cxx=conf.find_program('icpc',var='CXX')
-	if not cxx:conf.fatal('Intel C++ Compiler (icpc) was not found')
-	cxx=conf.cmd_to_list(cxx)
+	cxx=conf.find_program('icpc',var='CXX')
 	conf.get_cc_version(cxx,icc=True)
-	v['CXX']=cxx
-	v['CXX_NAME']='icc'
+	conf.env.CXX_NAME='icc'
 def configure(conf):
 	conf.find_icpc()
 	conf.find_ar()
--- a/waflib/Tools/ifort.py
+++ b/waflib/Tools/ifort.py
@@ -9,7 +9,6 @@
 @conf
 def find_ifort(conf):
 	fc=conf.find_program('ifort',var='FC')
-	fc=conf.cmd_to_list(fc)
 	conf.get_ifort_version(fc)
 	conf.env.FC_NAME='IFORT'
 @conf
@@ -29,8 +28,11 @@
 		ifort_modifier_func()
 @conf
 def get_ifort_version(conf,fc):
-	version_re=re.compile(r"ifort\s*\(IFORT\)\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
-	cmd=fc+['--version']
+	version_re=re.compile(r"Intel[\sa-zA-Z()0-9,-]*Version\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+	if Utils.is_win32:
+		cmd=fc
+	else:
+		cmd=fc+['-logo']
 	out,err=fc_config.getoutput(conf,cmd,stdin=False)
 	if out:
 		match=version_re(out)
--- a/waflib/Tools/intltool.py
+++ b/waflib/Tools/intltool.py
@@ -3,30 +3,47 @@
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
 import os,re
-from waflib import Configure,TaskGen,Task,Utils,Runner,Options,Build,Logs
+from waflib import Configure,Context,TaskGen,Task,Utils,Runner,Options,Build,Logs
 import waflib.Tools.ccroot
-from waflib.TaskGen import feature,before_method
+from waflib.TaskGen import feature,before_method,taskgen_method
 from waflib.Logs import error
+from waflib.Configure import conf
+_style_flags={'ba':'-b','desktop':'-d','keys':'-k','quoted':'--quoted-style','quotedxml':'--quotedxml-style','rfc822deb':'-r','schemas':'-s','xml':'-x',}
+@taskgen_method
+def ensure_localedir(self):
+	if not self.env.LOCALEDIR:
+		if self.env.DATAROOTDIR:
+			self.env.LOCALEDIR=os.path.join(self.env.DATAROOTDIR,'locale')
+		else:
+			self.env.LOCALEDIR=os.path.join(self.env.PREFIX,'share','locale')
 @before_method('process_source')
 @feature('intltool_in')
 def apply_intltool_in_f(self):
 	try:self.meths.remove('process_source')
 	except ValueError:pass
-	if not self.env.LOCALEDIR:
-		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+	self.ensure_localedir()
+	podir=getattr(self,'podir','.')
+	podirnode=self.path.find_dir(podir)
+	if not podirnode:
+		error("could not find the podir %r"%podir)
+		return
+	cache=getattr(self,'intlcache','.intlcache')
+	self.env.INTLCACHE=[os.path.join(str(self.path.get_bld()),podir,cache)]
+	self.env.INTLPODIR=podirnode.bldpath()
+	self.env.append_value('INTLFLAGS',getattr(self,'flags',self.env.INTLFLAGS_DEFAULT))
+	if'-c'in self.env.INTLFLAGS:
+		self.bld.fatal('Redundant -c flag in intltool task %r'%self)
+	style=getattr(self,'style',None)
+	if style:
+		try:
+			style_flag=_style_flags[style]
+		except KeyError:
+			self.bld.fatal('intltool_in style "%s" is not valid'%style)
+		self.env.append_unique('INTLFLAGS',[style_flag])
 	for i in self.to_list(self.source):
 		node=self.path.find_resource(i)
-		podir=getattr(self,'podir','po')
-		podirnode=self.path.find_dir(podir)
-		if not podirnode:
-			error("could not find the podir %r"%podir)
-			continue
-		cache=getattr(self,'intlcache','.intlcache')
-		self.env['INTLCACHE']=os.path.join(self.path.bldpath(),podir,cache)
-		self.env['INTLPODIR']=podirnode.bldpath()
-		self.env['INTLFLAGS']=getattr(self,'flags',['-q','-u','-c'])
 		task=self.create_task('intltool',node,node.change_ext(''))
-		inst=getattr(self,'install_path','${LOCALEDIR}')
+		inst=getattr(self,'install_path',None)
 		if inst:
 			self.bld.install_files(inst,task.outputs)
 @feature('intltool_po')
@@ -33,10 +50,9 @@
 def apply_intltool_po(self):
 	try:self.meths.remove('process_source')
 	except ValueError:pass
-	if not self.env.LOCALEDIR:
-		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
-	appname=getattr(self,'appname','set_your_app_name')
-	podir=getattr(self,'podir','')
+	self.ensure_localedir()
+	appname=getattr(self,'appname',getattr(Context.g_module,Context.APPNAME,'set_your_app_name'))
+	podir=getattr(self,'podir','.')
 	inst=getattr(self,'install_path','${LOCALEDIR}')
 	linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
 	if linguas:
@@ -62,16 +78,20 @@
 	run_str='${MSGFMT} -o ${TGT} ${SRC}'
 	color='BLUE'
 class intltool(Task.Task):
-	run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
+	run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
 	color='BLUE'
-def configure(conf):
+@conf
+def find_msgfmt(conf):
 	conf.find_program('msgfmt',var='MSGFMT')
-	conf.find_perl_program('intltool-merge',var='INTLTOOL')
-	prefix=conf.env.PREFIX
-	datadir=conf.env.DATADIR
-	if not datadir:
-		datadir=os.path.join(prefix,'share')
-	conf.define('LOCALEDIR',os.path.join(datadir,'locale').replace('\\','\\\\'))
-	conf.define('DATADIR',datadir.replace('\\','\\\\'))
+@conf
+def find_intltool_merge(conf):
+	if not conf.env.PERL:
+		conf.find_program('perl',var='PERL')
+	conf.env.INTLCACHE_ST='--cache=%s'
+	conf.env.INTLFLAGS_DEFAULT=['-q','-u']
+	conf.find_program('intltool-merge',interpreter='PERL',var='INTLTOOL')
+def configure(conf):
+	conf.find_msgfmt()
+	conf.find_intltool_merge()
 	if conf.env.CC or conf.env.CXX:
 		conf.check(header_name='locale.h')
--- a/waflib/Tools/irixcc.py
+++ b/waflib/Tools/irixcc.py
@@ -14,7 +14,6 @@
 	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')
-	cc=conf.cmd_to_list(cc)
 	try:
 		conf.cmd_and_log(cc+['-version'])
 	except Exception:
--- a/waflib/Tools/javaw.py
+++ b/waflib/Tools/javaw.py
@@ -157,7 +157,6 @@
 		return super(jar_create,self).runnable_status()
 class javac(Task.Task):
 	color='BLUE'
-	nocache=True
 	vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
 	def runnable_status(self):
 		for t in self.run_after:
@@ -253,7 +252,6 @@
 		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)
-		self.env[x.upper()]=self.cmd_to_list(self.env[x.upper()])
 	if'CLASSPATH'in self.environ:
 		v['CLASSPATH']=self.environ['CLASSPATH']
 	if not v['JAR']:self.fatal('jar is required for making java packages')
--- a/waflib/Tools/kde4.py
+++ b/waflib/Tools/kde4.py
@@ -19,7 +19,7 @@
 	run_str='${MSGFMT} ${SRC} -o ${TGT}'
 def configure(self):
 	kdeconfig=self.find_program('kde4-config')
-	prefix=self.cmd_and_log('%s --prefix'%kdeconfig).strip()
+	prefix=self.cmd_and_log(kdeconfig+['--prefix']).strip()
 	fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
 	try:os.stat(fname)
 	except OSError:
@@ -28,7 +28,7 @@
 		except OSError:self.fatal('could not open %s'%fname)
 	try:
 		txt=Utils.readf(fname)
-	except(OSError,IOError):
+	except EnvironmentError:
 		self.fatal('could not read %s'%fname)
 	txt=txt.replace('\\\n','\n')
 	fu=re.compile('#(.*)\n')
--- a/waflib/Tools/ldc2.py
+++ b/waflib/Tools/ldc2.py
@@ -8,7 +8,7 @@
 @conf
 def find_ldc2(conf):
 	conf.find_program(['ldc2'],var='D')
-	out=conf.cmd_and_log([conf.env.D,'-version'])
+	out=conf.cmd_and_log(conf.env.D+['-version'])
 	if out.find("based on DMD v2.")==-1:
 		conf.fatal("detected compiler is not ldc2")
 @conf
--- a/waflib/Tools/msvc.py
+++ b/waflib/Tools/msvc.py
@@ -59,7 +59,11 @@
 @conf
 def get_msvc_version(conf,compiler,version,target,vcvars):
 	debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
-	batfile=conf.bldnode.make_node('waf-print-msvc.bat')
+	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=
@@ -68,7 +72,7 @@
 echo INCLUDE=%%INCLUDE%%
 echo LIB=%%LIB%%;%%LIBPATH%%
 """%(vcvars,target))
-	sout=conf.cmd_and_log(['cmd','/E:on','/V:on','/C',batfile.abspath()])
+	sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
 	lines=sout.splitlines()
 	if not lines[0]:
 		lines.pop(0)
@@ -87,7 +91,6 @@
 	env.update(PATH=path)
 	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
 	cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
-	cxx=conf.cmd_to_list(cxx)
 	if'CL'in env:
 		del(env['CL'])
 	try:
@@ -175,7 +178,7 @@
 def gather_msvc_detected_versions():
 	version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
 	detected_versions=[]
-	for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
+	for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')):
 		try:
 			prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
 			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
@@ -372,7 +375,7 @@
 					setattr(conf,compilervars_warning_attr,False)
 					patch_url='http://software.intel.com/en-us/forums/topic/328487'
 					compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
-					for vscomntool in['VS110COMNTOOLS','VS100COMNTOOLS']:
+					for vscomntool in('VS110COMNTOOLS','VS100COMNTOOLS'):
 						if vscomntool in os.environ:
 							vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe'
 							dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe'
@@ -528,7 +531,6 @@
 	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)
-	cxx=conf.cmd_to_list(cxx)
 	env=dict(conf.environ)
 	if path:env.update(PATH=';'.join(path))
 	if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
@@ -618,10 +620,8 @@
 			if d[1:]=='debug':
 				pdbnode=self.link_task.outputs[0].change_ext('.pdb')
 				self.link_task.outputs.append(pdbnode)
-				try:
-					self.install_task.source.append(pdbnode)
-				except AttributeError:
-					pass
+				if getattr(self,'install_task',None):
+					self.pdb_install_task=self.bld.install_files(self.install_task.dest,pdbnode,env=self.env)
 				break
 @feature('cprogram','cshlib','cxxprogram','cxxshlib')
 @after_method('apply_link')
@@ -651,13 +651,11 @@
 	elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
 		mode='2'
 	debug('msvc: embedding manifest in mode %r'%mode)
-	lst=[]
-	lst.append(env['MT'])
+	lst=[]+mtool
 	lst.extend(Utils.to_list(env['MTFLAGS']))
 	lst.extend(['-manifest',manifest])
 	lst.append('-outputresource:%s;%s'%(outfile,mode))
-	lst=[lst]
-	return self.exec_command(*lst)
+	return self.exec_command(lst)
 def quote_response_command(self,flag):
 	if flag.find(' ')>-1:
 		for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
@@ -725,6 +723,8 @@
 	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)
--- a/waflib/Tools/perl.py
+++ b/waflib/Tools/perl.py
@@ -36,7 +36,7 @@
 		self.end_msg("Perl not found",color="YELLOW")
 		return False
 	self.env['PERL']=perl
-	version=self.cmd_and_log([perl,"-e",'printf \"%vd\", $^V'])
+	version=self.cmd_and_log(self.env.PERL+["-e",'printf \"%vd\", $^V'])
 	if not version:
 		res=False
 		version="Unknown"
@@ -48,7 +48,7 @@
 	return res
 @conf
 def check_perl_module(self,module):
-	cmd=[self.env['PERL'],'-e','use %s'%module]
+	cmd=self.env.PERL+['-e','use %s'%module]
 	self.start_msg('perl module %s'%module)
 	try:
 		r=self.cmd_and_log(cmd)
@@ -63,18 +63,22 @@
 	perl=env.PERL
 	if not perl:
 		self.fatal('find perl first')
-	def read_out(cmd):
-		return Utils.to_list(self.cmd_and_log(perl+cmd))
-	env['LINKFLAGS_PERLEXT']=read_out(" -MConfig -e'print $Config{lddlflags}'")
-	env['INCLUDES_PERLEXT']=read_out(" -MConfig -e'print \"$Config{archlib}/CORE\"'")
-	env['CFLAGS_PERLEXT']=read_out(" -MConfig -e'print \"$Config{ccflags} $Config{cccdlflags}\"'")
-	env['XSUBPP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}\"'")
-	env['EXTUTILS_TYPEMAP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/typemap\"'")
+	def cmd_perl_config(s):
+		return perl+['-MConfig','-e','print \"%s\"'%s]
+	def cfg_str(cfg):
+		return self.cmd_and_log(cmd_perl_config(cfg))
+	def cfg_lst(cfg):
+		return Utils.to_list(cfg_str(cfg))
+	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['XSUBPP']=cfg_lst('$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}')
+	env['EXTUTILS_TYPEMAP']=cfg_lst('$Config{privlib}/ExtUtils/typemap')
 	if not getattr(Options.options,'perlarchdir',None):
-		env['ARCHDIR_PERL']=self.cmd_and_log(perl+" -MConfig -e'print $Config{sitearch}'")
+		env['ARCHDIR_PERL']=cfg_str('$Config{sitearch}')
 	else:
 		env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
-	env['perlext_PATTERN']='%s.'+self.cmd_and_log(perl+" -MConfig -e'print $Config{dlext}'")
+	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)
--- a/waflib/Tools/python.py
+++ b/waflib/Tools/python.py
@@ -3,7 +3,7 @@
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
 import os,sys
-from waflib import Utils,Options,Errors,Logs
+from waflib import Utils,Options,Errors,Logs,Task,Node
 from waflib.TaskGen import extension,before_method,after_method,feature
 from waflib.Configure import conf
 FRAG='''
@@ -26,64 +26,66 @@
 '''
 INST='''
 import sys, py_compile
-py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
+py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
 '''
 DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
+@before_method('process_source')
+@feature('py')
+def feature_py(self):
+	self.install_path=getattr(self,'install_path','${PYTHONDIR}')
+	install_from=getattr(self,'install_from',None)
+	if install_from and not isinstance(install_from,Node.Node):
+		install_from=self.path.find_dir(install_from)
+	self.install_from=install_from
+	ver=self.env.PYTHON_VERSION
+	if not ver:
+		self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
+	if int(ver.replace('.',''))>31:
+		self.install_32=True
 @extension('.py')
 def process_py(self,node):
-	try:
-		if not self.bld.is_install:
-			return
-	except AttributeError:
-		return
-	try:
-		if not self.install_path:
-			return
-	except AttributeError:
-		self.install_path='${PYTHONDIR}'
-	def inst_py(ctx):
-		install_from=getattr(self,'install_from',None)
-		if install_from:
-			install_from=self.path.find_dir(install_from)
-		install_pyfile(self,node,install_from)
-	self.bld.add_post_fun(inst_py)
-def install_pyfile(self,node,install_from=None):
-	from_node=install_from or node.parent
-	tsk=self.bld.install_as(self.install_path+'/'+node.path_from(from_node),node,postpone=False)
-	path=tsk.get_install_path()
-	if self.bld.is_install<0:
-		Logs.info("+ removing byte compiled python files")
-		for x in'co':
-			try:
-				os.remove(path+x)
-			except OSError:
-				pass
-	if self.bld.is_install>0:
-		try:
-			st1=os.stat(path)
-		except OSError:
-			Logs.error('The python file is missing, this should not happen')
-		for x in['c','o']:
-			do_inst=self.env['PY'+x.upper()]
-			try:
-				st2=os.stat(path+x)
-			except OSError:
-				pass
-			else:
-				if st1.st_mtime<=st2.st_mtime:
-					do_inst=False
-			if do_inst:
-				lst=(x=='o')and[self.env['PYFLAGS_OPT']]or[]
-				(a,b,c)=(path,path+x,tsk.get_install_path(destdir=False)+x)
-				argv=self.env['PYTHON']+lst+['-c',INST,a,b,c]
-				Logs.info('+ byte compiling %r'%(path+x))
-				env=self.env.env or None
-				ret=Utils.subprocess.Popen(argv,env=env).wait()
-				if ret:
-					raise Errors.WafError('py%s compilation failed %r'%(x,path))
-@feature('py')
-def feature_py(self):
-	pass
+	assert(node.get_bld_sig())
+	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)
+		else:
+			self.bld.install_files(self.install_path,[node],relative_trick=True)
+	lst=[]
+	if self.env.PYC:
+		lst.append('pyc')
+	if self.env.PYO:
+		lst.append('pyo')
+	if self.install_path:
+		if self.install_from:
+			pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.install_from)),self.env)
+		else:
+			pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.path)),self.env)
+	else:
+		pyd=node.abspath()
+	for ext in lst:
+		if self.env.PYTAG:
+			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()
+		else:
+			pyobj=node.change_ext(".%s"%ext)
+		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)
+class pyc(Task.Task):
+	color='PINK'
+	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 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)
+		return ret
 @feature('pyext')
 @before_method('propagate_uselib_vars','apply_link')
 @after_method('apply_bundle')
@@ -131,7 +133,7 @@
 		self.fatal('The distutils module is unusable: install "python-devel"?')
 	self.to_log(out)
 	return_values=[]
-	for s in out.split('\n'):
+	for s in out.splitlines():
 		s=s.strip()
 		if not s:
 			continue
@@ -144,33 +146,82 @@
 		else:break
 	return return_values
 @conf
-def check_python_headers(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):
+		return False
+	for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split():
+		if not x in self.environ:
+			self.fatal('Please set %s in the os environment'%x)
+		else:
+			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))
+		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')
+	if'pyembed'in features:
+		flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
+		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))
+	return True
+@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']:
 		conf.fatal('load a compiler first (gcc, g++, ..)')
+	if conf.python_cross_compile(features):
+		return
 	if not env['PYTHON_VERSION']:
 		conf.check_python_version()
-	pybin=conf.env.PYTHON
+	pybin=env.PYTHON
 	if not pybin:
 		conf.fatal('Could not find the python executable')
-	v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
+	v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
 	try:
 		lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
 	except RuntimeError:
 		conf.fatal("Python development headers not found (-v for details).")
 	vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
-	conf.to_log("Configuration returned from %r:\n%r\n"%(pybin,'\n'.join(vals)))
+	conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals)))
 	dct=dict(zip(v,lst))
 	x='MACOSX_DEPLOYMENT_TARGET'
 	if dct[x]:
-		conf.env[x]=conf.environ[x]=dct[x]
+		env[x]=conf.environ[x]=dct[x]
 	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']]
+		if sys.hexversion<0x2070000:
+			all_flags=[[k]for k in all_flags[0]]
+		xx=env.CXX_NAME and'cxx'or'c'
+		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))
+		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')
+		conf.define('HAVE_PYTHON_H',1)
+		return
 	all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
 	conf.parse_flags(all_flags,'PYEMBED')
 	all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
 	conf.parse_flags(all_flags,'PYEXT')
 	result=None
-	for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
+	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']
 			conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
@@ -194,25 +245,12 @@
 		env.append_value('LIB_PYEMBED',[name])
 	else:
 		conf.to_log("\n\n### LIB NOT FOUND\n")
-	if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
+	if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
 		env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
 		env['LIB_PYEXT']=env['LIB_PYEMBED']
-	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',mandatory=False)
-	includes=[]
-	if conf.env.PYTHON_CONFIG:
-		for incstr in conf.cmd_and_log([conf.env.PYTHON_CONFIG,'--includes']).strip().split():
-			if(incstr.startswith('-I')or incstr.startswith('/I')):
-				incstr=incstr[2:]
-			if incstr not in includes:
-				includes.append(incstr)
-		conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n"%(includes,))
-		env['INCLUDES_PYEXT']=includes
-		env['INCLUDES_PYEMBED']=includes
-	else:
-		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']]
+	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.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
 		env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
@@ -226,17 +264,7 @@
 		env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
 		env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
 		env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
-	try:
-		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg=':-(')
-	except conf.errors.ConfigurationError:
-		xx=conf.env.CXX_NAME and'cxx'or'c'
-		flags=['--cflags','--libs','--ldflags']
-		for f in flags:
-			conf.check_cfg(msg='Asking python-config for pyembed %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=[f])
-		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
-		for f in flags:
-			conf.check_cfg(msg='Asking python-config for pyext %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=[f])
-		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
+	conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Distutils not installed? Broken python installation? Get python-config now!')
 @conf
 def check_python_version(conf,minver=None):
 	assert minver is None or isinstance(minver,tuple)
@@ -252,23 +280,27 @@
 	if result:
 		pyver='.'.join([str(x)for x in pyver_tuple[:2]])
 		conf.env['PYTHON_VERSION']=pyver
-		if'PYTHONDIR'in conf.environ:
+		if'PYTHONDIR'in conf.env:
+			pydir=conf.env['PYTHONDIR']
+		elif'PYTHONDIR'in conf.environ:
 			pydir=conf.environ['PYTHONDIR']
 		else:
 			if Utils.is_win32:
-				(python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+				(python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
 			else:
 				python_LIBDEST=None
-				(pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+				(pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0) or ''"])
 			if python_LIBDEST is None:
 				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)
-		if'PYTHONARCHDIR'in conf.environ:
+		if'PYTHONARCHDIR'in conf.env:
+			pyarchdir=conf.env['PYTHONARCHDIR']
+		elif'PYTHONARCHDIR'in conf.environ:
 			pyarchdir=conf.environ['PYTHONARCHDIR']
 		else:
-			(pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
+			(pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0) or ''"])
 			if not pyarchdir:
 				pyarchdir=pydir
 		if hasattr(conf,'define'):
@@ -288,13 +320,13 @@
 import %s as current_module
 version = getattr(current_module, '__version__', None)
 if version is not None:
-    print(str(version))
+	print(str(version))
 else:
-    print('unknown version')
+	print('unknown version')
 '''
 @conf
 def check_python_module(conf,module_name,condition=''):
-	msg='Python module %s'%module_name
+	msg="Checking for python module '%s'"%module_name
 	if condition:
 		msg='%s (%s)'%(msg,condition)
 	conf.start_msg(msg)
@@ -324,20 +356,25 @@
 		else:
 			conf.end_msg(ret)
 def configure(conf):
-	try:
-		conf.find_program('python',var='PYTHON')
-	except conf.errors.ConfigurationError:
-		Logs.warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
-		conf.env.PYTHON=sys.executable
-	if conf.env.PYTHON!=sys.executable:
-		Logs.warn("python executable %r differs from system %r"%(conf.env.PYTHON,sys.executable))
-	conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
 	v=conf.env
-	v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
+	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):
-	opt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
-	opt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
+	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)')
--- a/waflib/Tools/qt4.py
+++ b/waflib/Tools/qt4.py
@@ -11,8 +11,8 @@
 else:
 	has_xml=True
 import os,sys
-from waflib.Tools import c_preproc,cxx
-from waflib import Task,Utils,Options,Errors
+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
@@ -25,17 +25,6 @@
 	def __init__(self,*k,**kw):
 		Task.Task.__init__(self,*k,**kw)
 		self.moc_done=0
-	def scan(self):
-		(nodes,names)=c_preproc.scan(self)
-		lst=[]
-		for x in nodes:
-			if x.name.endswith('.moc'):
-				s=x.path_from(self.inputs[0].parent.get_bld())
-				if s not in names:
-					names.append(s)
-			else:
-				lst.append(x)
-		return(lst,names)
 	def runnable_status(self):
 		if self.moc_done:
 			return Task.Task.runnable_status(self)
@@ -56,10 +45,20 @@
 			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
@@ -69,27 +68,19 @@
 			pass
 		else:
 			delattr(self,'cache_sig')
+		include_nodes=[node.parent]+self.generator.includes_nodes
 		moctasks=[]
-		mocfiles=[]
-		try:
-			tmp_lst=bld.raw_deps[self.uid()]
-			bld.raw_deps[self.uid()]=[]
-		except KeyError:
-			tmp_lst=[]
-		for d in tmp_lst:
+		mocfiles=set([])
+		for d in bld.raw_deps.get(self.uid(),[]):
 			if not d.endswith('.moc'):
 				continue
 			if d in mocfiles:
-				Logs.error("paranoia owns")
 				continue
-			mocfiles.append(d)
+			mocfiles.add(d)
 			h_node=None
-			try:ext=Options.options.qt_header_ext.split()
-			except AttributeError:pass
-			if not ext:ext=MOC_H
 			base2=d[:-4]
-			for x in[node.parent]+self.generator.includes_nodes:
-				for e in ext:
+			for x in include_nodes:
+				for e in self.moc_h_ext():
 					h_node=x.find_node(base2+e)
 					if h_node:
 						break
@@ -99,28 +90,19 @@
 			else:
 				for k in EXT_QT4:
 					if base2.endswith(k):
-						for x in[node.parent]+self.generator.includes_nodes:
+						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 h_node:
+							m_node=h_node.change_ext(k+'.moc')
+							break
 			if not h_node:
-				raise Errors.WafError('no header found for %r which is a moc file'%d)
-			bld.node_deps[(self.inputs[0].parent.abspath(),m_node.name)]=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)
-		tmp_lst=bld.raw_deps[self.uid()]=mocfiles
-		lst=bld.node_deps.get(self.uid(),())
-		for d in lst:
-			name=d.name
-			if name.endswith('.moc'):
-				task=self.create_moc_task(bld.node_deps[(self.inputs[0].parent.abspath(),name)],d)
-				moctasks.append(task)
 		self.run_after.update(set(moctasks))
 		self.moc_done=1
-	run=Task.classes['cxx'].__dict__['run']
 class trans_update(Task.Task):
 	run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
 	color='BLUE'
@@ -140,7 +122,7 @@
 @extension(*EXT_RCC)
 def create_rcc_task(self,node):
 	rcnode=node.change_ext('_rc.cpp')
-	rcctask=self.create_task('rcc',node,rcnode)
+	self.create_task('rcc',node,rcnode)
 	cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
 	try:
 		self.compiled_tasks.append(cpptask)
@@ -179,7 +161,7 @@
 	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 in('-D','-I','/D','/I'):
 			if(f[0]=='/'):
 				lst.append('-'+flag[1:])
 			else:
@@ -190,10 +172,11 @@
 	return self.create_compiled_task('qxx',node)
 class rcc(Task.Task):
 	color='BLUE'
-	run_str='${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+	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):
-		node=self.inputs[0]
 		if not has_xml:
 			Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
 			return([],[])
@@ -216,6 +199,10 @@
 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}'
@@ -267,7 +254,7 @@
 				paths.append(qtbin)
 	cand=None
 	prev_ver=['4','0','0']
-	for qmk in['qmake-qt4','qmake4','qmake']:
+	for qmk in('qmake-qt4','qmake4','qmake'):
 		try:
 			qmake=self.find_program(qmk,path_list=paths)
 		except self.errors.ConfigurationError:
@@ -274,7 +261,7 @@
 			pass
 		else:
 			try:
-				version=self.cmd_and_log([qmake,'-query','QT_VERSION']).strip()
+				version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
 			except self.errors.WafError:
 				pass
 			else:
@@ -287,7 +274,7 @@
 		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
+	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
@@ -301,18 +288,17 @@
 				break
 	find_bin(['uic-qt3','uic3'],'QT_UIC3')
 	find_bin(['uic-qt4','uic'],'QT_UIC')
-	if not env['QT_UIC']:
+	if not env.QT_UIC:
 		self.fatal('cannot find the uic compiler for qt4')
-	try:
-		uicver=self.cmd_and_log(env['QT_UIC']+" -version 2>&1").strip()
-	except self.errors.ConfigurationError:
-		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+	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.msg('Checking for uic version','%s'%uicver)
+	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'],'QT_RCC')
+	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'
@@ -327,12 +313,12 @@
 	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()
+			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
+			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()
+	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)
--- /dev/null
+++ b/waflib/Tools/qt5.py
@@ -1,0 +1,488 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.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_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)
+		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
+		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
+		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_QT5:
+					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)
+@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
+@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])]
+@extension('.ts')
+def add_lang(self,node):
+	self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+@feature('qt5')
+@after_method('apply_link')
+def apply_qt5(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_qt5:
+			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)
+@extension(*EXT_QT5)
+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}'
+class ui5(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_qt5_binaries()
+	self.set_qt5_libs_to_check()
+	self.set_qt5_defines()
+	self.find_qt5_libraries()
+	self.add_qt5_rpath()
+	self.simplify_qt5_libs()
+@conf
+def find_qt5_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('QT5_ROOT','')
+		qtbin=os.environ.get('QT5_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/qt5/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=['5','0','0']
+	for qmk in('qmake-qt5','qmake5','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 not cand:
+		try:
+			self.find_program('qtchooser')
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake']
+			try:
+				version=self.cmd_and_log(cmd+['-query','QT_VERSION'])
+			except self.errors.WafError:
+				pass
+			else:
+				cand=cmd
+	if cand:
+		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
+	paths.insert(0,qtbin)
+	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-qt5','uic'],'QT_UIC')
+	if not env.QT_UIC:
+		self.fatal('cannot find the uic compiler for qt5')
+	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 or uicver.find(' 4.')!=-1:
+		self.fatal('this uic compiler is for qt3 or qt5, add uic for qt5 to your path')
+	find_bin(['moc-qt5','moc'],'QT_MOC')
+	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.MOCCPPPATH_ST='-I%s'
+	env.MOCDEFINES_ST='-D%s'
+@conf
+def find_qt5_libraries(self):
+	qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT5_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 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=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)
+	try:
+		if os.environ.get("QT5_XCOMPILE",None):
+			raise self.errors.ConfigurationError()
+		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 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%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))
+				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))
+	else:
+		for i in self.qt5_vars_debug+self.qt5_vars:
+			self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+@conf
+def simplify_qt5_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.qt5_vars,'LIBPATH_QTCORE')
+	process_lib(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def add_qt5_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.qt5_vars,'LIBPATH_QTCORE')
+		process_rpath(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@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)
+	if not hasattr(self,'qt5_vars_debug'):
+		self.qt5_vars_debug=[a+'_debug'for a in self.qt5_vars]
+	self.qt5_vars_debug=Utils.to_list(self.qt5_vars_debug)
+@conf
+def set_qt5_defines(self):
+	if sys.platform!='win32':
+		return
+	for x in self.qt5_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)
+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)
--- a/waflib/Tools/ruby.py
+++ b/waflib/Tools/ruby.py
@@ -27,7 +27,7 @@
 		self.find_program('ruby',var='RUBY')
 	ruby=self.env.RUBY
 	try:
-		version=self.cmd_and_log([ruby,'-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
+		version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
 	except Exception:
 		self.fatal('could not determine ruby version')
 	self.env.RUBY_VERSION=version
@@ -51,9 +51,9 @@
 		self.fatal('load a c/c++ compiler first')
 	version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
 	def read_out(cmd):
-		return Utils.to_list(self.cmd_and_log([self.env.RUBY,'-rrbconfig','-e',cmd]))
+		return Utils.to_list(self.cmd_and_log(self.env.RUBY+['-rrbconfig','-e',cmd]))
 	def read_config(key):
-		return read_out('puts Config::CONFIG[%r]'%key)
+		return read_out('puts RbConfig::CONFIG[%r]'%key)
 	ruby=self.env['RUBY']
 	archdir=read_config('archdir')
 	cpppath=archdir
@@ -87,7 +87,7 @@
 def check_ruby_module(self,module_name):
 	self.start_msg('Ruby module %s'%module_name)
 	try:
-		self.cmd_and_log([self.env['RUBY'],'-e','require \'%s\';puts 1'%module_name])
+		self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name])
 	except Exception:
 		self.end_msg(False)
 		self.fatal('Could not find the ruby module %r'%module_name)
--- a/waflib/Tools/suncc.py
+++ b/waflib/Tools/suncc.py
@@ -2,7 +2,6 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os
 from waflib import Utils
 from waflib.Tools import ccroot,ar
 from waflib.Configure import conf
@@ -9,18 +8,12 @@
 @conf
 def find_scc(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('Could not find a Sun C compiler')
-	cc=conf.cmd_to_list(cc)
+	cc=conf.find_program('cc',var='CC')
 	try:
 		conf.cmd_and_log(cc+['-flags'])
 	except Exception:
 		conf.fatal('%r is not a Sun compiler'%cc)
-	v['CC']=cc
-	v['CC_NAME']='sun'
+	v.CC_NAME='sun'
 	conf.get_suncc_version(cc)
 @conf
 def scc_common_flags(conf):
--- a/waflib/Tools/suncxx.py
+++ b/waflib/Tools/suncxx.py
@@ -2,7 +2,6 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os
 from waflib import Utils
 from waflib.Tools import ccroot,ar
 from waflib.Configure import conf
@@ -9,19 +8,12 @@
 @conf
 def find_sxx(conf):
 	v=conf.env
-	cc=None
-	if v['CXX']:cc=v['CXX']
-	elif'CXX'in conf.environ:cc=conf.environ['CXX']
-	if not cc:cc=conf.find_program('CC',var='CXX')
-	if not cc:cc=conf.find_program('c++',var='CXX')
-	if not cc:conf.fatal('Could not find a Sun C++ compiler')
-	cc=conf.cmd_to_list(cc)
+	cc=conf.find_program(['CC','c++'],var='CXX')
 	try:
 		conf.cmd_and_log(cc+['-flags'])
 	except Exception:
 		conf.fatal('%r is not a Sun compiler'%cc)
-	v['CXX']=cc
-	v['CXX_NAME']='sun'
+	v.CXX_NAME='sun'
 	conf.get_suncc_version(cc)
 @conf
 def sxx_common_flags(conf):
--- a/waflib/Tools/tex.py
+++ b/waflib/Tools/tex.py
@@ -3,7 +3,7 @@
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
 import os,re
-from waflib import Utils,Task,Errors,Logs
+from waflib import Utils,Task,Errors,Logs,Node
 from waflib.TaskGen import feature,before_method
 re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
 def bibunitscan(self):
@@ -14,7 +14,7 @@
 	for match in re_bibunit.finditer(code):
 		path=match.group('file')
 		if path:
-			for k in['','.bib']:
+			for k in('','.bib'):
 				Logs.debug('tex: trying %s%s'%(path,k))
 				fi=node.parent.find_resource(path+k)
 				if fi:
@@ -23,10 +23,11 @@
 				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']
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty']
 exts_tex=['.ltx','.tex']
-re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+re_tex=re.compile(r'\\(?P<type>usepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
 g_bibtex_re=re.compile('bibdata',re.M)
+g_glossaries_re=re.compile('\\@newglossary',re.M)
 class tex(Task.Task):
 	bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
 	bibtex_fun.__doc__="""
@@ -36,8 +37,13 @@
 	makeindex_fun.__doc__="""
 	Execute the program **makeindex**
 	"""
+	makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False)
+	makeglossaries_fun.__doc__="""
+	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
@@ -71,13 +77,23 @@
 			code=node.read()
 			global re_tex
 			for match in re_tex.finditer(code):
+				multibib=match.group('type')
+				if multibib and multibib.startswith('bibliography'):
+					multibib=multibib[len('bibliography'):]
+					if multibib.startswith('style'):
+						continue
+				else:
+					multibib=None
 				for path in match.group('file').split(','):
 					if path:
 						add_name=True
 						found=None
 						for k in exts_deps_tex:
-							Logs.debug('tex: trying %s%s'%(path,k))
-							found=node.parent.find_resource(path+k)
+							for up in self.texinputs_nodes:
+								Logs.debug('tex: trying %s%s'%(path,k))
+								found=up.find_resource(path+k)
+								if found:
+									break
 							for tsk in self.generator.tasks:
 								if not found or found in tsk.outputs:
 									break
@@ -88,6 +104,11 @@
 									if found.name.endswith(ext):
 										parse_node(found)
 										break
+							if found and multibib and found.name.endswith('.bib'):
+								try:
+									self.multibibs.append(found)
+								except AttributeError:
+									self.multibibs=[found]
 						if add_name:
 							names.append(path)
 		parse_node(node)
@@ -102,16 +123,22 @@
 		for aux_node in self.aux_nodes:
 			try:
 				ct=aux_node.read()
-			except(OSError,IOError):
+			except EnvironmentError:
 				Logs.error('Error reading %s: %r'%aux_node.abspath())
 				continue
 			if g_bibtex_re.findall(ct):
-				Logs.warn('calling bibtex')
+				Logs.info('calling bibtex')
 				self.env.env={}
 				self.env.env.update(os.environ)
-				self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
+				self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
 				self.env.SRCFILE=aux_node.name[:-4]
 				self.check_status('error when calling bibtex',self.bibtex_fun())
+		for node in getattr(self,'multibibs',[]):
+			self.env.env={}
+			self.env.env.update(os.environ)
+			self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
+			self.env.SRCFILE=node.name[:-4]
+			self.check_status('error when calling bibtex',self.bibtex_fun())
 	def bibunits(self):
 		try:
 			bibunits=bibunitscan(self)
@@ -119,21 +146,22 @@
 			Logs.error('error bibunitscan')
 		else:
 			if bibunits:
-				fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
+				fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
 				if fn:
-					Logs.warn('calling bibtex on bibunits')
+					Logs.info('calling bibtex on bibunits')
 				for f in fn:
-					self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
+					self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
 					self.env.SRCFILE=f
 					self.check_status('error when calling bibtex',self.bibtex_fun())
 	def makeindex(self):
+		self.idx_node=self.inputs[0].change_ext('.idx')
 		try:
 			idx_path=self.idx_node.abspath()
 			os.stat(idx_path)
 		except OSError:
-			Logs.warn('index file %s absent, not calling makeindex'%idx_path)
+			Logs.info('index file %s absent, not calling makeindex'%idx_path)
 		else:
-			Logs.warn('calling makeindex')
+			Logs.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())
@@ -141,6 +169,25 @@
 		p=self.inputs[0].parent.get_bld()
 		if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
 			self.aux_nodes+=p.ant_glob('*[0-9].aux')
+	def makeglossaries(self):
+		src_file=self.inputs[0].abspath()
+		base_file=os.path.basename(src_file)
+		base,_=os.path.splitext(base_file)
+		for aux_node in self.aux_nodes:
+			try:
+				ct=aux_node.read()
+			except EnvironmentError:
+				Logs.error('Error reading %s: %r'%aux_node.abspath())
+				continue
+			if g_glossaries_re.findall(ct):
+				if not self.env.MAKEGLOSSARIES:
+					raise Errors.WafError("The program 'makeglossaries' is missing!")
+				Logs.warn('calling makeglossaries')
+				self.env.SRCFILE=base
+				self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun())
+				return
+	def texinputs(self):
+		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']:
@@ -147,41 +194,40 @@
 			env.append_value('LATEXFLAGS','-interaction=batchmode')
 			env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
 			env.append_value('XELATEXFLAGS','-interaction=batchmode')
-		fun=self.texfun
-		node=self.inputs[0]
-		srcfile=node.abspath()
-		texinputs=self.env.TEXINPUTS or''
-		self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
 		self.cwd=self.inputs[0].parent.get_bld().abspath()
-		Logs.warn('first pass on %s'%self.__class__.__name__)
-		self.env.env={}
-		self.env.env.update(os.environ)
-		self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
-		self.env.SRCFILE=srcfile
-		self.check_status('error when calling latex',fun())
-		self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
-		self.idx_node=node.change_ext('.idx')
+		Logs.info('first pass on %s'%self.__class__.__name__)
+		cur_hash=self.hash_aux_nodes()
+		self.call_latex()
+		self.hash_aux_nodes()
 		self.bibtopic()
 		self.bibfile()
 		self.bibunits()
 		self.makeindex()
-		hash=''
+		self.makeglossaries()
 		for i in range(10):
-			prev_hash=hash
-			try:
-				hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
-				hash=Utils.h_list(hashes)
-			except(OSError,IOError):
-				Logs.error('could not read aux.h')
-				pass
-			if hash and hash==prev_hash:
+			prev_hash=cur_hash
+			cur_hash=self.hash_aux_nodes()
+			if not cur_hash:
+				Logs.error('No aux.h to process')
+			if cur_hash and cur_hash==prev_hash:
 				break
-			Logs.warn('calling %s'%self.__class__.__name__)
-			self.env.env={}
-			self.env.env.update(os.environ)
-			self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
-			self.env.SRCFILE=srcfile
-			self.check_status('error when calling %s'%self.__class__.__name__,fun())
+			Logs.info('calling %s'%self.__class__.__name__)
+			self.call_latex()
+	def hash_aux_nodes(self):
+		try:
+			nodes=self.aux_nodes
+		except AttributeError:
+			try:
+				self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
+			except IOError:
+				return None
+		return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes])
+	def call_latex(self):
+		self.env.env={}
+		self.env.env.update(os.environ)
+		self.env.env.update({'TEXINPUTS':self.texinputs()})
+		self.env.SRCFILE=self.inputs[0].abspath()
+		self.check_status('error when calling latex',self.texfun())
 class latex(tex):
 	texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
 class pdflatex(tex):
@@ -203,7 +249,7 @@
 @feature('tex')
 @before_method('process_source')
 def apply_tex(self):
-	if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
+	if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
 		self.type='pdflatex'
 	tree=self.bld
 	outs=Utils.to_list(getattr(self,'outs',[]))
@@ -211,12 +257,15 @@
 	deps_lst=[]
 	if getattr(self,'deps',None):
 		deps=self.to_list(self.deps)
-		for filename in deps:
-			n=self.path.find_resource(filename)
-			if not n:
-				self.bld.fatal('Could not find %r for %r'%(filename,self))
-			if not n in deps_lst:
-				deps_lst.append(n)
+		for dep in deps:
+			if isinstance(dep,str):
+				n=self.path.find_resource(dep)
+				if not n:
+					self.bld.fatal('Could not find %r for %r'%(dep,self))
+				if not n in deps_lst:
+					deps_lst.append(n)
+			elif isinstance(dep,Node.Node):
+				deps_lst.append(dep)
 	for node in self.to_nodes(self.source):
 		if self.type=='latex':
 			task=self.create_task('latex',node,node.change_ext('.dvi'))
@@ -226,23 +275,35 @@
 			task=self.create_task('xelatex',node,node.change_ext('.pdf'))
 		task.env=self.env
 		if deps_lst:
-			try:
-				lst=tree.node_deps[task.uid()]
-				for n in deps_lst:
-					if not n in lst:
-						lst.append(n)
-			except KeyError:
-				tree.node_deps[task.uid()]=deps_lst
-		v=dict(os.environ)
-		p=node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()+os.pathsep+v.get('TEXINPUTS','')+os.pathsep
-		v['TEXINPUTS']=p
+			for n in deps_lst:
+				if not n in task.dep_nodes:
+					task.dep_nodes.append(n)
+		if hasattr(self,'texinputs_nodes'):
+			task.texinputs_nodes=self.texinputs_nodes
+		else:
+			task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()]
+			lst=os.environ.get('TEXINPUTS','')
+			if self.env.TEXINPUTS:
+				lst+=os.pathsep+self.env.TEXINPUTS
+			if lst:
+				lst=lst.split(os.pathsep)
+			for x in lst:
+				if x:
+					if os.path.isabs(x):
+						p=self.bld.root.find_node(x)
+						if p:
+							task.texinputs_nodes.append(p)
+						else:
+							Logs.error('Invalid TEXINPUTS folder %s'%x)
+					else:
+						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'))
-				tsk.env.env=dict(v)
+				tsk.env.env=dict(os.environ)
 			if'pdf'in outs:
 				tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
-				tsk.env.env=dict(v)
+				tsk.env.env=dict(os.environ)
 		elif self.type=='pdflatex':
 			if'ps'in outs:
 				self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
@@ -249,7 +310,7 @@
 	self.source=[]
 def configure(self):
 	v=self.env
-	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
+	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split():
 		try:
 			self.find_program(p,var=p.upper())
 		except self.errors.ConfigurationError:
--- a/waflib/Tools/vala.py
+++ b/waflib/Tools/vala.py
@@ -10,7 +10,7 @@
 	vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
 	ext_out=['.h']
 	def run(self):
-		cmd=[self.env['VALAC']]+self.env['VALAFLAGS']
+		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())
 		if ret:
@@ -159,7 +159,7 @@
 def find_valac(self,valac_name,min_version):
 	valac=self.find_program(valac_name,var='VALAC')
 	try:
-		output=self.cmd_and_log(valac+' --version')
+		output=self.cmd_and_log(valac+['--version'])
 	except Exception:
 		valac_version=None
 	else:
--- a/waflib/Tools/waf_unit_test.py
+++ b/waflib/Tools/waf_unit_test.py
@@ -2,8 +2,8 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys
-from waflib.TaskGen import feature,after_method
+import os
+from waflib.TaskGen import feature,after_method,taskgen_method
 from waflib import Utils,Task,Logs,Options
 testlock=Utils.threading.Lock()
 @feature('test')
@@ -11,6 +11,14 @@
 def make_test(self):
 	if getattr(self,'link_task',None):
 		self.create_task('utest',self.link_task.outputs)
+@taskgen_method
+def add_test_results(self,tup):
+	Logs.debug("ut: %r",tup)
+	self.utest_result=tup
+	try:
+		self.bld.utest_results.append(tup)
+	except AttributeError:
+		self.bld.utest_results=[tup]
 class utest(Task.Task):
 	color='PINK'
 	after=['vnum','inst']
@@ -23,11 +31,9 @@
 			if getattr(Options.options,'all_tests',False):
 				return Task.RUN_ME
 		return ret
-	def run(self):
-		filename=self.inputs[0].abspath()
-		self.ut_exec=getattr(self.generator,'ut_exec',[filename])
-		if getattr(self.generator,'ut_fun',None):
-			self.generator.ut_fun(self)
+	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:
@@ -39,32 +45,30 @@
 						s=tg.link_task.outputs[0].parent.abspath()
 						if s not in lst:
 							lst.append(s)
-			def add_path(dct,path,var):
-				dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
 			if Utils.is_win32:
-				add_path(fu,lst,'PATH')
+				self.add_path(fu,lst,'PATH')
 			elif Utils.unversioned_sys_platform()=='darwin':
-				add_path(fu,lst,'DYLD_LIBRARY_PATH')
-				add_path(fu,lst,'LD_LIBRARY_PATH')
+				self.add_path(fu,lst,'DYLD_LIBRARY_PATH')
+				self.add_path(fu,lst,'LD_LIBRARY_PATH')
 			else:
-				add_path(fu,lst,'LD_LIBRARY_PATH')
+				self.add_path(fu,lst,'LD_LIBRARY_PATH')
 			self.generator.bld.all_test_paths=fu
+		return fu
+	def run(self):
+		filename=self.inputs[0].abspath()
+		self.ut_exec=getattr(self.generator,'ut_exec',[filename])
+		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(Options.options,'testcmd',False)
+		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=fu,stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
+		proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
 		(stdout,stderr)=proc.communicate()
 		tup=(filename,proc.returncode,stdout,stderr)
-		self.generator.utest_result=tup
 		testlock.acquire()
 		try:
-			bld=self.generator.bld
-			Logs.debug("ut: %r",tup)
-			try:
-				bld.utest_results.append(tup)
-			except AttributeError:
-				bld.utest_results=[tup]
+			return self.generator.add_test_results(tup)
 		finally:
 			testlock.release()
 def summary(bld):
--- a/waflib/Tools/xlc.py
+++ b/waflib/Tools/xlc.py
@@ -7,10 +7,8 @@
 @conf
 def find_xlc(conf):
 	cc=conf.find_program(['xlc_r','xlc'],var='CC')
-	cc=conf.cmd_to_list(cc)
 	conf.get_xlc_version(cc)
 	conf.env.CC_NAME='xlc'
-	conf.env.CC=cc
 @conf
 def xlc_common_flags(conf):
 	v=conf.env
--- a/waflib/Tools/xlcxx.py
+++ b/waflib/Tools/xlcxx.py
@@ -7,10 +7,8 @@
 @conf
 def find_xlcxx(conf):
 	cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
-	cxx=conf.cmd_to_list(cxx)
 	conf.get_xlc_version(cxx)
 	conf.env.CXX_NAME='xlc++'
-	conf.env.CXX=cxx
 @conf
 def xlcxx_common_flags(conf):
 	v=conf.env
--- a/waflib/Utils.py
+++ b/waflib/Utils.py
@@ -2,15 +2,10 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import os,sys,errno,traceback,inspect,re,shutil,datetime,gc
+import os,sys,errno,traceback,inspect,re,shutil,datetime,gc,platform
 import subprocess
+from collections import deque,defaultdict
 try:
-	from collections import deque
-except ImportError:
-	class deque(list):
-		def popleft(self):
-			return self.pop(0)
-try:
 	import _winreg as winreg
 except ImportError:
 	try:
@@ -32,6 +27,8 @@
 try:
 	import threading
 except ImportError:
+	if not'JOBS'in os.environ:
+		os.environ['JOBS']='1'
 	class threading(object):
 		pass
 	class Lock(object):
@@ -56,23 +53,34 @@
 rot_chr=['\\','|','/','-']
 rot_idx=0
 try:
-	from collections import defaultdict
+	from collections import OrderedDict as ordered_iter_dict
 except ImportError:
-	class defaultdict(dict):
-		def __init__(self,default_factory):
-			super(defaultdict,self).__init__()
-			self.default_factory=default_factory
-		def __getitem__(self,key):
+	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:
-				return super(defaultdict,self).__getitem__(key)
-			except KeyError:
-				value=self.default_factory()
-				self[key]=value
-				return value
-is_win32=sys.platform in('win32','cli')
-indicator='\x1b[K%s%s%s\r'
-if is_win32 and'NOCOLOR'in os.environ:
-	indicator='%s%s%s\r'
+				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
+is_win32=sys.platform in('win32','cli','os2')
 def readf(fname,m='r',encoding='ISO8859-1'):
 	if sys.hexversion>0x3000000 and not'b'in m:
 		m+='b'
@@ -81,7 +89,10 @@
 			txt=f.read()
 		finally:
 			f.close()
-		txt=txt.decode(encoding)
+		if encoding:
+			txt=txt.decode(encoding)
+		else:
+			txt=txt.decode()
 	else:
 		f=open(fname,m)
 		try:
@@ -108,67 +119,70 @@
 	finally:
 		f.close()
 	return m.digest()
-if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000:
-	def readf_win32(f,m='r',encoding='ISO8859-1'):
-		flags=os.O_NOINHERIT|os.O_RDONLY
-		if'b'in m:
-			flags|=os.O_BINARY
-		if'+'in m:
-			flags|=os.O_RDWR
+def readf_win32(f,m='r',encoding='ISO8859-1'):
+	flags=os.O_NOINHERIT|os.O_RDONLY
+	if'b'in m:
+		flags|=os.O_BINARY
+	if'+'in m:
+		flags|=os.O_RDWR
+	try:
+		fd=os.open(f,flags)
+	except OSError:
+		raise IOError('Cannot read from %r'%f)
+	if sys.hexversion>0x3000000 and not'b'in m:
+		m+='b'
+		f=os.fdopen(fd,m)
 		try:
-			fd=os.open(f,flags)
-		except OSError:
-			raise IOError('Cannot read from %r'%f)
-		if sys.hexversion>0x3000000 and not'b'in m:
-			m+='b'
-			f=os.fdopen(fd,m)
-			try:
-				txt=f.read()
-			finally:
-				f.close()
+			txt=f.read()
+		finally:
+			f.close()
+		if encoding:
 			txt=txt.decode(encoding)
 		else:
-			f=os.fdopen(fd,m)
-			try:
-				txt=f.read()
-			finally:
-				f.close()
-		return txt
-	def writef_win32(f,data,m='w',encoding='ISO8859-1'):
-		if sys.hexversion>0x3000000 and not'b'in m:
-			data=data.encode(encoding)
-			m+='b'
-		flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
-		if'b'in m:
-			flags|=os.O_BINARY
-		if'+'in m:
-			flags|=os.O_RDWR
-		try:
-			fd=os.open(f,flags)
-		except OSError:
-			raise IOError('Cannot write to %r'%f)
+			txt=txt.decode()
+	else:
 		f=os.fdopen(fd,m)
 		try:
-			f.write(data)
+			txt=f.read()
 		finally:
 			f.close()
-	def h_file_win32(fname):
-		try:
-			fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
-		except OSError:
-			raise IOError('Cannot read from %r'%fname)
-		f=os.fdopen(fd,'rb')
-		m=md5()
-		try:
-			while fname:
-				fname=f.read(200000)
-				m.update(fname)
-		finally:
-			f.close()
-		return m.digest()
-	readf_old=readf
-	writef_old=writef
-	h_file_old=h_file
+	return txt
+def writef_win32(f,data,m='w',encoding='ISO8859-1'):
+	if sys.hexversion>0x3000000 and not'b'in m:
+		data=data.encode(encoding)
+		m+='b'
+	flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
+	if'b'in m:
+		flags|=os.O_BINARY
+	if'+'in m:
+		flags|=os.O_RDWR
+	try:
+		fd=os.open(f,flags)
+	except OSError:
+		raise IOError('Cannot write to %r'%f)
+	f=os.fdopen(fd,m)
+	try:
+		f.write(data)
+	finally:
+		f.close()
+def h_file_win32(fname):
+	try:
+		fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
+	except OSError:
+		raise IOError('Cannot read from %r'%fname)
+	f=os.fdopen(fd,'rb')
+	m=md5()
+	try:
+		while fname:
+			fname=f.read(200000)
+			m.update(fname)
+	finally:
+		f.close()
+	return m.digest()
+readf_unix=readf
+writef_unix=writef
+h_file_unix=h_file
+if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000:
 	readf=readf_win32
 	writef=writef_win32
 	h_file=h_file_win32
@@ -190,27 +204,27 @@
 :param s: string to convert
 :type s: string
 """
+def listdir_win32(s):
+	if not s:
+		try:
+			import ctypes
+		except ImportError:
+			return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
+		else:
+			dlen=4
+			maxdrives=26
+			buf=ctypes.create_string_buffer(maxdrives*dlen)
+			ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
+			return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
+	if len(s)==2 and s[1]==":":
+		s+=os.sep
+	if not os.path.isdir(s):
+		e=OSError('%s is not a directory'%s)
+		e.errno=errno.ENOENT
+		raise e
+	return os.listdir(s)
 listdir=os.listdir
 if is_win32:
-	def listdir_win32(s):
-		if not s:
-			try:
-				import ctypes
-			except ImportError:
-				return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
-			else:
-				dlen=4
-				maxdrives=26
-				buf=ctypes.create_string_buffer(maxdrives*dlen)
-				ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
-				return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
-		if len(s)==2 and s[1]==":":
-			s+=os.sep
-		if not os.path.isdir(s):
-			e=OSError('%s is not a directory'%s)
-			e.errno=errno.ENOENT
-			raise e
-		return os.listdir(s)
 	listdir=listdir_win32
 def num2ver(ver):
 	if isinstance(ver,str):
@@ -231,18 +245,7 @@
 		return sth.split()
 	else:
 		return sth
-re_nl=re.compile('\r*\n',re.M)
-def str_to_dict(txt):
-	tbl={}
-	lines=re_nl.split(txt)
-	for x in lines:
-		x=x.strip()
-		if not x or x.startswith('#')or x.find('=')<0:
-			continue
-		tmp=x.split('=')
-		tbl[tmp[0].strip()]='='.join(tmp[1:]).strip()
-	return tbl
-def split_path(path):
+def split_path_unix(path):
 	return path.split('/')
 def split_path_cygwin(path):
 	if path.startswith('//'):
@@ -261,6 +264,8 @@
 	split_path=split_path_cygwin
 elif is_win32:
 	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
 
@@ -275,12 +280,29 @@
 		except OSError ,e:
 			if not os.path.isdir(path):
 				raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
+def check_exe(name,env=None):
+	if not name:
+		raise ValueError('Cannot execute an empty string!')
+	def is_exe(fpath):
+		return os.path.isfile(fpath)and os.access(fpath,os.X_OK)
+	fpath,fname=os.path.split(name)
+	if fpath and is_exe(name):
+		return os.path.abspath(name)
+	else:
+		env=env or os.environ
+		for path in env["PATH"].split(os.pathsep):
+			path=path.strip('"')
+			exe_file=os.path.join(path,name)
+			if is_exe(exe_file):
+				return os.path.abspath(exe_file)
+	return None
 def def_attrs(cls,**kw):
 	for k,v in kw.items():
 		if not hasattr(cls,k):
 			setattr(cls,k,v)
 def quote_define_name(s):
-	fu=re.compile("[^a-zA-Z0-9]").sub("_",s)
+	fu=re.sub('[^a-zA-Z0-9]','_',s)
+	fu=re.sub('_+','_',fu)
 	fu=fu.upper()
 	return fu
 def h_list(lst):
@@ -336,7 +358,8 @@
 		else:s=s.lower()
 	if s=='powerpc':
 		return'darwin'
-	if s=='win32'or s.endswith('os2')and s!='sunos2':return s
+	if s=='win32'or s=='os2':
+		return s
 	return re.split('\d+$',s)[0]
 def nada(*k,**kw):
 	pass
@@ -345,10 +368,10 @@
 		self.start_time=datetime.datetime.utcnow()
 	def __str__(self):
 		delta=datetime.datetime.utcnow()-self.start_time
-		days=int(delta.days)
-		hours=delta.seconds//3600
-		minutes=(delta.seconds-hours*3600)//60
-		seconds=delta.seconds-hours*3600-minutes*60+float(delta.microseconds)/1000/1000
+		days=delta.days
+		hours,rem=divmod(delta.seconds,3600)
+		minutes,seconds=divmod(rem,60)
+		seconds+=delta.microseconds*1e-6
 		result=''
 		if days:
 			result+='%dd'%days
@@ -410,3 +433,11 @@
 	else:
 		if os.path.isfile(result):
 			return result
+def lib64():
+	if os.sep=='/':
+		is_64=platform.architecture()[0]=='64bit'
+		if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'):
+			return'64'if is_64 else''
+		else:
+			return''if is_64 else'32'
+	return''
--- a/waflib/ansiterm.py
+++ b/waflib/ansiterm.py
@@ -2,19 +2,49 @@
 # encoding: utf-8
 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
 
-import sys,os
+import os,re,sys
+from waflib.Utils import threading
+wlock=threading.Lock()
 try:
-	if not(sys.stderr.isatty()and sys.stdout.isatty()):
-		raise ValueError('not a tty')
-	from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,POINTER,c_long,c_char
+	from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,c_wchar,POINTER,c_long
+except ImportError:
+	class AnsiTerm(object):
+		def __init__(self,stream):
+			self.stream=stream
+			try:
+				self.errors=self.stream.errors
+			except AttributeError:
+				pass
+			self.encoding=self.stream.encoding
+		def write(self,txt):
+			try:
+				wlock.acquire()
+				self.stream.write(txt)
+				self.stream.flush()
+			finally:
+				wlock.release()
+		def fileno(self):
+			return self.stream.fileno()
+		def flush(self):
+			self.stream.flush()
+		def isatty(self):
+			return self.stream.isatty()
+else:
 	class COORD(Structure):
 		_fields_=[("X",c_short),("Y",c_short)]
 	class SMALL_RECT(Structure):
 		_fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)]
 	class CONSOLE_SCREEN_BUFFER_INFO(Structure):
-		_fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_short),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
+		_fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_ushort),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
 	class CONSOLE_CURSOR_INFO(Structure):
 		_fields_=[('dwSize',c_ulong),('bVisible',c_int)]
+	try:
+		_type=unicode
+	except NameError:
+		_type=str
+	to_int=lambda number,default:number and int(number)or default
+	STD_OUTPUT_HANDLE=-11
+	STD_ERROR_HANDLE=-12
 	windll.kernel32.GetStdHandle.argtypes=[c_ulong]
 	windll.kernel32.GetStdHandle.restype=c_ulong
 	windll.kernel32.GetConsoleScreenBufferInfo.argtypes=[c_ulong,POINTER(CONSOLE_SCREEN_BUFFER_INFO)]
@@ -21,8 +51,8 @@
 	windll.kernel32.GetConsoleScreenBufferInfo.restype=c_long
 	windll.kernel32.SetConsoleTextAttribute.argtypes=[c_ulong,c_ushort]
 	windll.kernel32.SetConsoleTextAttribute.restype=c_long
-	windll.kernel32.FillConsoleOutputCharacterA.argtypes=[c_ulong,c_char,c_ulong,POINTER(COORD),POINTER(c_ulong)]
-	windll.kernel32.FillConsoleOutputCharacterA.restype=c_long
+	windll.kernel32.FillConsoleOutputCharacterW.argtypes=[c_ulong,c_wchar,c_ulong,POINTER(COORD),POINTER(c_ulong)]
+	windll.kernel32.FillConsoleOutputCharacterW.restype=c_long
 	windll.kernel32.FillConsoleOutputAttribute.argtypes=[c_ulong,c_ushort,c_ulong,POINTER(COORD),POINTER(c_ulong)]
 	windll.kernel32.FillConsoleOutputAttribute.restype=c_long
 	windll.kernel32.SetConsoleCursorPosition.argtypes=[c_ulong,POINTER(COORD)]
@@ -29,38 +59,26 @@
 	windll.kernel32.SetConsoleCursorPosition.restype=c_long
 	windll.kernel32.SetConsoleCursorInfo.argtypes=[c_ulong,POINTER(CONSOLE_CURSOR_INFO)]
 	windll.kernel32.SetConsoleCursorInfo.restype=c_long
-	sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
-	csinfo=CONSOLE_CURSOR_INFO()
-	hconsole=windll.kernel32.GetStdHandle(-11)
-	windll.kernel32.GetConsoleScreenBufferInfo(hconsole,byref(sbinfo))
-	if sbinfo.Size.X<9 or sbinfo.Size.Y<9:raise ValueError('small console')
-	windll.kernel32.GetConsoleCursorInfo(hconsole,byref(csinfo))
-except Exception:
-	pass
-else:
-	import re,threading
-	is_vista=getattr(sys,"getwindowsversion",None)and sys.getwindowsversion()[0]>=6
-	try:
-		_type=unicode
-	except NameError:
-		_type=str
-	to_int=lambda number,default:number and int(number)or default
-	wlock=threading.Lock()
-	STD_OUTPUT_HANDLE=-11
-	STD_ERROR_HANDLE=-12
 	class AnsiTerm(object):
-		def __init__(self):
-			self.encoding=sys.stdout.encoding
-			self.hconsole=windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
+		def __init__(self,s):
+			self.stream=s
+			try:
+				self.errors=s.errors
+			except AttributeError:
+				pass
+			self.encoding=s.encoding
 			self.cursor_history=[]
-			self.orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
-			self.orig_csinfo=CONSOLE_CURSOR_INFO()
-			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self.orig_sbinfo))
-			windll.kernel32.GetConsoleCursorInfo(hconsole,byref(self.orig_csinfo))
+			handle=(s.fileno()==2)and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE
+			self.hconsole=windll.kernel32.GetStdHandle(handle)
+			self._sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+			self._csinfo=CONSOLE_CURSOR_INFO()
+			windll.kernel32.GetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
+			self._orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+			r=windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._orig_sbinfo))
+			self._isatty=r==1
 		def screen_buffer_info(self):
-			sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
-			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
-			return sbinfo
+			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._sbinfo))
+			return self._sbinfo
 		def clear_line(self,param):
 			mode=param and int(param)or 0
 			sbinfo=self.screen_buffer_info()
@@ -74,7 +92,7 @@
 				line_start=sbinfo.CursorPosition
 				line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
 			chars_written=c_ulong()
-			windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_char(' '),line_length,line_start,byref(chars_written))
+			windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written))
 			windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written))
 		def clear_screen(self,param):
 			mode=to_int(param,0)
@@ -90,7 +108,7 @@
 				clear_start=sbinfo.CursorPosition
 				clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y))
 			chars_written=c_ulong()
-			windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_char(' '),clear_length,clear_start,byref(chars_written))
+			windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written))
 			windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written))
 		def push_cursor(self,param):
 			sbinfo=self.screen_buffer_info()
@@ -133,20 +151,16 @@
 			return((c&1)<<2)|(c&2)|((c&4)>>2)
 		def set_color(self,param):
 			cols=param.split(';')
-			sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
-			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
+			sbinfo=self.screen_buffer_info()
 			attr=sbinfo.Attributes
 			for c in cols:
-				if is_vista:
-					c=int(c)
-				else:
-					c=to_int(c,0)
+				c=to_int(c,0)
 				if 29<c<38:
 					attr=(attr&0xfff0)|self.rgb2bgr(c-30)
 				elif 39<c<48:
 					attr=(attr&0xff0f)|(self.rgb2bgr(c-40)<<4)
 				elif c==0:
-					attr=self.orig_sbinfo.Attributes
+					attr=self._orig_sbinfo.Attributes
 				elif c==1:
 					attr|=0x08
 				elif c==4:
@@ -155,23 +169,26 @@
 					attr=(attr&0xff88)|((attr&0x70)>>4)|((attr&0x07)<<4)
 			windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr)
 		def show_cursor(self,param):
-			csinfo.bVisible=1
-			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+			self._csinfo.bVisible=1
+			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
 		def hide_cursor(self,param):
-			csinfo.bVisible=0
-			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+			self._csinfo.bVisible=0
+			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
 		ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,}
 		ansi_tokens=re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
 		def write(self,text):
 			try:
 				wlock.acquire()
-				for param,cmd,txt in self.ansi_tokens.findall(text):
-					if cmd:
-						cmd_func=self.ansi_command_table.get(cmd)
-						if cmd_func:
-							cmd_func(self,param)
-					else:
-						self.writeconsole(txt)
+				if self._isatty:
+					for param,cmd,txt in self.ansi_tokens.findall(text):
+						if cmd:
+							cmd_func=self.ansi_command_table.get(cmd)
+							if cmd_func:
+								cmd_func(self,param)
+						else:
+							self.writeconsole(txt)
+				else:
+					self.stream.write(text)
 			finally:
 				wlock.release()
 		def writeconsole(self,txt):
@@ -179,13 +196,43 @@
 			writeconsole=windll.kernel32.WriteConsoleA
 			if isinstance(txt,_type):
 				writeconsole=windll.kernel32.WriteConsoleW
-			TINY_STEP=3000
-			for x in range(0,len(txt),TINY_STEP):
-				tiny=txt[x:x+TINY_STEP]
-				writeconsole(self.hconsole,tiny,len(tiny),byref(chars_written),None)
+			done=0
+			todo=len(txt)
+			chunk=32<<10
+			while todo!=0:
+				doing=min(chunk,todo)
+				buf=txt[done:done+doing]
+				r=writeconsole(self.hconsole,buf,doing,byref(chars_written),None)
+				if r==0:
+					chunk>>=1
+					continue
+				done+=doing
+				todo-=doing
+		def fileno(self):
+			return self.stream.fileno()
 		def flush(self):
 			pass
 		def isatty(self):
-			return True
-	sys.stderr=sys.stdout=AnsiTerm()
-	os.environ['TERM']='vt100'
+			return self._isatty
+	if sys.stdout.isatty()or sys.stderr.isatty():
+		handle=sys.stdout.isatty()and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE
+		console=windll.kernel32.GetStdHandle(handle)
+		sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+		def get_term_cols():
+			windll.kernel32.GetConsoleScreenBufferInfo(console,byref(sbinfo))
+			return sbinfo.Size.X-1
+try:
+	import struct,fcntl,termios
+except ImportError:
+	pass
+else:
+	if(sys.stdout.isatty()or sys.stderr.isatty())and os.environ.get('TERM','')not in('dumb','emacs'):
+		FD=sys.stdout.isatty()and sys.stdout.fileno()or sys.stderr.fileno()
+		def fun():
+			return struct.unpack("HHHH",fcntl.ioctl(FD,termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[1]
+		try:
+			fun()
+		except Exception ,e:
+			pass
+		else:
+			get_term_cols=fun
--- a/waflib/extras/compat15.py
+++ b/waflib/extras/compat15.py
@@ -26,8 +26,36 @@
 Build.BuildContext.new_task_gen=Build.BuildContext.__call__
 Build.BuildContext.is_install=0
 Node.Node.relpath_gen=Node.Node.path_from
+Utils.pproc=Utils.subprocess
+Utils.get_term_cols=Logs.get_term_cols
+def cmd_output(cmd,**kw):
+	silent=False
+	if'silent'in kw:
+		silent=kw['silent']
+		del(kw['silent'])
+	if'e'in kw:
+		tmp=kw['e']
+		del(kw['e'])
+		kw['env']=tmp
+	kw['shell']=isinstance(cmd,str)
+	kw['stdout']=Utils.subprocess.PIPE
+	if silent:
+		kw['stderr']=Utils.subprocess.PIPE
+	try:
+		p=Utils.subprocess.Popen(cmd,**kw)
+		output=p.communicate()[0]
+	except OSError ,e:
+		raise ValueError(str(e))
+	if p.returncode:
+		if not silent:
+			msg="command execution failed: %s -> %r"%(cmd,str(output))
+			raise ValueError(msg)
+		output=''
+	return output
+Utils.cmd_output=cmd_output
 def name_to_obj(self,s,env=None):
-	Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
+	if Logs.verbose:
+		Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
 	return self.get_tgen_by_name(s)
 Build.BuildContext.name_to_obj=name_to_obj
 def env_of_name(self,name):
@@ -49,7 +77,8 @@
 		self.prepare_env(env)
 		self.all_envs[name]=env
 	else:
-		if fromenv:Logs.warn("The environment %s may have been configured already"%name)
+		if fromenv:
+			Logs.warn("The environment %s may have been configured already"%name)
 	return env
 Configure.ConfigurationContext.retrieve=retrieve
 Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse
@@ -56,6 +85,7 @@
 Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load
 Configure.conftest=Configure.conf
 Configure.ConfigurationError=Errors.ConfigurationError
+Utils.WafError=Errors.WafError
 Options.OptionsContext.sub_options=Options.OptionsContext.recurse
 Options.OptionsContext.tool_options=Context.Context.load
 Options.Handler=Options.OptionsContext
@@ -76,24 +106,32 @@
 def load_tool(*k,**kw):
 	ret=eld(*k,**kw)
 	if'set_options'in ret.__dict__:
-		Logs.warn('compat: rename "set_options" to options')
+		if Logs.verbose:
+			Logs.warn('compat: rename "set_options" to options')
 		ret.options=ret.set_options
 	if'detect'in ret.__dict__:
-		Logs.warn('compat: rename "detect" to "configure"')
+		if Logs.verbose:
+			Logs.warn('compat: rename "detect" to "configure"')
 		ret.configure=ret.detect
 	return ret
 Context.load_tool=load_tool
+def get_curdir(self):
+	return self.path.abspath()
+Context.Context.curdir=property(get_curdir,Utils.nada)
 rev=Context.load_module
-def load_module(path):
-	ret=rev(path)
+def load_module(path,encoding=None):
+	ret=rev(path,encoding)
 	if'set_options'in ret.__dict__:
-		Logs.warn('compat: rename "set_options" to "options" (%r)'%path)
+		if Logs.verbose:
+			Logs.warn('compat: rename "set_options" to "options" (%r)'%path)
 		ret.options=ret.set_options
 	if'srcdir'in ret.__dict__:
-		Logs.warn('compat: rename "srcdir" to "top" (%r)'%path)
+		if Logs.verbose:
+			Logs.warn('compat: rename "srcdir" to "top" (%r)'%path)
 		ret.top=ret.srcdir
 	if'blddir'in ret.__dict__:
-		Logs.warn('compat: rename "blddir" to "out" (%r)'%path)
+		if Logs.verbose:
+			Logs.warn('compat: rename "blddir" to "out" (%r)'%path)
 		ret.out=ret.blddir
 	return ret
 Context.load_module=load_module
@@ -101,15 +139,18 @@
 def post(self):
 	self.features=self.to_list(self.features)
 	if'cc'in self.features:
-		Logs.warn('compat: the feature cc does not exist anymore (use "c")')
+		if Logs.verbose:
+			Logs.warn('compat: the feature cc does not exist anymore (use "c")')
 		self.features.remove('cc')
 		self.features.append('c')
 	if'cstaticlib'in self.features:
-		Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
+		if Logs.verbose:
+			Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
 		self.features.remove('cstaticlib')
 		self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib')
 	if getattr(self,'ccflags',None):
-		Logs.warn('compat: "ccflags" was renamed to "cflags"')
+		if Logs.verbose:
+			Logs.warn('compat: "ccflags" was renamed to "cflags"')
 		self.cflags=self.ccflags
 	return old_post(self)
 TaskGen.task_gen.post=post
@@ -128,9 +169,11 @@
 	names=self.to_list(getattr(self,'uselib_local',[]))
 	get=self.bld.get_tgen_by_name
 	seen=set([])
+	seen_uselib=set([])
 	tmp=Utils.deque(names)
 	if tmp:
-		Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
+		if Logs.verbose:
+			Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
 	while tmp:
 		lib_name=tmp.popleft()
 		if lib_name in seen:
@@ -157,9 +200,11 @@
 			if not tmp_path in env['LIBPATH']:
 				env.prepend_value('LIBPATH',[tmp_path])
 		for v in self.to_list(getattr(y,'uselib',[])):
-			if not env['STLIB_'+v]:
-				if not v in self.uselib:
-					self.uselib.insert(0,v)
+			if v not in seen_uselib:
+				seen_uselib.add(v)
+				if not env['STLIB_'+v]:
+					if not v in self.uselib:
+						self.uselib.insert(0,v)
 		if getattr(y,'export_includes',None):
 			self.includes.extend(y.to_incnodes(y.export_includes))
 @TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib')
@@ -218,3 +263,17 @@
 	Logs.warn('compat: change "export_incdirs" by "export_includes"')
 	self.export_includes=val
 TaskGen.task_gen.export_incdirs=property(None,set_incdirs)
+def install_dir(self,path):
+	if not path:
+		return[]
+	destpath=Utils.subst_vars(path,self.env)
+	if self.is_install>0:
+		Logs.info('* creating %s'%destpath)
+		Utils.check_dir(destpath)
+	elif self.is_install<0:
+		Logs.info('* removing %s'%destpath)
+		try:
+			os.remove(destpath)
+		except OSError:
+			pass
+Build.BuildContext.install_dir=install_dir