summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cowgill <jcowgill@debian.org>2018-07-27 15:28:15 +0800
committerJames Cowgill <jcowgill@debian.org>2018-07-27 21:18:11 +0800
commit4f2b12429a53514a0635ffa657f9cd0ac203947b (patch)
tree8df0f70e042de0986e475c8719472252af494f86
parentc266a82891be316f57db7dc3692c8477834f793f (diff)
Refresh patches
-rw-r--r--debian/patches/02_fix-config-path.patch2
-rw-r--r--debian/patches/03_waf.patch2600
-rw-r--r--debian/patches/05_add-keywords.patch4
-rw-r--r--debian/patches/06_ffmpeg-abi.patch13
4 files changed, 1551 insertions, 1068 deletions
diff --git a/debian/patches/02_fix-config-path.patch b/debian/patches/02_fix-config-path.patch
index a4ccfff..304630c 100644
--- a/debian/patches/02_fix-config-path.patch
+++ b/debian/patches/02_fix-config-path.patch
@@ -7,7 +7,7 @@ Last-Update: 2015-05-03
--- a/DOCS/man/mpv.rst
+++ b/DOCS/man/mpv.rst
-@@ -1025,7 +1025,7 @@ FILES
+@@ -1127,7 +1127,7 @@ FILES
For Windows-specifics, see `FILES ON WINDOWS`_ section.
diff --git a/debian/patches/03_waf.patch b/debian/patches/03_waf.patch
index df5cf97..73c1a4e 100644
--- a/debian/patches/03_waf.patch
+++ b/debian/patches/03_waf.patch
@@ -11,8 +11,8 @@ Last-Update: 2017-07-19
+++ b/waf
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
-+# encoding: ISO8859-1
-+# Thomas Nagy, 2005-2016
++# encoding: latin-1
++# Thomas Nagy, 2005-2018
+#
+"""
+Redistribution and use in source and binary forms, with or without
@@ -44,13 +44,13 @@ Last-Update: 2017-07-19
+
+import os, sys, inspect
+
-+VERSION="1.9.8"
-+REVISION="17756245c4cc550633dacf3b08eec42a"
-+GIT="a6109383bfb9e70f32efc3a9d189bf5a088140bf"
++VERSION="2.0.9"
++REVISION="10a533182bd85c3f45a157fb5d62db50"
++GIT="c543921e7de1e319d9d3e425484d5a4d0794bb00"
+INSTALL=''
-+C1='#/'
-+C2='#-'
-+C3='#%'
++C1='#1'
++C2='#,'
++C3='#*'
+cwd = os.getcwd()
+join = os.path.join
+
@@ -178,7 +178,7 @@ Last-Update: 2017-07-19
+
--- /dev/null
+++ b/waflib/Build.py
-@@ -0,0 +1,785 @@
+@@ -0,0 +1,777 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -236,7 +236,7 @@ Last-Update: 2017-07-19
+ def get_variant_dir(self):
+ if not self.variant:
+ return self.out_dir
-+ return os.path.join(self.out_dir,self.variant)
++ return os.path.join(self.out_dir,os.path.normpath(self.variant))
+ variant_dir=property(get_variant_dir,None)
+ def __call__(self,*k,**kw):
+ kw['bld']=self
@@ -244,12 +244,6 @@ Last-Update: 2017-07-19
+ self.task_gen_cache_names={}
+ self.add_to_group(ret,group=kw.get('group'))
+ return ret
-+ def rule(self,*k,**kw):
-+ def f(rule):
-+ ret=self(*k,**kw)
-+ ret.rule=rule
-+ return ret
-+ return f
+ def __copy__(self):
+ raise Errors.WafError('build contexts cannot be copied')
+ def load_envs(self):
@@ -353,19 +347,24 @@ Last-Update: 2017-07-19
+ try:
+ self.producer.start()
+ except KeyboardInterrupt:
-+ self.store()
++ if self.is_dirty():
++ self.store()
+ raise
+ else:
-+ if self.producer.dirty:
++ if self.is_dirty():
+ self.store()
+ if self.producer.error:
+ raise Errors.BuildError(self.producer.error)
++ def is_dirty(self):
++ return self.producer.dirty
+ def setup(self,tool,tooldir=None,funs=None):
+ if isinstance(tool,list):
-+ for i in tool:self.setup(i,tooldir)
++ for i in tool:
++ self.setup(i,tooldir)
+ return
+ module=Context.load_tool(tool,tooldir)
-+ if hasattr(module,"setup"):module.setup(self)
++ if hasattr(module,"setup"):
++ module.setup(self)
+ def get_env(self):
+ try:
+ return self.all_envs[self.variant]
@@ -438,7 +437,8 @@ Last-Update: 2017-07-19
+ left=fs%(idx,total,col1,pc,col2)
+ right='][%s%s%s]'%(col1,self.timer,col2)
+ cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
-+ if cols<7:cols=7
++ if cols<7:
++ cols=7
+ ratio=((cols*idx)//total)-1
+ bar=('='*ratio+'>').ljust(cols)
+ msg=Logs.indicator%(left,bar,right)
@@ -470,7 +470,7 @@ Last-Update: 2017-07-19
+ return self.group_names[x]
+ return self.groups[x]
+ def add_to_group(self,tgen,group=None):
-+ assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.TaskBase))
++ assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.Task))
+ tgen.bld=self
+ self.get_group(group).append(tgen)
+ def get_group_name(self,g):
@@ -531,23 +531,20 @@ Last-Update: 2017-07-19
+ lst.extend(g)
+ return lst
+ def post_group(self):
++ def tgpost(tg):
++ try:
++ f=tg.post
++ except AttributeError:
++ pass
++ else:
++ f()
+ if self.targets=='*':
-+ for tg in self.groups[self.cur]:
-+ try:
-+ f=tg.post
-+ except AttributeError:
-+ pass
-+ else:
-+ f()
++ for tg in self.groups[self.current_group]:
++ tgpost(tg)
+ elif self.targets:
-+ if self.cur<self._min_grp:
-+ for tg in self.groups[self.cur]:
-+ try:
-+ f=tg.post
-+ except AttributeError:
-+ pass
-+ else:
-+ f()
++ if self.current_group<self._min_grp:
++ for tg in self.groups[self.current_group]:
++ tgpost(tg)
+ else:
+ for tg in self._exact_tg:
+ tg.post()
@@ -559,14 +556,14 @@ Last-Update: 2017-07-19
+ elif not ln.is_child_of(self.srcnode):
+ Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)',ln.abspath(),self.srcnode.abspath())
+ ln=self.srcnode
-+ for tg in self.groups[self.cur]:
++ for tg in self.groups[self.current_group]:
+ try:
-+ f=tg.post
++ p=tg.path
+ except AttributeError:
+ pass
+ else:
-+ if tg.path.is_child_of(ln):
-+ f()
++ if p.is_child_of(ln):
++ tgpost(tg)
+ def get_tasks_group(self,idx):
+ tasks=[]
+ for tg in self.groups[idx]:
@@ -576,26 +573,20 @@ Last-Update: 2017-07-19
+ tasks.append(tg)
+ return tasks
+ def get_build_iterator(self):
-+ self.cur=0
+ if self.targets and self.targets!='*':
+ (self._min_grp,self._exact_tg)=self.get_targets()
-+ global lazy_post
+ if self.post_mode!=POST_LAZY:
-+ while self.cur<len(self.groups):
++ for self.current_group,_ in enumerate(self.groups):
+ self.post_group()
-+ self.cur+=1
-+ self.cur=0
-+ while self.cur<len(self.groups):
++ for self.current_group,_ in enumerate(self.groups):
+ if self.post_mode!=POST_AT_ONCE:
+ self.post_group()
-+ tasks=self.get_tasks_group(self.cur)
++ tasks=self.get_tasks_group(self.current_group)
+ Task.set_file_constraints(tasks)
+ Task.set_precedence_constraints(tasks)
+ self.cur_tasks=tasks
-+ self.cur+=1
-+ if not tasks:
-+ continue
-+ yield tasks
++ if tasks:
++ yield tasks
+ while 1:
+ yield[]
+ def install_files(self,dest,files,**kw):
@@ -826,15 +817,6 @@ Last-Update: 2017-07-19
+ def __init__(self,**kw):
+ super(UninstallContext,self).__init__(**kw)
+ self.is_install=UNINSTALL
-+ def execute(self):
-+ try:
-+ def runnable_status(self):
-+ return Task.SKIP_ME
-+ setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status)
-+ setattr(Task.Task,'runnable_status',runnable_status)
-+ super(UninstallContext,self).execute()
-+ finally:
-+ setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back)
+class CleanContext(BuildContext):
+ '''cleans the project'''
+ cmd='clean'
@@ -849,7 +831,10 @@ Last-Update: 2017-07-19
+ self.store()
+ def clean(self):
+ Logs.debug('build: clean called')
-+ if self.bldnode!=self.srcnode:
++ if hasattr(self,'clean_files'):
++ for n in self.clean_files:
++ n.delete()
++ elif self.bldnode!=self.srcnode:
+ lst=[]
+ for env in self.all_envs.values():
+ lst.extend(self.root.find_or_declare(f)for f in env[CFG_FILES])
@@ -884,8 +869,15 @@ Last-Update: 2017-07-19
+ self.get_tgen_by_name('')
+ except Errors.WafError:
+ pass
-+ for k in sorted(self.task_gen_cache_names.keys()):
-+ Logs.pprint('GREEN',k)
++ targets=sorted(self.task_gen_cache_names)
++ line_just=max(len(t)for t in targets)if targets else 0
++ for target in targets:
++ tgen=self.task_gen_cache_names[target]
++ descript=getattr(tgen,'description','')
++ if descript:
++ target=target.ljust(line_just)
++ descript=': %s'%descript
++ Logs.pprint('GREEN',target,label=descript)
+class StepContext(BuildContext):
+ '''executes tasks in a step-by-step fashion, for debugging'''
+ cmd='step'
@@ -913,17 +905,17 @@ Last-Update: 2017-07-19
+ for pat in self.files.split(','):
+ matcher=self.get_matcher(pat)
+ for tg in g:
-+ if isinstance(tg,Task.TaskBase):
++ if isinstance(tg,Task.Task):
+ lst=[tg]
+ else:
+ lst=tg.tasks
+ for tsk in lst:
+ do_exec=False
-+ for node in getattr(tsk,'inputs',[]):
++ for node in tsk.inputs:
+ if matcher(node,output=False):
+ do_exec=True
+ break
-+ for node in getattr(tsk,'outputs',[]):
++ for node in tsk.outputs:
+ if matcher(node,output=True):
+ do_exec=True
+ break
@@ -948,9 +940,9 @@ Last-Update: 2017-07-19
+ pat='%s$'%pat
+ pattern=re.compile(pat)
+ def match(node,output):
-+ if output==True and not out:
++ if output and not out:
+ return False
-+ if output==False and not inn:
++ if not output and not inn:
+ return False
+ if anode:
+ return anode==node
@@ -966,7 +958,7 @@ Last-Update: 2017-07-19
+ self.recurse([self.run_dir])
--- /dev/null
+++ b/waflib/ConfigSet.py
-@@ -0,0 +1,159 @@
+@@ -0,0 +1,165 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -981,9 +973,12 @@ Last-Update: 2017-07-19
+ if filename:
+ self.load(filename)
+ def __contains__(self,key):
-+ if key in self.table:return True
-+ try:return self.parent.__contains__(key)
-+ except AttributeError:return False
++ if key in self.table:
++ return True
++ try:
++ return self.parent.__contains__(key)
++ except AttributeError:
++ return False
+ def keys(self):
+ keys=set()
+ cur=self
@@ -1012,7 +1007,7 @@ Last-Update: 2017-07-19
+ self[key]=[]
+ def __getattr__(self,name):
+ if name in self.__slots__:
-+ return object.__getattr__(self,name)
++ return object.__getattribute__(self,name)
+ else:
+ return self[name]
+ def __setattr__(self,name,value):
@@ -1043,7 +1038,8 @@ Last-Update: 2017-07-19
+ return self
+ def get_flat(self,key):
+ s=self[key]
-+ if isinstance(s,str):return s
++ if isinstance(s,str):
++ return s
+ return' '.join(s)
+ def _get_list_value_for_modification(self,key):
+ try:
@@ -1084,8 +1080,10 @@ Last-Update: 2017-07-19
+ env=self
+ while 1:
+ table_list.insert(0,env.table)
-+ try:env=env.parent
-+ except AttributeError:break
++ try:
++ env=env.parent
++ except AttributeError:
++ break
+ merged_table={}
+ for table in table_list:
+ merged_table.update(table)
@@ -1133,7 +1131,7 @@ Last-Update: 2017-07-19
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import os,shlex,sys,time,re,shutil
++import os,re,shlex,shutil,sys,time,traceback
+from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
+WAF_CONFIG_LOG='config.log'
+autoconfig=False
@@ -1227,26 +1225,26 @@ Last-Update: 2017-07-19
+ env.hash=self.hash
+ env.files=self.files
+ env.environ=dict(self.environ)
-+ if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options,'no_lock_in_run'):
++ if not(self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN')or getattr(Options.options,'no_lock_in_run')):
+ env.store(os.path.join(Context.run_dir,Options.lockfile))
-+ if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options,'no_lock_in_top'):
++ if not(self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP')or getattr(Options.options,'no_lock_in_top')):
+ env.store(os.path.join(Context.top_dir,Options.lockfile))
-+ if not self.env.NO_LOCK_IN_OUT and not getattr(Options.options,'no_lock_in_out'):
++ if not(self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT')or getattr(Options.options,'no_lock_in_out')):
+ 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:
-+ env.PREFIX=Utils.sane_path(Options.options.prefix)
++ env.PREFIX=Options.options.prefix
+ else:
-+ env.PREFIX=''
++ env.PREFIX='/'
+ if not env.BINDIR:
+ if Options.options.bindir:
-+ env.BINDIR=Utils.sane_path(Options.options.bindir)
++ env.BINDIR=Options.options.bindir
+ else:
+ env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
+ if not env.LIBDIR:
+ if Options.options.libdir:
-+ env.LIBDIR=Utils.sane_path(Options.options.libdir)
++ env.LIBDIR=Options.options.libdir
+ else:
+ env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env)
+ def store(self):
@@ -1257,9 +1255,10 @@ Last-Update: 2017-07-19
+ 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,with_sys_path=True,cache=False):
-+ tools=Utils.to_list(input)
-+ if tooldir:tooldir=Utils.to_list(tooldir)
++ def load(self,tool_list,tooldir=None,funs=None,with_sys_path=True,cache=False):
++ tools=Utils.to_list(tool_list)
++ if tooldir:
++ tooldir=Utils.to_list(tooldir)
+ for tool in tools:
+ if cache:
+ mag=(tool,id(self.env),tooldir,funs)
@@ -1271,18 +1270,20 @@ Last-Update: 2017-07-19
+ try:
+ module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path)
+ except ImportError as e:
-+ self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,sys.path,e))
++ self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,getattr(e,'waf_sys_path',sys.path),e))
+ except Exception as e:
+ self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
-+ self.to_log(Utils.ex_stack())
++ self.to_log(traceback.format_exc())
+ raise
+ if funs is not None:
+ self.eval_rules(funs)
+ else:
+ func=getattr(module,'configure',None)
+ if func:
-+ if type(func)is type(Utils.readf):func(self)
-+ else:self.eval_rules(func)
++ if type(func)is type(Utils.readf):
++ func(self)
++ else:
++ self.eval_rules(func)
+ self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
+ def post_recurse(self,node):
+ super(ConfigurationContext,self).post_recurse(node)
@@ -1297,10 +1298,7 @@ Last-Update: 2017-07-19
+ f()
+def conf(f):
+ def fun(*k,**kw):
-+ mandatory=True
-+ if'mandatory'in kw:
-+ mandatory=kw['mandatory']
-+ del kw['mandatory']
++ mandatory=kw.pop('mandatory',True)
+ try:
+ return f(*k,**kw)
+ except Errors.ConfigurationError:
@@ -1332,7 +1330,7 @@ Last-Update: 2017-07-19
+ return shlex.split(cmd)
+ return cmd
+@conf
-+def check_waf_version(self,mini='1.8.99',maxi='2.0.0',**kw):
++def check_waf_version(self,mini='1.9.99',maxi='2.1.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:
@@ -1365,7 +1363,7 @@ Last-Update: 2017-07-19
+ path_list=environ.get('PATH','').split(os.pathsep)
+ if kw.get('value'):
+ ret=self.cmd_to_list(kw['value'])
-+ elif var in environ:
++ elif environ.get(var):
+ ret=self.cmd_to_list(environ[var])
+ elif self.env[var]:
+ ret=self.cmd_to_list(self.env[var])
@@ -1438,7 +1436,7 @@ Last-Update: 2017-07-19
+ bdir=os.path.join(dir,'testbuild')
+ if not os.path.exists(bdir):
+ os.makedirs(bdir)
-+ cls_name=getattr(self,'run_build_cls','build')
++ cls_name=kw.get('run_build_cls')or getattr(self,'run_build_cls','build')
+ self.test_bld=bld=Context.create_context(cls_name,top_dir=dir,out_dir=bdir)
+ bld.init_dirs()
+ bld.progress_bar=0
@@ -1454,7 +1452,7 @@ Last-Update: 2017-07-19
+ try:
+ bld.compile()
+ except Errors.WafError:
-+ ret='Test does not build: %s'%Utils.ex_stack()
++ ret='Test does not build: %s'%traceback.format_exc()
+ self.fatal(ret)
+ else:
+ ret=getattr(bld,'retval',0)
@@ -1499,7 +1497,7 @@ Last-Update: 2017-07-19
+ return ret
--- /dev/null
+++ b/waflib/Context.py
-@@ -0,0 +1,396 @@
+@@ -0,0 +1,406 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -1507,10 +1505,10 @@ Last-Update: 2017-07-19
+import os,re,imp,sys
+from waflib import Utils,Errors,Logs
+import waflib.Node
-+HEXVERSION=0x1090800
-+WAFVERSION="1.9.8"
-+WAFREVISION="ffcbf5d4020624dcd1b9338005e3e10dcbebf8f1"
-+ABI=99
++HEXVERSION=0x2000900
++WAFVERSION="2.0.9"
++WAFREVISION="8a950e7bca9a3a9b1ae62aae039ef76e2adc4177"
++ABI=20
+DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
+APPNAME='APPNAME'
+VERSION='VERSION'
@@ -1522,13 +1520,13 @@ Last-Update: 2017-07-19
+top_dir=''
+out_dir=''
+waf_dir=''
++default_encoding=Utils.console_encoding()
+g_module=None
+STDOUT=1
+STDERR=-1
+BOTH=0
+classes=[]
+def create_context(cmd_name,*k,**kw):
-+ global classes
+ for x in classes:
+ if x.cmd==cmd_name:
+ return x(*k,**kw)
@@ -1536,8 +1534,8 @@ Last-Update: 2017-07-19
+ ctx.fun=cmd_name
+ return ctx
+class store_context(type):
-+ def __init__(cls,name,bases,dict):
-+ super(store_context,cls).__init__(name,bases,dict)
++ def __init__(cls,name,bases,dct):
++ super(store_context,cls).__init__(name,bases,dct)
+ name=cls.__name__
+ if name in('ctx','Context'):
+ return
@@ -1547,7 +1545,6 @@ Last-Update: 2017-07-19
+ raise Errors.WafError('Missing command for the context class %r (cmd)'%name)
+ if not getattr(cls,'fun',None):
+ cls.fun=cls.cmd
-+ global classes
+ classes.insert(0,cls)
+ctx=store_context('ctx',(object,),{})
+class Context(ctx):
@@ -1557,7 +1554,6 @@ Last-Update: 2017-07-19
+ try:
+ rd=kw['run_dir']
+ except KeyError:
-+ global run_dir
+ rd=run_dir
+ self.node_class=type('Nod3',(waflib.Node.Node,),{})
+ self.node_class.__module__='waflib.Node'
@@ -1586,7 +1582,6 @@ Last-Update: 2017-07-19
+ if fun:
+ fun(self)
+ def execute(self):
-+ global g_module
+ self.recurse([os.path.dirname(g_module.root_path)])
+ def pre_recurse(self,node):
+ self.stack_path.append(self.cur_script)
@@ -1639,11 +1634,18 @@ Last-Update: 2017-07-19
+ except OSError:
+ raise Errors.WafError('Cannot read the folder %r'%d)
+ raise Errors.WafError('No wscript file in directory %s'%d)
++ def log_command(self,cmd,kw):
++ if Logs.verbose:
++ fmt=os.environ.get('WAF_CMD_FORMAT')
++ if fmt=='string':
++ if not isinstance(cmd,str):
++ cmd=Utils.shell_escape(cmd)
++ Logs.debug('runner: %r',cmd)
++ Logs.debug('runner_env: kw=%s',kw)
+ def exec_command(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
-+ Logs.debug('runner: %r',cmd)
-+ Logs.debug('runner_env: kw=%s',kw)
++ self.log_command(cmd,kw)
+ if self.logger:
+ self.logger.info(cmd)
+ if'stdout'not in kw:
@@ -1667,20 +1669,21 @@ Last-Update: 2017-07-19
+ if'cwd'in kw:
+ if not isinstance(kw['cwd'],str):
+ kw['cwd']=kw['cwd'].abspath()
++ encoding=kw.pop('decode_as',default_encoding)
+ try:
+ ret,out,err=Utils.run_process(cmd,kw,cargs)
+ except Exception as e:
+ raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+ if out:
+ if not isinstance(out,str):
-+ out=out.decode(sys.stdout.encoding or'iso8859-1',errors='replace')
++ out=out.decode(encoding,errors='replace')
+ if self.logger:
+ self.logger.debug('out: %s',out)
+ else:
+ Logs.info(out,extra={'stream':sys.stdout,'c1':''})
+ if err:
+ if not isinstance(err,str):
-+ err=err.decode(sys.stdout.encoding or'iso8859-1',errors='replace')
++ err=err.decode(encoding,errors='replace')
+ if self.logger:
+ self.logger.error('err: %s'%err)
+ else:
@@ -1689,17 +1692,9 @@ Last-Update: 2017-07-19
+ def cmd_and_log(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
-+ Logs.debug('runner: %r',cmd)
-+ if'quiet'in kw:
-+ quiet=kw['quiet']
-+ del kw['quiet']
-+ else:
-+ quiet=None
-+ if'output'in kw:
-+ to_ret=kw['output']
-+ del kw['output']
-+ else:
-+ to_ret=STDOUT
++ self.log_command(cmd,kw)
++ quiet=kw.pop('quiet',None)
++ to_ret=kw.pop('output',STDOUT)
+ if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
+ raise Errors.WafError('Program %r not found!'%cmd[0])
+ kw['stdout']=kw['stderr']=subprocess.PIPE
@@ -1720,14 +1715,15 @@ Last-Update: 2017-07-19
+ if'cwd'in kw:
+ if not isinstance(kw['cwd'],str):
+ kw['cwd']=kw['cwd'].abspath()
++ encoding=kw.pop('decode_as',default_encoding)
+ try:
+ ret,out,err=Utils.run_process(cmd,kw,cargs)
+ except Exception as e:
+ raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+ if not isinstance(out,str):
-+ out=out.decode(sys.stdout.encoding or'iso8859-1',errors='replace')
++ out=out.decode(encoding,errors='replace')
+ if not isinstance(err,str):
-+ err=err.decode(sys.stdout.encoding or'iso8859-1',errors='replace')
++ err=err.decode(encoding,errors='replace')
+ if out and quiet!=STDOUT and quiet!=BOTH:
+ self.to_log('out: %s'%out)
+ if err and quiet!=STDERR and quiet!=BOTH:
@@ -1747,9 +1743,14 @@ Last-Update: 2017-07-19
+ if self.logger:
+ self.logger.info('from %s: %s'%(self.path.abspath(),msg))
+ try:
-+ msg='%s\n(complete log in %s)'%(msg,self.logger.handlers[0].baseFilename)
++ logfile=self.logger.handlers[0].baseFilename
+ except AttributeError:
+ pass
++ else:
++ if os.environ.get('WAF_PRINT_FAILURE_LOG'):
++ msg='Log from (%s):\n%s\n'%(logfile,Utils.readf(logfile))
++ else:
++ msg='%s\n(complete log in %s)'%(msg,logfile)
+ raise self.errors.ConfigurationError(msg,ex=ex)
+ def to_log(self,msg):
+ if not msg:
@@ -1799,9 +1800,9 @@ Last-Update: 2017-07-19
+ return
+ result=kw.get('result')or k[0]
+ defcolor='GREEN'
-+ if result==True:
++ if result is True:
+ msg='ok'
-+ elif result==False:
++ elif not result:
+ msg='not found'
+ defcolor='YELLOW'
+ else:
@@ -1816,7 +1817,6 @@ Last-Update: 2017-07-19
+ color=defcolor
+ Logs.pprint(color,msg)
+ def load_special_tools(self,var,ban=[]):
-+ global waf_dir
+ if os.path.isdir(waf_dir):
+ lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
+ for x in lst:
@@ -1871,6 +1871,9 @@ Last-Update: 2017-07-19
+ sys.path=tooldir+sys.path
+ try:
+ __import__(tool)
++ except ImportError as e:
++ e.waf_sys_path=list(sys.path)
++ raise
+ finally:
+ for d in tooldir:
+ sys.path.remove(d)
@@ -1878,7 +1881,8 @@ Last-Update: 2017-07-19
+ Context.tools[tool]=ret
+ return ret
+ else:
-+ if not with_sys_path:sys.path.insert(0,waf_dir)
++ if not with_sys_path:
++ sys.path.insert(0,waf_dir)
+ try:
+ for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
+ try:
@@ -1888,8 +1892,12 @@ Last-Update: 2017-07-19
+ x=None
+ else:
+ __import__(tool)
++ except ImportError as e:
++ e.waf_sys_path=list(sys.path)
++ raise
+ finally:
-+ if not with_sys_path:sys.path.remove(waf_dir)
++ if not with_sys_path:
++ sys.path.remove(waf_dir)
+ ret=sys.modules[x%tool]
+ Context.tools[tool]=ret
+ return ret
@@ -1898,7 +1906,7 @@ Last-Update: 2017-07-19
+ sys.path+=back_path
--- /dev/null
+++ b/waflib/Errors.py
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -1906,6 +1914,7 @@ Last-Update: 2017-07-19
+import traceback,sys
+class WafError(Exception):
+ def __init__(self,msg='',ex=None):
++ Exception.__init__(self)
+ self.msg=msg
+ assert not isinstance(msg,Exception)
+ self.stack=[]
@@ -1928,7 +1937,8 @@ Last-Update: 2017-07-19
+ lst=['Build failed']
+ for tsk in self.tasks:
+ txt=tsk.format_error()
-+ if txt:lst.append(txt)
++ if txt:
++ lst.append(txt)
+ return'\n'.join(lst)
+class ConfigurationError(WafError):
+ pass
@@ -1938,7 +1948,7 @@ Last-Update: 2017-07-19
+ pass
--- /dev/null
+++ b/waflib/Logs.py
-@@ -0,0 +1,205 @@
+@@ -0,0 +1,203 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -2000,7 +2010,6 @@ Last-Update: 2017-07-19
+ def __init__(self,name=''):
+ logging.Filter.__init__(self,name)
+ def filter(self,rec):
-+ global verbose
+ rec.zone=rec.module
+ if rec.levelno>=logging.INFO:
+ return True
@@ -2081,14 +2090,11 @@ Last-Update: 2017-07-19
+ return logging.Formatter.format(self,rec)
+log=None
+def debug(*k,**kw):
-+ global verbose
+ if verbose:
+ k=list(k)
+ k[0]=k[0].replace('\n',' ')
-+ global log
+ log.debug(*k,**kw)
+def error(*k,**kw):
-+ global log,verbose
+ log.error(*k,**kw)
+ if verbose>2:
+ st=traceback.extract_stack()
@@ -2099,12 +2105,11 @@ Last-Update: 2017-07-19
+ buf.append(' File %r, line %d, in %s'%(filename,lineno,name))
+ if line:
+ buf.append(' %s'%line.strip())
-+ if buf:log.error('\n'.join(buf))
++ if buf:
++ log.error('\n'.join(buf))
+def warn(*k,**kw):
-+ global log
+ log.warn(*k,**kw)
+def info(*k,**kw):
-+ global log
+ log.info(*k,**kw)
+def init_log():
+ global log
@@ -2118,7 +2123,11 @@ Last-Update: 2017-07-19
+ log.setLevel(logging.DEBUG)
+def make_logger(path,name):
+ logger=logging.getLogger(name)
-+ hdlr=logging.FileHandler(path,'w')
++ if sys.hexversion>0x3000000:
++ encoding=sys.stdout.encoding
++ else:
++ encoding=None
++ hdlr=logging.FileHandler(path,'w',encoding=encoding)
+ formatter=logging.Formatter('%(message)s')
+ hdlr.setFormatter(formatter)
+ logger.addHandler(hdlr)
@@ -2142,11 +2151,10 @@ Last-Update: 2017-07-19
+ except Exception:
+ pass
+def pprint(col,msg,label='',sep='\n'):
-+ global info
+ info('%s%s%s %s',colors(col),msg,colors.NORMAL,label,extra={'terminator':sep})
--- /dev/null
+++ b/waflib/Node.py
-@@ -0,0 +1,485 @@
+@@ -0,0 +1,478 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -2159,6 +2167,7 @@ Last-Update: 2017-07-19
+**/.#*
+**/%*%
+**/._*
++**/*.swp
+**/CVS
+**/CVS/**
+**/.cvsignore
@@ -2184,6 +2193,49 @@ Last-Update: 2017-07-19
+**/_darcs/**
+**/.intlcache
+**/.DS_Store'''
++def ant_matcher(s,ignorecase):
++ reflags=re.I if ignorecase else 0
++ ret=[]
++ for x in Utils.to_list(s):
++ x=x.replace('\\','/').replace('//','/')
++ if x.endswith('/'):
++ x+='**'
++ accu=[]
++ for k in x.split('/'):
++ if k=='**':
++ accu.append(k)
++ else:
++ k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
++ k='^%s$'%k
++ try:
++ exp=re.compile(k,flags=reflags)
++ except Exception as e:
++ raise Errors.WafError('Invalid pattern: %s'%k,e)
++ else:
++ accu.append(exp)
++ ret.append(accu)
++ return ret
++def ant_sub_filter(name,nn):
++ ret=[]
++ for lst in nn:
++ if not lst:
++ pass
++ elif lst[0]=='**':
++ ret.append(lst)
++ if len(lst)>1:
++ if lst[1].match(name):
++ ret.append(lst[2:])
++ else:
++ ret.append([])
++ elif lst[0].match(name):
++ ret.append(lst[1:])
++ return ret
++def ant_sub_matcher(name,pats):
++ nacc=ant_sub_filter(name,pats[0])
++ nrej=ant_sub_filter(name,pats[1])
++ if[]in nrej:
++ nacc=[]
++ return[nacc,nrej]
+class Node(object):
+ dict_class=dict
+ __slots__=('name','parent','children','cache_abspath','cache_isdir')
@@ -2207,9 +2259,9 @@ Last-Update: 2017-07-19
+ return self.abspath()
+ def __copy__(self):
+ raise Errors.WafError('nodes are not supposed to be copied')
-+ def read(self,flags='r',encoding='ISO8859-1'):
++ def read(self,flags='r',encoding='latin-1'):
+ return Utils.readf(self.abspath(),flags,encoding)
-+ def write(self,data,flags='w',encoding='ISO8859-1'):
++ def write(self,data,flags='w',encoding='latin-1'):
+ Utils.writef(self.abspath(),data,flags,encoding)
+ def read_json(self,convert=True,encoding='utf-8'):
+ import json
@@ -2298,6 +2350,10 @@ Last-Update: 2017-07-19
+ def find_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in Utils.split_path(lst)if x and x!='.']
++ if lst and lst[0].startswith('\\\\')and not self.parent:
++ node=self.ctx.root.make_node(lst[0])
++ node.cache_isdir=True
++ return node.find_node(lst[1:])
+ cur=self
+ for x in lst:
+ if x=='..':
@@ -2412,7 +2468,7 @@ Last-Update: 2017-07-19
+ diff-=1
+ p=p.parent
+ return p is node
-+ def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True):
++ def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False):
+ dircont=self.listdir()
+ dircont.sort()
+ try:
@@ -2433,67 +2489,29 @@ Last-Update: 2017-07-19
+ if isdir:
+ if dir:
+ yield node
-+ else:
-+ if src:
-+ yield node
++ elif src:
++ yield node
+ if isdir:
+ node.cache_isdir=True
+ if maxdepth:
-+ for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove):
++ for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove,quiet=quiet):
+ yield k
-+ raise StopIteration
+ def ant_glob(self,*k,**kw):
+ src=kw.get('src',True)
-+ dir=kw.get('dir',False)
++ dir=kw.get('dir')
+ excl=kw.get('excl',exclude_regs)
+ incl=k and k[0]or kw.get('incl','**')
-+ reflags=kw.get('ignorecase',0)and re.I
-+ def to_pat(s):
-+ lst=Utils.to_list(s)
-+ ret=[]
-+ for x in lst:
-+ x=x.replace('\\','/').replace('//','/')
-+ if x.endswith('/'):
-+ x+='**'
-+ lst2=x.split('/')
-+ accu=[]
-+ for k in lst2:
-+ if k=='**':
-+ accu.append(k)
-+ else:
-+ k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
-+ k='^%s$'%k
-+ try:
-+ accu.append(re.compile(k,flags=reflags))
-+ except Exception as e:
-+ raise Errors.WafError('Invalid pattern: %s'%k,e)
-+ ret.append(accu)
-+ return ret
-+ def filtre(name,nn):
-+ ret=[]
-+ for lst in nn:
-+ if not lst:
-+ pass
-+ elif lst[0]=='**':
-+ ret.append(lst)
-+ if len(lst)>1:
-+ if lst[1].match(name):
-+ ret.append(lst[2:])
-+ else:
-+ ret.append([])
-+ elif lst[0].match(name):
-+ ret.append(lst[1:])
-+ return ret
-+ def accept(name,pats):
-+ nacc=filtre(name,pats[0])
-+ nrej=filtre(name,pats[1])
-+ if[]in nrej:
-+ nacc=[]
-+ return[nacc,nrej]
-+ ret=[x for x in self.ant_iter(accept=accept,pats=[to_pat(incl),to_pat(excl)],maxdepth=kw.get('maxdepth',25),dir=dir,src=src,remove=kw.get('remove',True))]
-+ if kw.get('flat',False):
-+ return' '.join([x.path_from(self)for x in ret])
-+ return ret
++ remove=kw.get('remove',True)
++ maxdepth=kw.get('maxdepth',25)
++ ignorecase=kw.get('ignorecase',False)
++ quiet=kw.get('quiet',False)
++ pats=(ant_matcher(incl,ignorecase),ant_matcher(excl,ignorecase))
++ if kw.get('generator'):
++ return Utils.lazy_generator(self.ant_iter,(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet))
++ it=self.ant_iter(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet)
++ if kw.get('flat'):
++ return' '.join(x.path_from(self)for x in it)
++ return list(it)
+ def is_src(self):
+ cur=self
+ x=self.ctx.srcnode
@@ -2554,18 +2572,10 @@ Last-Update: 2017-07-19
+ return None
+ return node
+ def find_or_declare(self,lst):
-+ if isinstance(lst,str):
-+ lst=[x for x in Utils.split_path(lst)if x and x!='.']
-+ node=self.get_bld().search_node(lst)
-+ if node:
-+ if not os.path.isfile(node.abspath()):
-+ node.parent.mkdir()
-+ return node
-+ self=self.get_src()
-+ node=self.find_node(lst)
-+ if node:
-+ return node
-+ node=self.get_bld().make_node(lst)
++ if isinstance(lst,str)and os.path.isabs(lst):
++ node=self.ctx.root.make_node(lst)
++ else:
++ node=self.get_bld().make_node(lst)
+ node.parent.mkdir()
+ return node
+ def find_dir(self,lst):
@@ -2620,36 +2630,37 @@ Last-Update: 2017-07-19
+ return ret
+ raise
+ return ret
-+ def get_sig(self):
-+ return self.h_file()
-+ def set_sig(self,val):
-+ try:
-+ del self.get_bld_sig.__cache__[(self,)]
-+ except(AttributeError,KeyError):
-+ pass
-+ sig=property(get_sig,set_sig)
-+ cache_sig=property(get_sig,set_sig)
+pickle_lock=Utils.threading.Lock()
+class Nod3(Node):
+ pass
--- /dev/null
+++ b/waflib/Options.py
-@@ -0,0 +1,147 @@
+@@ -0,0 +1,200 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,tempfile,optparse,sys,re
+from waflib import Logs,Utils,Context,Errors
-+options={}
++options=optparse.Values()
+commands=[]
+envvars=[]
+lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%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))
++ def __init__(self,ctx,allow_unknown=False):
++ optparse.OptionParser.__init__(self,conflict_handler='resolve',add_help_option=False,version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION))
+ self.formatter.width=Logs.get_term_cols()
+ self.ctx=ctx
++ self.allow_unknown=allow_unknown
++ def _process_args(self,largs,rargs,values):
++ while rargs:
++ try:
++ optparse.OptionParser._process_args(self,largs,rargs,values)
++ except(optparse.BadOptionError,optparse.AmbiguousOptionError)as e:
++ if self.allow_unknown:
++ largs.append(e.opt_str)
++ else:
++ self.error(str(e))
+ def print_usage(self,file=None):
+ return self.print_help(file)
+ def get_usage(self):
@@ -2687,12 +2698,18 @@ Last-Update: 2017-07-19
+ jobs=self.jobs()
+ p=self.add_option
+ color=os.environ.get('NOCOLOR','')and'no'or'auto'
++ if os.environ.get('CLICOLOR','')=='0':
++ color='no'
++ elif os.environ.get('CLICOLOR_FORCE','')=='1':
++ color='yes'
+ 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)')
-+ p('--profile',dest='profile',default='',action='store_true',help=optparse.SUPPRESS_HELP)
++ p('--profile',dest='profile',default=0,action='store_true',help=optparse.SUPPRESS_HELP)
++ p('--pdb',dest='pdb',default=0,action='store_true',help=optparse.SUPPRESS_HELP)
++ p('-h','--help',dest='whelp',default=0,action='store_true',help="show this help message and exit")
+ 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')
@@ -2764,38 +2781,111 @@ Last-Update: 2017-07-19
+ if group.title==opt_str:
+ return group
+ return None
-+ def parse_args(self,_args=None):
-+ global options,commands,envvars
++ def sanitize_path(self,path,cwd=None):
++ if not cwd:
++ cwd=Context.launch_dir
++ p=os.path.expanduser(path)
++ p=os.path.join(cwd,p)
++ p=os.path.normpath(p)
++ p=os.path.abspath(p)
++ return p
++ def parse_cmd_args(self,_args=None,cwd=None,allow_unknown=False):
++ self.parser.allow_unknown=allow_unknown
+ (options,leftover_args)=self.parser.parse_args(args=_args)
++ envvars=[]
++ commands=[]
+ for arg in leftover_args:
+ if'='in arg:
+ envvars.append(arg)
-+ else:
++ elif arg!='options':
+ commands.append(arg)
-+ if options.destdir:
-+ options.destdir=Utils.sane_path(options.destdir)
++ for name in'top out destdir prefix bindir libdir'.split():
++ if getattr(options,name,None):
++ path=self.sanitize_path(getattr(options,name),cwd)
++ setattr(options,name,path)
++ return options,commands,envvars
++ def init_module_vars(self,arg_options,arg_commands,arg_envvars):
++ options.__dict__.clear()
++ del commands[:]
++ del envvars[:]
++ options.__dict__.update(arg_options.__dict__)
++ commands.extend(arg_commands)
++ envvars.extend(arg_envvars)
++ for var in envvars:
++ (name,value)=var.split('=',1)
++ os.environ[name.strip()]=value
++ def init_logs(self,options,commands,envvars):
++ Logs.verbose=options.verbose
+ if options.verbose>=1:
+ self.load('errcheck')
+ colors={'yes':2,'auto':1,'no':0}[options.colors]
+ Logs.enable_colors(colors)
++ if options.zones:
++ Logs.zones=options.zones.split(',')
++ if not Logs.verbose:
++ Logs.verbose=1
++ elif Logs.verbose>0:
++ Logs.zones=['runner']
++ if Logs.verbose>2:
++ Logs.zones=['*']
++ def parse_args(self,_args=None):
++ options,commands,envvars=self.parse_cmd_args()
++ self.init_logs(options,commands,envvars)
++ self.init_module_vars(options,commands,envvars)
+ def execute(self):
+ super(OptionsContext,self).execute()
+ self.parse_args()
+ Utils.alloc_process_pool(options.jobs)
--- /dev/null
+++ b/waflib/Runner.py
-@@ -0,0 +1,181 @@
+@@ -0,0 +1,350 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import random
++import heapq,traceback
+try:
-+ from queue import Queue
++ from queue import Queue,PriorityQueue
+except ImportError:
+ from Queue import Queue
++ try:
++ from Queue import PriorityQueue
++ except ImportError:
++ class PriorityQueue(Queue):
++ def _init(self,maxsize):
++ self.maxsize=maxsize
++ self.queue=[]
++ def _put(self,item):
++ heapq.heappush(self.queue,item)
++ def _get(self):
++ return heapq.heappop(self.queue)
+from waflib import Utils,Task,Errors,Logs
-+GAP=20
++GAP=5
++class PriorityTasks(object):
++ def __init__(self):
++ self.lst=[]
++ def __len__(self):
++ return len(self.lst)
++ def __iter__(self):
++ return iter(self.lst)
++ def clear(self):
++ self.lst=[]
++ def append(self,task):
++ heapq.heappush(self.lst,task)
++ def appendleft(self,task):
++ heapq.heappush(self.lst,task)
++ def pop(self):
++ return heapq.heappop(self.lst)
++ def extend(self,lst):
++ if self.lst:
++ for x in lst:
++ self.append(x)
++ else:
++ if isinstance(lst,list):
++ self.lst=lst
++ heapq.heapify(lst)
++ else:
++ self.lst=lst.lst
+class Consumer(Utils.threading.Thread):
+ def __init__(self,spawner,task):
+ Utils.threading.Thread.__init__(self)
@@ -2806,7 +2896,7 @@ Last-Update: 2017-07-19
+ def run(self):
+ try:
+ if not self.spawner.master.stop:
-+ self.task.process()
++ self.spawner.master.process_task(self.task)
+ finally:
+ self.spawner.sem.release()
+ self.spawner.master.out.put(self.task)
@@ -2836,77 +2926,134 @@ Last-Update: 2017-07-19
+ def __init__(self,bld,j=2):
+ self.numjobs=j
+ self.bld=bld
-+ self.outstanding=Utils.deque()
-+ self.frozen=Utils.deque()
-+ self.ready=Queue(0)
++ self.outstanding=PriorityTasks()
++ self.postponed=PriorityTasks()
++ self.incomplete=set()
++ self.ready=PriorityQueue(0)
+ self.out=Queue(0)
+ self.count=0
-+ self.processed=1
++ self.processed=0
+ self.stop=False
+ self.error=[]
+ self.biter=None
+ self.dirty=False
++ self.revdeps=Utils.defaultdict(set)
+ self.spawner=Spawner(self)
+ def get_next_task(self):
+ if not self.outstanding:
+ return None
-+ return self.outstanding.popleft()
++ return self.outstanding.pop()
+ def postpone(self,tsk):
-+ if random.randint(0,1):
-+ self.frozen.appendleft(tsk)
-+ else:
-+ self.frozen.append(tsk)
++ self.postponed.append(tsk)
+ def refill_task_list(self):
+ while self.count>self.numjobs*GAP:
+ self.get_out()
+ while not self.outstanding:
+ if self.count:
+ self.get_out()
-+ elif self.frozen:
++ if self.outstanding:
++ break
++ elif self.postponed:
+ try:
+ cond=self.deadlock==self.processed
+ except AttributeError:
+ pass
+ else:
+ if cond:
-+ msg='check the build order for the tasks'
-+ for tsk in self.frozen:
-+ if not tsk.run_after:
-+ msg='check the methods runnable_status'
-+ break
+ lst=[]
-+ for tsk in self.frozen:
-+ lst.append('%s\t-> %r'%(repr(tsk),[id(x)for x in tsk.run_after]))
-+ raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst)))
++ for tsk in self.postponed:
++ deps=[id(x)for x in tsk.run_after if not x.hasrun]
++ lst.append('%s\t-> %r'%(repr(tsk),deps))
++ if not deps:
++ lst.append('\n task %r dependencies are done, check its *runnable_status*?'%id(tsk))
++ raise Errors.WafError('Deadlock detected: check the task build order%s'%''.join(lst))
+ self.deadlock=self.processed
-+ if self.frozen:
-+ self.outstanding.extend(self.frozen)
-+ self.frozen.clear()
++ if self.postponed:
++ self.outstanding.extend(self.postponed)
++ self.postponed.clear()
+ elif not self.count:
-+ self.outstanding.extend(next(self.biter))
-+ self.total=self.bld.total()
-+ break
++ if self.incomplete:
++ for x in self.incomplete:
++ for k in x.run_after:
++ if not k.hasrun:
++ break
++ else:
++ self.incomplete.remove(x)
++ self.outstanding.append(x)
++ break
++ else:
++ raise Errors.WafError('Broken revdeps detected on %r'%self.incomplete)
++ else:
++ tasks=next(self.biter)
++ ready,waiting=self.prio_and_split(tasks)
++ self.outstanding.extend(ready)
++ self.incomplete.update(waiting)
++ self.total=self.bld.total()
++ break
+ def add_more_tasks(self,tsk):
+ if getattr(tsk,'more_tasks',None):
-+ self.outstanding.extend(tsk.more_tasks)
++ more=set(tsk.more_tasks)
++ groups_done=set()
++ def iteri(a,b):
++ for x in a:
++ yield x
++ for x in b:
++ yield x
++ for x in iteri(self.outstanding,self.incomplete):
++ for k in x.run_after:
++ if isinstance(k,Task.TaskGroup):
++ if k not in groups_done:
++ groups_done.add(k)
++ for j in k.prev&more:
++ self.revdeps[j].add(k)
++ elif k in more:
++ self.revdeps[k].add(x)
++ ready,waiting=self.prio_and_split(tsk.more_tasks)
++ self.outstanding.extend(ready)
++ self.incomplete.update(waiting)
+ self.total+=len(tsk.more_tasks)
++ def mark_finished(self,tsk):
++ def try_unfreeze(x):
++ if x in self.incomplete:
++ for k in x.run_after:
++ if not k.hasrun:
++ break
++ else:
++ self.incomplete.remove(x)
++ self.outstanding.append(x)
++ if tsk in self.revdeps:
++ for x in self.revdeps[tsk]:
++ if isinstance(x,Task.TaskGroup):
++ x.prev.remove(tsk)
++ if not x.prev:
++ for k in x.next:
++ k.run_after.remove(x)
++ try_unfreeze(k)
++ x.next=[]
++ else:
++ try_unfreeze(x)
++ del self.revdeps[tsk]
+ def get_out(self):
+ tsk=self.out.get()
+ if not self.stop:
+ self.add_more_tasks(tsk)
++ self.mark_finished(tsk)
+ self.count-=1
+ self.dirty=True
+ return tsk
+ def add_task(self,tsk):
+ self.ready.put(tsk)
++ def process_task(self,tsk):
++ tsk.process()
++ if tsk.hasrun!=Task.SUCCESS:
++ self.error_handler(tsk)
+ def skip(self,tsk):
+ tsk.hasrun=Task.SKIPPED
++ self.mark_finished(tsk)
++ def cancel(self,tsk):
++ tsk.hasrun=Task.CANCELED
++ self.mark_finished(tsk)
+ def error_handler(self,tsk):
-+ if hasattr(tsk,'scan')and hasattr(tsk,'uid'):
-+ try:
-+ del self.bld.imp_sigs[tsk.uid()]
-+ except KeyError:
-+ pass
+ if not self.bld.keep:
+ self.stop=True
+ self.error.append(tsk)
@@ -2915,7 +3062,7 @@ Last-Update: 2017-07-19
+ return tsk.runnable_status()
+ except Exception:
+ self.processed+=1
-+ tsk.err_msg=Utils.ex_stack()
++ tsk.err_msg=traceback.format_exc()
+ if not self.stop and self.bld.keep:
+ self.skip(tsk)
+ if self.bld.keep==1:
@@ -2951,28 +3098,105 @@ Last-Update: 2017-07-19
+ if self.numjobs==1:
+ tsk.log_display(tsk.generator.bld)
+ try:
-+ tsk.process()
++ self.process_task(tsk)
+ finally:
+ self.out.put(tsk)
+ else:
+ self.add_task(tsk)
-+ if st==Task.ASK_LATER:
++ elif st==Task.ASK_LATER:
+ self.postpone(tsk)
+ elif st==Task.SKIP_ME:
+ self.processed+=1
+ self.skip(tsk)
+ self.add_more_tasks(tsk)
++ elif st==Task.CANCEL_ME:
++ if Logs.verbose>1:
++ self.error.append(tsk)
++ self.processed+=1
++ self.cancel(tsk)
+ while self.error and self.count:
+ self.get_out()
+ self.ready.put(None)
-+ assert(self.count==0 or self.stop)
++ if not self.stop:
++ assert not self.count
++ assert not self.postponed
++ assert not self.incomplete
++ def prio_and_split(self,tasks):
++ for x in tasks:
++ x.visited=0
++ reverse=self.revdeps
++ groups_done=set()
++ for x in tasks:
++ for k in x.run_after:
++ if isinstance(k,Task.TaskGroup):
++ if k not in groups_done:
++ groups_done.add(k)
++ for j in k.prev:
++ reverse[j].add(k)
++ else:
++ reverse[k].add(x)
++ def visit(n):
++ if isinstance(n,Task.TaskGroup):
++ return sum(visit(k)for k in n.next)
++ if n.visited==0:
++ n.visited=1
++ if n in reverse:
++ rev=reverse[n]
++ n.prio_order=n.tree_weight+len(rev)+sum(visit(k)for k in rev)
++ else:
++ n.prio_order=n.tree_weight
++ n.visited=2
++ elif n.visited==1:
++ raise Errors.WafError('Dependency cycle found!')
++ return n.prio_order
++ for x in tasks:
++ if x.visited!=0:
++ continue
++ try:
++ visit(x)
++ except Errors.WafError:
++ self.debug_cycles(tasks,reverse)
++ ready=[]
++ waiting=[]
++ for x in tasks:
++ for k in x.run_after:
++ if not k.hasrun:
++ waiting.append(x)
++ break
++ else:
++ ready.append(x)
++ return(ready,waiting)
++ def debug_cycles(self,tasks,reverse):
++ tmp={}
++ for x in tasks:
++ tmp[x]=0
++ def visit(n,acc):
++ if isinstance(n,Task.TaskGroup):
++ for k in n.next:
++ visit(k,acc)
++ return
++ if tmp[n]==0:
++ tmp[n]=1
++ for k in reverse.get(n,[]):
++ visit(k,[n]+acc)
++ tmp[n]=2
++ elif tmp[n]==1:
++ lst=[]
++ for tsk in acc:
++ lst.append(repr(tsk))
++ if tsk is n:
++ break
++ raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s'%''.join(lst))
++ for x in tasks:
++ visit(x,[])
--- /dev/null
+++ b/waflib/Scripting.py
-@@ -0,0 +1,398 @@
+@@ -0,0 +1,403 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from __future__ import with_statement
+import os,shlex,shutil,traceback,errno,sys,stat
+from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
+build_dir_override=None
@@ -2983,35 +3207,32 @@ Last-Update: 2017-07-19
+ if Context.WAFVERSION!=version:
+ Logs.error('Waf script %r and library %r do not match (directory %r)',version,Context.WAFVERSION,wafdir)
+ sys.exit(1)
-+ if'--version'in sys.argv:
-+ Context.run_dir=current_directory
-+ ctx=Context.create_context('options')
-+ ctx.curdir=current_directory
-+ ctx.parse_args()
-+ sys.exit(0)
++ Context.waf_dir=wafdir
++ Context.run_dir=Context.launch_dir=current_directory
++ start_dir=current_directory
++ no_climb=os.environ.get('NOCLIMB')
+ 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))
++ if os.path.basename(potential_wscript)==Context.WSCRIPT_FILE and os.path.isfile(potential_wscript):
++ path=os.path.normpath(os.path.dirname(potential_wscript))
++ start_dir=os.path.abspath(path)
++ no_climb=True
+ sys.argv.pop(1)
-+ Context.waf_dir=wafdir
-+ Context.launch_dir=current_directory
-+ no_climb=os.environ.get('NOCLIMB')
++ ctx=Context.create_context('options')
++ (options,commands,env)=ctx.parse_cmd_args(allow_unknown=True)
++ if options.top:
++ start_dir=Context.run_dir=Context.top_dir=options.top
++ no_climb=True
++ if options.out:
++ Context.out_dir=options.out
+ if not no_climb:
+ for k in no_climb_commands:
-+ for y in sys.argv:
++ for y in commands:
+ if y.startswith(k):
+ no_climb=True
+ break
-+ for i,x in enumerate(sys.argv):
-+ if x.startswith('--top='):
-+ Context.run_dir=Context.top_dir=Utils.sane_path(x[6:])
-+ sys.argv[i]='--top='+Context.run_dir
-+ if x.startswith('--out='):
-+ Context.out_dir=Utils.sane_path(x[6:])
-+ sys.argv[i]='--out='+Context.out_dir
-+ cur=current_directory
-+ while cur and not Context.top_dir:
++ cur=start_dir
++ while cur:
+ try:
+ lst=os.listdir(cur)
+ except OSError:
@@ -3026,6 +3247,8 @@ Last-Update: 2017-07-19
+ pass
+ else:
+ for x in(env.run_dir,env.top_dir,env.out_dir):
++ if not x:
++ continue
+ if Utils.is_win32:
+ if cur==x:
+ load=True
@@ -3057,14 +3280,11 @@ Last-Update: 2017-07-19
+ if no_climb:
+ break
+ if not Context.run_dir:
-+ if'-h'in sys.argv or'--help'in sys.argv:
-+ Logs.warn('No wscript file found: the help message may be incomplete')
-+ Context.run_dir=current_directory
-+ ctx=Context.create_context('options')
-+ ctx.curdir=current_directory
-+ ctx.parse_args()
++ if options.whelp:
++ Logs.warn('These are the generic options (no wscript/project found)')
++ ctx.parser.print_help()
+ sys.exit(0)
-+ Logs.error('Waf: Run from a directory containing a file named %r',Context.WSCRIPT_FILE)
++ Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)',Context.WSCRIPT_FILE)
+ sys.exit(1)
+ try:
+ os.chdir(Context.run_dir)
@@ -3081,14 +3301,23 @@ Last-Update: 2017-07-19
+ Logs.error('Waf: The wscript in %r is unreadable',Context.run_dir)
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(2)
-+ if'--profile'in sys.argv:
++ if options.profile:
+ import cProfile,pstats
+ cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt')
+ p=pstats.Stats('profi.txt')
+ p.sort_stats('time').print_stats(75)
+ else:
+ try:
-+ run_commands()
++ try:
++ run_commands()
++ except:
++ if options.pdb:
++ import pdb
++ type,value,tb=sys.exc_info()
++ traceback.print_exc()
++ pdb.post_mortem(tb)
++ else:
++ raise
+ except Errors.WafError as e:
+ if Logs.verbose>1:
+ Logs.pprint('RED',e.verbose_msg)
@@ -3118,22 +3347,13 @@ Last-Update: 2017-07-19
+ if not'options'in Context.g_module.__dict__:
+ 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
++ ctx=Context.create_context('options')
++ ctx.execute()
+ if not Options.commands:
-+ Options.commands=[default_cmd]
-+ Options.commands=[x for x in Options.commands if x!='options']
-+ Logs.verbose=Options.options.verbose
-+ if Options.options.zones:
-+ Logs.zones=Options.options.zones.split(',')
-+ if not Logs.verbose:
-+ Logs.verbose=1
-+ elif Logs.verbose>0:
-+ Logs.zones=['runner']
-+ if Logs.verbose>2:
-+ Logs.zones=['*']
++ Options.commands.append(default_cmd)
++ if Options.options.whelp:
++ ctx.parser.print_help()
++ sys.exit(0)
+def run_command(cmd_name):
+ ctx=Context.create_context(cmd_name)
+ ctx.log_timer=Utils.Timer()
@@ -3171,34 +3391,43 @@ Last-Update: 2017-07-19
+ except OSError:
+ pass
+def distclean(ctx):
-+ '''removes the build directory'''
-+ lst=os.listdir('.')
-+ for f in lst:
-+ if f==Options.lockfile:
-+ try:
-+ proj=ConfigSet.ConfigSet(f)
-+ except IOError:
-+ Logs.warn('Could not read %r',f)
-+ continue
-+ if proj['out_dir']!=proj['top_dir']:
-+ try:
-+ shutil.rmtree(proj['out_dir'])
-+ except EnvironmentError as e:
-+ if e.errno!=errno.ENOENT:
-+ 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(p)
-+ except OSError as e:
-+ if e.errno!=errno.ENOENT:
-+ 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):
-+ shutil.rmtree(f,ignore_errors=True)
++ '''removes build folders and data'''
++ def remove_and_log(k,fun):
++ try:
++ fun(k)
++ except EnvironmentError as e:
++ if e.errno!=errno.ENOENT:
++ Logs.warn('Could not remove %r',k)
++ if not Options.commands:
++ for k in os.listdir('.'):
++ for x in'.waf-2 waf-2 .waf3-2 waf3-2'.split():
++ if k.startswith(x):
++ remove_and_log(k,shutil.rmtree)
++ cur='.'
++ if ctx.options.no_lock_in_top:
++ cur=ctx.options.out
++ try:
++ lst=os.listdir(cur)
++ except OSError:
++ Logs.warn('Could not read %r',cur)
++ return
++ if Options.lockfile in lst:
++ f=os.path.join(cur,Options.lockfile)
++ try:
++ env=ConfigSet.ConfigSet(f)
++ except EnvironmentError:
++ Logs.warn('Could not read %r',f)
++ return
++ if not env.out_dir or not env.top_dir:
++ Logs.warn('Invalid lock file %r',f)
++ return
++ if env.out_dir==env.top_dir:
++ distclean_dir(env.out_dir)
++ else:
++ remove_and_log(env.out_dir,shutil.rmtree)
++ for k in(env.out_dir,env.top_dir,env.run_dir):
++ p=os.path.join(k,Options.lockfile)
++ remove_and_log(p,os.remove)
+class Dist(Context.Context):
+ '''creates an archive containing the project source code'''
+ cmd='dist'
@@ -3236,11 +3465,11 @@ Last-Update: 2017-07-19
+ else:
+ self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip')
+ try:
-+ from hashlib import sha1
++ from hashlib import sha256
+ except ImportError:
+ digest=''
+ else:
-+ digest=' (sha=%r)'%sha1(node.read(flags='rb')).hexdigest()
++ digest=' (sha256=%r)'%sha256(node.read(flags='rb')).hexdigest()
+ Logs.info('New archive created: %s%s',self.arch_name,digest)
+ def get_tar_path(self,node):
+ return node.abspath()
@@ -3252,11 +3481,8 @@ Last-Update: 2017-07-19
+ tinfo.uname='root'
+ tinfo.gname='root'
+ if os.path.isfile(p):
-+ fu=open(p,'rb')
-+ try:
-+ tar.addfile(tinfo,fileobj=fu)
-+ finally:
-+ fu.close()
++ with open(p,'rb')as f:
++ tar.addfile(tinfo,fileobj=f)
+ else:
+ tar.addfile(tinfo)
+ def get_tar_prefix(self):
@@ -3282,7 +3508,7 @@ Last-Update: 2017-07-19
+ try:
+ return self.excl
+ except AttributeError:
-+ 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*'
++ self.excl=Node.exclude_regs+' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
+ if Context.out_dir:
+ nd=self.root.find_node(Context.out_dir)
+ if nd:
@@ -3304,21 +3530,22 @@ Last-Update: 2017-07-19
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+ self.check()
-+ def check(self):
-+ import tempfile,tarfile
-+ try:
-+ t=tarfile.open(self.get_arch_name())
-+ for x in t:
-+ t.extract(x)
-+ finally:
-+ t.close()
++ def make_distcheck_cmd(self,tmpdir):
+ cfg=[]
+ if Options.options.distcheck_args:
+ cfg=shlex.split(Options.options.distcheck_args)
+ else:
+ cfg=[x for x in sys.argv if x.startswith('-')]
++ cmd=[sys.executable,sys.argv[0],'configure','build','install','uninstall','--destdir='+tmpdir]+cfg
++ return cmd
++ def check(self):
++ import tempfile,tarfile
++ with tarfile.open(self.get_arch_name())as t:
++ for x in t:
++ t.extract(x)
+ instdir=tempfile.mkdtemp('.inst',self.get_base_name())
-+ ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait()
++ cmd=self.make_distcheck_cmd(instdir)
++ ret=Utils.subprocess.Popen(cmd,cwd=self.get_base_name()).wait()
+ if ret:
+ raise Errors.WafError('distcheck failed with code %r'%ret)
+ if os.path.exists(instdir):
@@ -3355,7 +3582,8 @@ Last-Update: 2017-07-19
+ cmd=env.config_cmd or'configure'
+ if Configure.autoconfig=='clobber':
+ tmp=Options.options.__dict__
-+ Options.options.__dict__=env.options
++ if env.options:
++ Options.options.__dict__=env.options
+ try:
+ run_command(cmd)
+ finally:
@@ -3369,22 +3597,24 @@ Last-Update: 2017-07-19
+Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
--- /dev/null
+++ b/waflib/Task.py
-@@ -0,0 +1,708 @@
+@@ -0,0 +1,771 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import os,re,sys,tempfile
++import os,re,sys,tempfile,traceback
+from waflib import Utils,Logs,Errors
+NOT_RUN=0
+MISSING=1
+CRASHED=2
+EXCEPTION=3
++CANCELED=4
+SKIPPED=8
+SUCCESS=9
+ASK_LATER=-1
+SKIP_ME=-2
+RUN_ME=-3
++CANCEL_ME=-4
+COMPILE_TEMPLATE_SHELL='''
+def f(tsk):
+ env = tsk.env
@@ -3415,13 +3645,24 @@ Last-Update: 2017-07-19
+ tsk.last_cmd = lst
+ return tsk.exec_command(lst, cwd=cwdx, env=env.env or None)
+'''
++COMPILE_TEMPLATE_SIG_VARS='''
++def f(tsk):
++ super(tsk.__class__, tsk).sig_vars()
++ env = tsk.env
++ gen = tsk.generator
++ bld = gen.bld
++ cwdx = tsk.get_cwd()
++ p = env.get_flat
++ buf = []
++ %s
++ tsk.m.update(repr(buf).encode())
++'''
+classes={}
+class store_task_type(type):
+ def __init__(cls,name,bases,dict):
+ super(store_task_type,cls).__init__(name,bases,dict)
+ name=cls.__name__
-+ if name!='evil'and name!='TaskBase':
-+ global classes
++ if name!='evil'and name!='Task':
+ if getattr(cls,'run_str',None):
+ (f,dvars)=compile_fun(cls.run_str,cls.shell)
+ cls.hcode=Utils.h_cmd(cls.run_str)
@@ -3430,35 +3671,48 @@ Last-Update: 2017-07-19
+ cls.run=f
+ cls.vars=list(set(cls.vars+dvars))
+ cls.vars.sort()
++ if cls.vars:
++ fun=compile_sig_vars(cls.vars)
++ if fun:
++ cls.sig_vars=fun
+ elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
+ cls.hcode=Utils.h_cmd(cls.run)
+ getattr(cls,'register',classes)[name]=cls
+evil=store_task_type('evil',(object,),{})
-+class TaskBase(evil):
++class Task(evil):
++ vars=[]
++ always_run=False
++ shell=False
+ color='GREEN'
+ ext_in=[]
+ ext_out=[]
+ before=[]
+ after=[]
-+ hcode=''
++ hcode=Utils.SIG_NIL
+ keep_last_cmd=False
-+ __slots__=('hasrun','generator')
++ weight=0
++ tree_weight=0
++ prio_order=0
++ __slots__=('hasrun','generator','env','inputs','outputs','dep_nodes','run_after')
+ def __init__(self,*k,**kw):
+ self.hasrun=NOT_RUN
+ try:
+ self.generator=kw['generator']
+ except KeyError:
+ self.generator=self
-+ def __repr__(self):
-+ return'\n\t{task %r: %s %s}'%(self.__class__.__name__,id(self),str(getattr(self,'fun','')))
-+ def __str__(self):
-+ if hasattr(self,'fun'):
-+ return self.fun.__name__
-+ return self.__class__.__name__
-+ def keyword(self):
-+ if hasattr(self,'fun'):
-+ return'Function'
-+ return'Processing'
++ self.env=kw['env']
++ self.inputs=[]
++ self.outputs=[]
++ self.dep_nodes=[]
++ self.run_after=set()
++ def __lt__(self,other):
++ return self.priority()>other.priority()
++ def __le__(self,other):
++ return self.priority()>=other.priority()
++ def __gt__(self,other):
++ return self.priority()<other.priority()
++ def __ge__(self,other):
++ return self.priority()<=other.priority()
+ def get_cwd(self):
+ bld=self.generator.bld
+ ret=getattr(self,'cwd',None)or getattr(bld,'cwd',bld.bldnode)
@@ -3477,6 +3731,8 @@ Last-Update: 2017-07-19
+ if old!=x or' 'in x or'\t'in x or"'"in x:
+ x='"%s"'%x
+ return x
++ def priority(self):
++ return(self.weight+self.prio_order,-getattr(self.generator,'tg_idx_count',0))
+ def split_argfile(self,cmd):
+ return([cmd[0]],[self.quote_flag(x)for x in cmd[1:]])
+ def exec_command(self,cmd,**kw):
@@ -3487,6 +3743,10 @@ Last-Update: 2017-07-19
+ if self.env.PATH:
+ env=kw['env']=dict(kw.get('env')or self.env.env or os.environ)
+ env['PATH']=self.env.PATH if isinstance(self.env.PATH,str)else os.pathsep.join(self.env.PATH)
++ if hasattr(self,'stdout'):
++ kw['stdout']=self.stdout
++ if hasattr(self,'stderr'):
++ kw['stderr']=self.stderr
+ if not isinstance(cmd,str)and(len(repr(cmd))>=8192 if Utils.is_win32 else len(cmd)>200000):
+ cmd,args=self.split_argfile(cmd)
+ try:
@@ -3503,12 +3763,7 @@ Last-Update: 2017-07-19
+ pass
+ else:
+ return self.generator.bld.exec_command(cmd,**kw)
-+ def runnable_status(self):
-+ return RUN_ME
-+ def uid(self):
-+ return Utils.SIG_NIL
+ def process(self):
-+ m=self.generator.bld.producer
+ try:
+ del self.generator.bld.task_sigs[self.uid()]
+ except KeyError:
@@ -3516,31 +3771,27 @@ Last-Update: 2017-07-19
+ try:
+ ret=self.run()
+ except Exception:
-+ self.err_msg=Utils.ex_stack()
++ self.err_msg=traceback.format_exc()
+ self.hasrun=EXCEPTION
-+ m.error_handler(self)
-+ return
-+ if ret:
-+ self.err_code=ret
-+ self.hasrun=CRASHED
+ else:
++ if ret:
++ self.err_code=ret
++ self.hasrun=CRASHED
++ else:
++ try:
++ self.post_run()
++ except Errors.WafError:
++ pass
++ except Exception:
++ self.err_msg=traceback.format_exc()
++ self.hasrun=EXCEPTION
++ else:
++ self.hasrun=SUCCESS
++ if self.hasrun!=SUCCESS and self.scan:
+ try:
-+ self.post_run()
-+ except Errors.WafError:
++ del self.generator.bld.imp_sigs[self.uid()]
++ except KeyError:
+ pass
-+ except Exception:
-+ self.err_msg=Utils.ex_stack()
-+ self.hasrun=EXCEPTION
-+ else:
-+ self.hasrun=SUCCESS
-+ if self.hasrun!=SUCCESS:
-+ m.error_handler(self)
-+ def run(self):
-+ if hasattr(self,'fun'):
-+ return self.fun(self)
-+ return 0
-+ def post_run(self):
-+ pass
+ def log_display(self,bld):
+ if self.generator.bld.progress_bar==3:
+ return
@@ -3561,10 +3812,7 @@ Last-Update: 2017-07-19
+ col2=Logs.colors.NORMAL
+ master=self.generator.bld.producer
+ def cur():
-+ tmp=-1
-+ if hasattr(master,'ready'):
-+ tmp-=master.ready.qsize()
-+ return master.processed+tmp
++ return master.processed-master.ready.qsize()
+ if self.generator.bld.progress_bar==1:
+ return self.generator.bld.progress_line(cur(),master.total,col1,col2)
+ if self.generator.bld.progress_bar==2:
@@ -3589,9 +3837,7 @@ Last-Update: 2017-07-19
+ kw+=' '
+ return fs%(cur(),total,kw,col1,s,col2)
+ def hash_constraints(self):
-+ cls=self.__class__
-+ tup=(str(cls.before),str(cls.after),str(cls.ext_in),str(cls.ext_out),cls.__name__,cls.hcode)
-+ return hash(tup)
++ return(tuple(self.before),tuple(self.after),tuple(self.ext_in),tuple(self.ext_out),self.__class__.__name__,self.hcode)
+ def format_error(self):
+ if Logs.verbose:
+ msg=': %r\n%r'%(self,getattr(self,'last_cmd',''))
@@ -3609,6 +3855,8 @@ Last-Update: 2017-07-19
+ return' -> task in %r failed%s'%(name,msg)
+ elif self.hasrun==MISSING:
+ return' -> missing files in %r%s'%(name,msg)
++ elif self.hasrun==CANCELED:
++ return' -> %r canceled because of missing dependencies'%name
+ else:
+ return'invalid status for task in %r: %r'%(name,self.hasrun)
+ def colon(self,var1,var2):
@@ -3627,17 +3875,6 @@ Last-Update: 2017-07-19
+ lst.extend(tmp)
+ lst.append(y)
+ return lst
-+class Task(TaskBase):
-+ vars=[]
-+ always_run=False
-+ shell=False
-+ def __init__(self,*k,**kw):
-+ TaskBase.__init__(self,*k,**kw)
-+ self.env=kw['env']
-+ self.inputs=[]
-+ self.outputs=[]
-+ self.dep_nodes=[]
-+ self.run_after=set()
+ def __str__(self):
+ name=self.__class__.__name__
+ if self.outputs:
@@ -3651,8 +3888,10 @@ Last-Update: 2017-07-19
+ 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=''
++ if self.outputs:
++ sep=' -> '
++ else:
++ sep=''
+ return'%s: %s%s%s'%(self.__class__.__name__,src_str,sep,tgt_str)
+ def keyword(self):
+ name=self.__class__.__name__
@@ -3685,13 +3924,17 @@ Last-Update: 2017-07-19
+ self.uid_=m.digest()
+ return self.uid_
+ def set_inputs(self,inp):
-+ if isinstance(inp,list):self.inputs+=inp
-+ else:self.inputs.append(inp)
++ if isinstance(inp,list):
++ self.inputs+=inp
++ else:
++ self.inputs.append(inp)
+ def set_outputs(self,out):
-+ if isinstance(out,list):self.outputs+=out
-+ else:self.outputs.append(out)
++ if isinstance(out,list):
++ self.outputs+=out
++ else:
++ self.outputs.append(out)
+ def set_run_after(self,task):
-+ assert isinstance(task,TaskBase)
++ assert isinstance(task,Task)
+ self.run_after.add(task)
+ def signature(self):
+ try:
@@ -3709,14 +3952,18 @@ Last-Update: 2017-07-19
+ ret=self.cache_sig=self.m.digest()
+ return ret
+ def runnable_status(self):
++ bld=self.generator.bld
++ if bld.is_install<0:
++ return SKIP_ME
+ for t in self.run_after:
+ if not t.hasrun:
+ return ASK_LATER
++ elif t.hasrun<SKIPPED:
++ return CANCEL_ME
+ try:
+ new_sig=self.signature()
+ except Errors.TaskNotReady:
+ return ASK_LATER
-+ bld=self.generator.bld
+ key=self.uid()
+ try:
+ prev_sig=bld.task_sigs[key]
@@ -3765,11 +4012,16 @@ Last-Update: 2017-07-19
+ except KeyError:
+ continue
+ for v in d:
-+ if isinstance(v,bld.root.__class__):
++ try:
+ v=v.get_bld_sig()
-+ elif hasattr(v,'__call__'):
-+ v=v()
++ except AttributeError:
++ if hasattr(v,'__call__'):
++ v=v()
+ upd(v)
++ def sig_deep_inputs(self):
++ bld=self.generator.bld
++ lst=[bld.task_sigs[bld.node_sigs[node]]for node in(self.inputs+self.dep_nodes)if node.is_bld()]
++ self.m.update(Utils.h_list(lst))
+ def sig_vars(self):
+ sig=self.generator.bld.hash_env_vars(self.env,self.vars)
+ self.m.update(sig)
@@ -3816,9 +4068,9 @@ Last-Update: 2017-07-19
+ except AttributeError:
+ bld.dct_implicit_nodes=cache={}
+ try:
-+ dct=cache[bld.cur]
++ dct=cache[bld.current_group]
+ except KeyError:
-+ dct=cache[bld.cur]={}
++ dct=cache[bld.current_group]={}
+ for tsk in bld.cur_tasks:
+ for x in tsk.outputs:
+ dct[x]=tsk
@@ -3836,10 +4088,10 @@ Last-Update: 2017-07-19
+ try:
+ return self.uid_
+ except AttributeError:
-+ m=Utils.md5(self.__class__.__name__.encode('iso8859-1','xmlcharrefreplace'))
++ m=Utils.md5(self.__class__.__name__.encode('latin-1','xmlcharrefreplace'))
+ up=m.update
+ for x in self.inputs+self.outputs:
-+ up(x.abspath().encode('iso8859-1','xmlcharrefreplace'))
++ up(x.abspath().encode('latin-1','xmlcharrefreplace'))
+ self.uid_=m.digest()
+ return self.uid_
+ uid.__doc__=Task.uid.__doc__
@@ -3858,14 +4110,27 @@ Last-Update: 2017-07-19
+ ins=Utils.defaultdict(set)
+ outs=Utils.defaultdict(set)
+ for x in tasks:
-+ for a in getattr(x,'inputs',[])+getattr(x,'dep_nodes',[]):
-+ ins[id(a)].add(x)
-+ for a in getattr(x,'outputs',[]):
-+ outs[id(a)].add(x)
++ for a in x.inputs:
++ ins[a].add(x)
++ for a in x.dep_nodes:
++ ins[a].add(x)
++ for a in x.outputs:
++ outs[a].add(x)
+ links=set(ins.keys()).intersection(outs.keys())
+ for k in links:
+ for a in ins[k]:
+ a.run_after.update(outs[k])
++class TaskGroup(object):
++ def __init__(self,prev,next):
++ self.prev=prev
++ self.next=next
++ self.done=False
++ def get_hasrun(self):
++ for k in self.prev:
++ if not k.hasrun:
++ return NOT_RUN
++ return SUCCESS
++ hasrun=property(get_hasrun,None)
+def set_precedence_constraints(tasks):
+ cstr_groups=Utils.defaultdict(list)
+ for x in tasks:
@@ -3885,9 +4150,15 @@ Last-Update: 2017-07-19
+ b=i
+ else:
+ continue
-+ aval=set(cstr_groups[keys[a]])
-+ for x in cstr_groups[keys[b]]:
-+ x.run_after.update(aval)
++ a=cstr_groups[keys[a]]
++ b=cstr_groups[keys[b]]
++ if len(a)<2 or len(b)<2:
++ for x in b:
++ x.run_after.update(a)
++ else:
++ group=TaskGroup(set(a),set(b))
++ for x in b:
++ x.run_after.add(group)
+def funex(c):
+ dc={}
+ exec(c,dc)
@@ -3909,6 +4180,9 @@ Last-Update: 2017-07-19
+ return None
+ line=reg_act.sub(repl,line)or line
+ dvars=[]
++ def add_dvar(x):
++ if x not in dvars:
++ dvars.append(x)
+ def replc(m):
+ if m.group('and'):
+ return' and '
@@ -3916,22 +4190,24 @@ Last-Update: 2017-07-19
+ return' or '
+ else:
+ x=m.group('var')
-+ if x not in dvars:
-+ dvars.append(x)
++ add_dvar(x)
+ return'env[%r]'%x
+ parm=[]
+ app=parm.append
+ for(var,meth)in extr:
+ if var=='SRC':
-+ if meth:app('tsk.inputs%s'%meth)
-+ else:app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
++ if meth:
++ app('tsk.inputs%s'%meth)
++ else:
++ app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
+ elif var=='TGT':
-+ if meth:app('tsk.outputs%s'%meth)
-+ else:app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
++ if meth:
++ app('tsk.outputs%s'%meth)
++ else:
++ app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
+ elif meth:
+ if meth.startswith(':'):
-+ if var not in dvars:
-+ dvars.append(var)
++ add_dvar(var)
+ m=meth[1:]
+ if m=='SRC':
+ m='[a.path_from(cwdx) for a in tsk.inputs]'
@@ -3941,21 +4217,25 @@ Last-Update: 2017-07-19
+ m='[tsk.inputs%s]'%m[3:]
+ elif re_novar.match(m):
+ m='[tsk.outputs%s]'%m[3:]
-+ elif m[:3]not in('tsk','gen','bld'):
-+ dvars.append(meth[1:])
-+ m='%r'%m
++ else:
++ add_dvar(m)
++ if m[:3]not in('tsk','gen','bld'):
++ m='%r'%m
+ app('" ".join(tsk.colon(%r, %s))'%(var,m))
+ elif meth.startswith('?'):
+ expr=re_cond.sub(replc,meth[1:])
+ app('p(%r) if (%s) else ""'%(var,expr))
+ else:
-+ app('%s%s'%(var,meth))
++ call='%s%s'%(var,meth)
++ add_dvar(call)
++ app(call)
+ else:
-+ if var not in dvars:
-+ dvars.append(var)
++ add_dvar(var)
+ app("p('%s')"%var)
-+ if parm:parm="%% (%s) "%(',\n\t\t'.join(parm))
-+ else:parm=''
++ if parm:
++ parm="%% (%s) "%(',\n\t\t'.join(parm))
++ else:
++ parm=''
+ c=COMPILE_TEMPLATE_SHELL%(line,parm)
+ Logs.debug('action: %s',c.strip().splitlines())
+ return(funex(c),dvars)
@@ -3965,6 +4245,9 @@ Last-Update: 2017-07-19
+ dvars=[]
+ merge=False
+ app=buf.append
++ def add_dvar(x):
++ if x not in dvars:
++ dvars.append(x)
+ def replc(m):
+ if m.group('and'):
+ return' and '
@@ -3972,8 +4255,7 @@ Last-Update: 2017-07-19
+ return' or '
+ else:
+ x=m.group('var')
-+ if x not in dvars:
-+ dvars.append(x)
++ add_dvar(x)
+ return'env[%r]'%x
+ for m in reg_act_noshell.finditer(line):
+ if m.group('space'):
@@ -3996,8 +4278,7 @@ Last-Update: 2017-07-19
+ app('[a.path_from(cwdx) for a in tsk.outputs]')
+ elif code:
+ if code.startswith(':'):
-+ if not var in dvars:
-+ dvars.append(var)
++ add_dvar(var)
+ m=code[1:]
+ if m=='SRC':
+ m='[a.path_from(cwdx) for a in tsk.inputs]'
@@ -4007,19 +4288,21 @@ Last-Update: 2017-07-19
+ m='[tsk.inputs%s]'%m[3:]
+ elif re_novar.match(m):
+ m='[tsk.outputs%s]'%m[3:]
-+ elif m[:3]not in('tsk','gen','bld'):
-+ dvars.append(m)
-+ m='%r'%m
++ else:
++ add_dvar(m)
++ if m[:3]not in('tsk','gen','bld'):
++ m='%r'%m
+ app('tsk.colon(%r, %s)'%(var,m))
+ elif code.startswith('?'):
+ expr=re_cond.sub(replc,code[1:])
+ app('to_list(env[%r] if (%s) else [])'%(var,expr))
+ else:
-+ app('gen.to_list(%s%s)'%(var,code))
++ call='%s%s'%(var,code)
++ add_dvar(call)
++ app('gen.to_list(%s)'%call)
+ else:
+ app('to_list(env[%r])'%var)
-+ if not var in dvars:
-+ dvars.append(var)
++ add_dvar(var)
+ if merge:
+ tmp='merge(%s, %s)'%(buf[-2],buf[-1])
+ del buf[-1]
@@ -4054,6 +4337,14 @@ Last-Update: 2017-07-19
+ return compile_fun_shell(line)
+ else:
+ return compile_fun_noshell(line)
++def compile_sig_vars(vars):
++ buf=[]
++ for x in sorted(vars):
++ if x[:3]in('tsk','gen','bld'):
++ buf.append('buf.append(%s)'%x)
++ if buf:
++ return funex(COMPILE_TEMPLATE_SIG_VARS%'\n\t'.join(buf))
++ return None
+def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
+ params={'vars':vars or[],'color':color,'name':name,'shell':shell,'scan':scan,}
+ if isinstance(func,str)or isinstance(func,tuple):
@@ -4061,7 +4352,6 @@ Last-Update: 2017-07-19
+ else:
+ params['run']=func
+ cls=type(Task)(name,(Task,),params)
-+ global classes
+ classes[name]=cls
+ if ext_in:
+ cls.ext_in=Utils.to_list(ext_in)
@@ -4072,15 +4362,16 @@ Last-Update: 2017-07-19
+ if after:
+ cls.after=Utils.to_list(after)
+ return cls
-+def always_run(cls):
-+ Logs.warn('This decorator is deprecated, set always_run on the task class instead!')
-+ cls.always_run=True
-+ return cls
-+def update_outputs(cls):
++def deep_inputs(cls):
++ def sig_explicit_deps(self):
++ Task.sig_explicit_deps(self)
++ Task.sig_deep_inputs(self)
++ cls.sig_explicit_deps=sig_explicit_deps
+ return cls
++TaskBase=Task
--- /dev/null
+++ b/waflib/TaskGen.py
-@@ -0,0 +1,458 @@
+@@ -0,0 +1,471 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -4091,9 +4382,9 @@ Last-Update: 2017-07-19
+HEADER_EXTS=['.h','.hpp','.hxx','.hh']
+class task_gen(object):
+ mappings=Utils.ordered_iter_dict()
-+ prec=Utils.defaultdict(list)
++ prec=Utils.defaultdict(set)
+ def __init__(self,*k,**kw):
-+ self.source=''
++ self.source=[]
+ self.target=''
+ self.meths=[]
+ self.features=[]
@@ -4106,11 +4397,16 @@ Last-Update: 2017-07-19
+ self.bld=kw['bld']
+ self.env=self.bld.env.derive()
+ self.path=self.bld.path
++ path=self.path.abspath()
+ try:
-+ self.idx=self.bld.idx[self.path]=self.bld.idx.get(self.path,0)+1
++ self.idx=self.bld.idx[path]=self.bld.idx.get(path,0)+1
+ except AttributeError:
+ self.bld.idx={}
-+ self.idx=self.bld.idx[self.path]=1
++ self.idx=self.bld.idx[path]=1
++ try:
++ self.tg_idx_count=self.bld.tg_idx_count=self.bld.tg_idx_count+1
++ except AttributeError:
++ self.tg_idx_count=self.bld.tg_idx_count=1
+ for key,val in kw.items():
+ setattr(self,key,val)
+ def __str__(self):
@@ -4162,10 +4458,11 @@ Last-Update: 2017-07-19
+ tmp=[]
+ for a in keys:
+ for x in prec.values():
-+ if a in x:break
++ if a in x:
++ break
+ else:
+ tmp.append(a)
-+ tmp.sort()
++ tmp.sort(reverse=True)
+ out=[]
+ while tmp:
+ e=tmp.pop()
@@ -4183,12 +4480,12 @@ Last-Update: 2017-07-19
+ break
+ else:
+ tmp.append(x)
++ tmp.sort(reverse=True)
+ if prec:
+ buf=['Cycle detected in the method execution:']
+ for k,v in prec.items():
+ buf.append('- %s after %s'%(k,[x for x in v if x in prec]))
+ raise Errors.WafError('\n'.join(buf))
-+ out.reverse()
+ self.meths=out
+ Logs.debug('task_gen: posting %s %d',self,id(self))
+ for x in out:
@@ -4279,8 +4576,7 @@ Last-Update: 2017-07-19
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
-+ if not func.__name__ in task_gen.prec[fun_name]:
-+ task_gen.prec[fun_name].append(func.__name__)
++ task_gen.prec[func.__name__].add(fun_name)
+ return func
+ return deco
+before=before_method
@@ -4288,8 +4584,7 @@ Last-Update: 2017-07-19
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
-+ if not fun_name in task_gen.prec[func.__name__]:
-+ task_gen.prec[func.__name__].append(fun_name)
++ task_gen.prec[fun_name].add(func.__name__)
+ return func
+ return deco
+after=after_method
@@ -4310,10 +4605,13 @@ Last-Update: 2017-07-19
+ for x in Utils.to_list(lst):
+ if isinstance(x,str):
+ node=find(x)
-+ else:
++ elif hasattr(x,'name'):
+ node=x
++ else:
++ tmp.extend(self.to_nodes(x))
++ continue
+ if not node:
-+ raise Errors.WafError("source not found: %r in %r"%(x,self))
++ raise Errors.WafError('source not found: %r in %r'%(x,self))
+ tmp.append(node)
+ return tmp
+@feature('*')
@@ -4339,10 +4637,11 @@ Last-Update: 2017-07-19
+ cls_str=getattr(self,'cls_str',None)
+ cls_keyword=getattr(self,'cls_keyword',None)
+ use_cache=getattr(self,'cache_rule','True')
++ deep_inputs=getattr(self,'deep_inputs',False)
+ scan_val=has_deps=hasattr(self,'deps')
+ if scan:
+ scan_val=id(scan)
-+ key=Utils.h_list((name,self.rule,chmod,shell,color,cls_str,cls_keyword,scan_val,_vars))
++ key=Utils.h_list((name,self.rule,chmod,shell,color,cls_str,cls_keyword,scan_val,_vars,deep_inputs))
+ cls=None
+ if use_cache:
+ try:
@@ -4366,6 +4665,8 @@ Last-Update: 2017-07-19
+ setattr(cls,'__str__',self.cls_str)
+ if cls_keyword:
+ setattr(cls,'keyword',self.cls_keyword)
++ if deep_inputs:
++ Task.deep_inputs(cls)
+ if scan:
+ cls.scan=self.scan
+ elif has_deps:
@@ -4378,11 +4679,15 @@ Last-Update: 2017-07-19
+ nodes.append(node)
+ return[nodes,[]]
+ cls.scan=scan
-+ for x in('after','before','ext_in','ext_out'):
-+ setattr(cls,x,getattr(self,x,[]))
+ if use_cache:
+ cache[key]=cls
+ tsk=self.create_task(name)
++ for x in('after','before','ext_in','ext_out'):
++ setattr(tsk,x,getattr(self,x,[]))
++ if hasattr(self,'stdout'):
++ tsk.stdout=self.stdout
++ if hasattr(self,'stderr'):
++ tsk.stderr=self.stderr
+ if getattr(self,'timeout',None):
+ tsk.timeout=self.timeout
+ if getattr(self,'always',None):
@@ -4430,6 +4735,8 @@ Last-Update: 2017-07-19
+ if getattr(self.generator,'is_copy',None):
+ for i,x in enumerate(self.outputs):
+ x.write(self.inputs[i].read('rb'),'wb')
++ stat=os.stat(self.inputs[i].abspath())
++ os.utime(self.outputs[i].abspath(),(stat.st_atime,stat.st_mtime))
+ self.force_permissions()
+ return None
+ if getattr(self.generator,'fun',None):
@@ -4437,11 +4744,11 @@ Last-Update: 2017-07-19
+ if not ret:
+ self.force_permissions()
+ return ret
-+ code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','ISO8859-1'))
++ code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','latin-1'))
+ if getattr(self.generator,'subst_fun',None):
+ code=self.generator.subst_fun(self,code)
+ if code is not None:
-+ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
++ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','latin-1'))
+ self.force_permissions()
+ return None
+ code=code.replace('%','%%')
@@ -4452,7 +4759,6 @@ Last-Update: 2017-07-19
+ lst.append(g(1))
+ return"%%(%s)s"%g(1)
+ return''
-+ global re_m4
+ code=getattr(self.generator,'re_m4',re_m4).sub(repl,code)
+ try:
+ d=self.generator.dct
@@ -4466,10 +4772,12 @@ Last-Update: 2017-07-19
+ tmp=str(tmp)
+ d[x]=tmp
+ code=code%d
-+ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
++ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','latin-1'))
+ self.generator.bld.raw_deps[self.uid()]=lst
-+ try:delattr(self,'cache_sig')
-+ except AttributeError:pass
++ try:
++ delattr(self,'cache_sig')
++ except AttributeError:
++ pass
+ self.force_permissions()
+ def sig_vars(self):
+ bld=self.generator.bld
@@ -4522,19 +4830,15 @@ Last-Update: 2017-07-19
+ b=y
+ if not a:
+ raise Errors.WafError('could not find %r for %r'%(x,self))
-+ has_constraints=False
+ tsk=self.create_task('subst',a,b)
+ for k in('after','before','ext_in','ext_out'):
+ val=getattr(self,k,None)
+ if val:
-+ has_constraints=True
+ setattr(tsk,k,val)
-+ 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
++ for xt in HEADER_EXTS:
++ if b.name.endswith(xt):
++ tsk.ext_in=tsk.ext_in+['.h']
++ break
+ inst_to=getattr(self,'install_path',None)
+ if inst_to:
+ self.install_task=self.add_install_files(install_to=inst_to,install_from=b,chmod=getattr(self,'chmod',Utils.O644))
@@ -4713,7 +5017,7 @@ Last-Update: 2017-07-19
+ return bld(*k,**kw)
--- /dev/null
+++ b/waflib/Tools/c_config.py
-@@ -0,0 +1,851 @@
+@@ -0,0 +1,805 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -4726,37 +5030,12 @@ Last-Update: 2017-07-19
+WAF_CONFIG_H='config.h'
+DEFKEYS='define_key'
+INCKEYS='include_key'
-+cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
-+SNIP_FUNCTION='''
-+int main(int argc, char **argv) {
-+ void (*p)();
-+ (void)argc; (void)argv;
-+ p=(void(*)())(%s);
-+ return !p;
-+}
-+'''
-+SNIP_TYPE='''
-+int main(int argc, char **argv) {
-+ (void)argc; (void)argv;
-+ if ((%(type_name)s *) 0) return 0;
-+ if (sizeof (%(type_name)s)) return 0;
-+ return 1;
-+}
-+'''
+SNIP_EMPTY_PROGRAM='''
+int main(int argc, char **argv) {
+ (void)argc; (void)argv;
+ return 0;
+}
+'''
-+SNIP_FIELD='''
-+int main(int argc, char **argv) {
-+ char *off;
-+ (void)argc; (void)argv;
-+ off = (char*) &((%(type_name)s*)0)->%(field_name)s;
-+ return (size_t) off < sizeof(%(type_name)s);
-+}
-+'''
+MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'cygwin','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
+MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh','__xtensa__':'xtensa',}
+@conf
@@ -4809,7 +5088,7 @@ Last-Update: 2017-07-19
+ elif x.startswith('-std='):
+ prefix='CXXFLAGS'if'++'in x else'CFLAGS'
+ app(prefix,x)
-+ elif x=='-pthread'or x.startswith('+'):
++ elif x.startswith('+')or x in('-pthread','-fPIC','-fpic','-fPIE','-fpie'):
+ app('CFLAGS',x)
+ app('CXXFLAGS',x)
+ app('LINKFLAGS',x)
@@ -4829,9 +5108,9 @@ Last-Update: 2017-07-19
+ static=True
+ elif x=='-Wl,-Bdynamic'or x=='-Bdynamic':
+ static=False
-+ elif x.startswith('-Wl'):
++ elif x.startswith('-Wl')or x in('-rdynamic','-pie'):
+ app('LINKFLAGS',x)
-+ elif x.startswith(('-m','-f','-dynamic','-O')):
++ elif x.startswith(('-m','-f','-dynamic','-O','-g')):
+ app('CFLAGS',x)
+ app('CXXFLAGS',x)
+ elif x.startswith('-bundle'):
@@ -4846,46 +5125,40 @@ Last-Update: 2017-07-19
+ app('LINKFLAGS',tmp)
+ elif x.endswith(('.a','.so','.dylib','.lib')):
+ appu('LINKFLAGS',x)
++ else:
++ self.to_log('Unhandled flag %r'%x)
+@conf
+def validate_cfg(self,kw):
+ if not'path'in kw:
+ if not self.env.PKGCONFIG:
+ self.find_program('pkg-config',var='PKGCONFIG')
+ kw['path']=self.env.PKGCONFIG
-+ if'atleast_pkgconfig_version'in kw:
-+ if not'msg'in kw:
++ s=('atleast_pkgconfig_version'in kw)+('modversion'in kw)+('package'in kw)
++ if s!=1:
++ raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set')
++ if not'msg'in kw:
++ if'atleast_pkgconfig_version'in kw:
+ kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
-+ return
-+ if not'okmsg'in kw:
++ elif'modversion'in kw:
++ kw['msg']='Checking for %r version'%kw['modversion']
++ else:
++ kw['msg']='Checking for %r'%(kw['package'])
++ if not'okmsg'in kw and not'modversion'in kw:
+ kw['okmsg']='yes'
+ if not'errmsg'in kw:
+ kw['errmsg']='not found'
-+ if'modversion'in kw:
-+ if not'msg'in kw:
-+ kw['msg']='Checking for %r version'%kw['modversion']
++ if'atleast_pkgconfig_version'in kw:
++ pass
++ elif'modversion'in kw:
+ if not'uselib_store'in kw:
+ kw['uselib_store']=kw['modversion']
+ if not'define_name'in kw:
+ kw['define_name']='%s_VERSION'%Utils.quote_define_name(kw['uselib_store'])
-+ return
-+ if not'package'in kw:
-+ raise ValueError('a package name is required')
-+ if not'uselib_store'in kw:
-+ kw['uselib_store']=kw['package'].upper()
-+ if not'define_name'in kw:
-+ kw['define_name']=self.have_define(kw['uselib_store'])
-+ if not'msg'in kw:
-+ kw['msg']='Checking for %r'%(kw['package']or kw['path'])
-+ for x in cfg_ver:
-+ y=x.replace('-','_')
-+ if y in kw:
-+ package=kw['package']
-+ if Logs.verbose:
-+ Logs.warn('Passing %r to conf.check_cfg() is obsolete, pass parameters directly, eg:',y)
-+ Logs.warn(" conf.check_cfg(package='%s', args=['--libs', '--cflags', '%s >= 1.6'])",package,package)
-+ if not'msg'in kw:
-+ kw['msg']='Checking for %r %s %s'%(package,cfg_ver[x],kw[y])
-+ break
++ else:
++ if not'uselib_store'in kw:
++ kw['uselib_store']=Utils.to_list(kw['package'])[0].upper()
++ if not'define_name'in kw:
++ kw['define_name']=self.have_define(kw['uselib_store'])
+@conf
+def exec_cfg(self,kw):
+ path=Utils.to_list(kw['path'])
@@ -4905,19 +5178,11 @@ Last-Update: 2017-07-19
+ if'atleast_pkgconfig_version'in kw:
+ cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+ self.cmd_and_log(cmd,env=env)
-+ if not'okmsg'in kw:
-+ kw['okmsg']='yes'
+ return
-+ for x in cfg_ver:
-+ y=x.replace('-','_')
-+ if y in kw:
-+ self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']],env=env)
-+ if not'okmsg'in kw:
-+ kw['okmsg']='yes'
-+ define_it()
-+ break
+ if'modversion'in kw:
+ version=self.cmd_and_log(path+['--modversion',kw['modversion']],env=env).strip()
++ if not'okmsg'in kw:
++ kw['okmsg']=version
+ self.define(kw['define_name'],version)
+ return version
+ lst=[]+path
@@ -4940,21 +5205,13 @@ Last-Update: 2017-07-19
+ val=self.cmd_and_log(lst+['--variable='+v],env=env).strip()
+ var='%s_%s'%(kw['uselib_store'],v)
+ v_env[var]=val
-+ if not'okmsg'in kw:
-+ kw['okmsg']='yes'
+ return
+ ret=self.cmd_and_log(lst,env=env)
-+ if not'okmsg'in kw:
-+ kw['okmsg']='yes'
+ define_it()
+ self.parse_flags(ret,kw['uselib_store'],kw.get('env',self.env),force_static=static,posix=kw.get('posix'))
+ return ret
+@conf
+def check_cfg(self,*k,**kw):
-+ if k:
-+ lst=k[0].split()
-+ kw['package']=lst[0]
-+ kw['args']=' '.join(lst[1:])
+ self.validate_cfg(kw)
+ if'msg'in kw:
+ self.start_msg(kw['msg'],**kw)
@@ -4986,6 +5243,9 @@ Last-Update: 2017-07-19
+ bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
+@conf
+def validate_c(self,kw):
++ for x in('type_name','field_name','function_name'):
++ if x in kw:
++ Logs.warn('Invalid argument %r in test'%x)
+ if not'build_fun'in kw:
+ kw['build_fun']=build_fun
+ if not'env'in kw:
@@ -5002,7 +5262,7 @@ Last-Update: 2017-07-19
+ self.fatal('a c compiler is required')
+ if not'compile_mode'in kw:
+ kw['compile_mode']='c'
-+ if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
++ if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler')=='cxx':
+ kw['compile_mode']='cxx'
+ if not'type'in kw:
+ kw['type']='cprogram'
@@ -5024,41 +5284,14 @@ Last-Update: 2017-07-19
+ fwkname=kw['framework_name']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=fwkname.upper()
-+ if not kw.get('no_header',False):
-+ if not'header_name'in kw:
-+ kw['header_name']=[]
++ if not kw.get('no_header'):
+ fwk='%s/%s.h'%(fwkname,fwkname)
+ if kw.get('remove_dot_h'):
+ fwk=fwk[:-2]
-+ kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
++ val=kw.get('header_name',[])
++ kw['header_name']=Utils.to_list(val)+[fwk]
+ kw['msg']='Checking for framework %s'%fwkname
+ kw['framework']=fwkname
-+ if'function_name'in kw:
-+ fu=kw['function_name']
-+ if not'msg'in kw:
-+ kw['msg']='Checking for function %s'%fu
-+ kw['code']=to_header(kw)+SNIP_FUNCTION%fu
-+ if not'uselib_store'in kw:
-+ kw['uselib_store']=fu.upper()
-+ if not'define_name'in kw:
-+ kw['define_name']=self.have_define(fu)
-+ elif'type_name'in kw:
-+ tu=kw['type_name']
-+ if not'header_name'in kw:
-+ kw['header_name']='stdint.h'
-+ if'field_name'in kw:
-+ field=kw['field_name']
-+ kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
-+ if not'msg'in kw:
-+ kw['msg']='Checking for field %s in %s'%(field,tu)
-+ if not'define_name'in kw:
-+ kw['define_name']=self.have_define((tu+'_'+field).upper())
-+ else:
-+ kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
-+ if not'msg'in kw:
-+ kw['msg']='Checking for type %s'%tu
-+ if not'define_name'in kw:
-+ kw['define_name']=self.have_define(tu.upper())
+ elif'header_name'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for header %s'%kw['header_name']
@@ -5104,10 +5337,11 @@ Last-Update: 2017-07-19
+ kw['code']=SNIP_EMPTY_PROGRAM
+ if self.env[INCKEYS]:
+ kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
-+ if kw.get('merge_config_header',False)or env.merge_config_header:
++ if kw.get('merge_config_header')or env.merge_config_header:
+ kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code'])
+ env.DEFINES=[]
-+ if not kw.get('success'):kw['success']=None
++ if not kw.get('success'):
++ kw['success']=None
+ if'define_name'in kw:
+ self.undefine(kw['define_name'])
+ if not'msg'in kw:
@@ -5117,7 +5351,7 @@ Last-Update: 2017-07-19
+ is_success=0
+ if kw['execute']:
+ if kw['success']is not None:
-+ if kw.get('define_ret',False):
++ if kw.get('define_ret'):
+ is_success=kw['success']
+ else:
+ is_success=(kw['success']==0)
@@ -5146,10 +5380,12 @@ Last-Update: 2017-07-19
+ if kw.get('add_have_to_env',1):
+ if kw.get('uselib_store'):
+ self.env[self.have_define(kw['uselib_store'])]=1
++ elif kw['execute']and kw.get('define_ret'):
++ self.env[define_name]=is_success
+ else:
+ self.env[define_name]=int(is_success)
+ if'header_name'in kw:
-+ if kw.get('auto_add_header_name',False):
++ if kw.get('auto_add_header_name'):
+ self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
+ if is_success and'uselib_store'in kw:
+ from waflib.Tools import ccroot
@@ -5287,7 +5523,8 @@ Last-Update: 2017-07-19
+ return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
+@conf
+def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''):
-+ if not configfile:configfile=WAF_CONFIG_H
++ 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()
+ node=node.make_node(configfile)
@@ -5353,7 +5590,7 @@ Last-Update: 2017-07-19
+ env=conf.env.env or None
+ try:
+ out,err=conf.cmd_and_log(cmd,output=0,input='\n'.encode(),env=env)
-+ except Exception:
++ except Errors.WafError:
+ conf.fatal('Could not determine the compiler version %r'%cmd)
+ if gcc:
+ if out.find('__INTEL_COMPILER')>=0:
@@ -5392,6 +5629,8 @@ Last-Update: 2017-07-19
+ conf.env.DEST_BINFMT='elf'
+ elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
+ conf.env.DEST_BINFMT='pe'
++ if not conf.env.IMPLIBDIR:
++ conf.env.IMPLIBDIR=conf.env.LIBDIR
+ conf.env.LIBDIR=conf.env.BINDIR
+ elif isD('__APPLE__'):
+ conf.env.DEST_BINFMT='mac-o'
@@ -5450,9 +5689,9 @@ Last-Update: 2017-07-19
+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','-Wl,--as-needed')
-+class cfgtask(Task.TaskBase):
++class cfgtask(Task.Task):
+ def __init__(self,*k,**kw):
-+ Task.TaskBase.__init__(self,*k,**kw)
++ Task.Task.__init__(self,*k,**kw)
+ self.run_after=set()
+ def display(self):
+ return''
@@ -5463,6 +5702,8 @@ Last-Update: 2017-07-19
+ return Task.RUN_ME
+ def uid(self):
+ return Utils.SIG_NIL
++ def signature(self):
++ return Utils.SIG_NIL
+ def run(self):
+ conf=self.conf
+ bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
@@ -5485,7 +5726,7 @@ Last-Update: 2017-07-19
+ except Exception:
+ return 1
+ def process(self):
-+ Task.TaskBase.process(self)
++ Task.Task.process(self)
+ if'msg'in self.args:
+ with self.generator.bld.multicheck_lock:
+ self.conf.start_msg(self.args['msg'])
@@ -5512,10 +5753,11 @@ Last-Update: 2017-07-19
+ return
+ bld=par()
+ bld.keep=kw.get('run_all_tests',True)
++ bld.imp_sigs={}
+ tasks=[]
+ id_to_task={}
+ for dct in k:
-+ x=Task.classes['cfgtask'](bld=bld)
++ x=Task.classes['cfgtask'](bld=bld,env=None)
+ tasks.append(x)
+ x.args=dct
+ x.bld=bld
@@ -5565,6 +5807,22 @@ Last-Update: 2017-07-19
+ if x.hasrun!=Task.SUCCESS:
+ if x.args.get('mandatory',True):
+ self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information')
++@conf
++def check_gcc_o_space(self,mode='c'):
++ if int(self.env.CC_VERSION[0])>4:
++ return
++ self.env.stash()
++ if mode=='c':
++ self.env.CCLNK_TGT_F=['-o','']
++ elif mode=='cxx':
++ self.env.CXXLNK_TGT_F=['-o','']
++ features='%s %sshlib'%(mode,mode)
++ try:
++ self.check(msg='Checking if the -o link must be split from arguments',fragment=SNIP_EMPTY_PROGRAM,features=features)
++ except self.errors.ConfigurationError:
++ self.env.revert()
++ else:
++ self.env.commit()
--- /dev/null
+++ b/waflib/Tools/c_osx.py
@@ -0,0 +1,121 @@
@@ -5637,7 +5895,7 @@ Last-Update: 2017-07-19
+ for node in self.to_nodes(self.mac_files):
+ relpath=node.path_from(mac_files_root or node.parent)
+ self.create_task('macapp',node,res_dir.make_node(relpath))
-+ self.add_install_as(install_to=os.path.join(inst_to,relpath),install_source=node)
++ self.add_install_as(install_to=os.path.join(inst_to,relpath),install_from=node)
+ if getattr(self.bld,'is_install',None):
+ self.install_task.hasrun=Task.SKIP_ME
+@feature('cprogram','cxxprogram')
@@ -5691,7 +5949,7 @@ Last-Update: 2017-07-19
+ self.outputs[0].write(txt)
--- /dev/null
+++ b/waflib/Tools/c_preproc.py
-@@ -0,0 +1,616 @@
+@@ -0,0 +1,672 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -5705,7 +5963,7 @@ Last-Update: 2017-07-19
+POPFILE='-'
+recursion_limit=150
+go_absolute=False
-+standard_includes=['/usr/include']
++standard_includes=['/usr/local/include','/usr/include']
+if Utils.is_win32:
+ standard_includes=[]
+use_trigraphs=0
@@ -5741,40 +5999,60 @@ Last-Update: 2017-07-19
+for x,syms in enumerate(ops):
+ for u in syms.split():
+ prec[u]=x
-+def trimquotes(s):
-+ if not s:return''
-+ s=s.rstrip()
-+ if s[0]=="'"and s[-1]=="'":return s[1:-1]
-+ return s
+def reduce_nums(val_1,val_2,val_op):
-+ try:a=0+val_1
-+ except TypeError:a=int(val_1)
-+ try:b=0+val_2
-+ except TypeError:b=int(val_2)
++ try:
++ a=0+val_1
++ except TypeError:
++ a=int(val_1)
++ try:
++ b=0+val_2
++ except TypeError:
++ b=int(val_2)
+ d=val_op
-+ if d=='%':c=a%b
-+ elif d=='+':c=a+b
-+ 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==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=a<<b
-+ elif d=='>>':c=a>>b
-+ else:c=0
++ if d=='%':
++ c=a%b
++ elif d=='+':
++ c=a+b
++ 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==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=a<<b
++ elif d=='>>':
++ c=a>>b
++ else:
++ c=0
+ return c
+def get_num(lst):
-+ if not lst:raise PreprocError('empty list for get_num')
++ if not lst:
++ raise PreprocError('empty list for get_num')
+ (p,v)=lst[0]
+ if p==OP:
+ if v=='(':
@@ -5814,7 +6092,8 @@ Last-Update: 2017-07-19
+ else:
+ raise PreprocError('Invalid token %r for get_num'%lst)
+def get_term(lst):
-+ if not lst:raise PreprocError('empty list for get_term')
++ if not lst:
++ raise PreprocError('empty list for get_term')
+ num,lst=get_num(lst)
+ if not lst:
+ return(num,[])
@@ -5930,18 +6209,22 @@ Last-Update: 2017-07-19
+ one_param.append((p2,v2))
+ count_paren+=1
+ elif v2==')':
-+ if one_param:args.append(one_param)
++ if one_param:
++ args.append(one_param)
+ break
+ elif v2==',':
-+ if not one_param:raise PreprocError('empty param in funcall %r'%v)
++ if not one_param:
++ raise PreprocError('empty param in funcall %r'%v)
+ args.append(one_param)
+ one_param=[]
+ else:
+ one_param.append((p2,v2))
+ else:
+ one_param.append((p2,v2))
-+ if v2=='(':count_paren+=1
-+ elif v2==')':count_paren-=1
++ if v2=='(':
++ count_paren+=1
++ elif v2==')':
++ count_paren-=1
+ else:
+ raise PreprocError('malformed macro')
+ accu=[]
@@ -5974,7 +6257,8 @@ Last-Update: 2017-07-19
+ for x in args[pt-st+1:]:
+ va_toks.extend(x)
+ va_toks.append((OP,','))
-+ if va_toks:va_toks.pop()
++ if va_toks:
++ va_toks.pop()
+ if len(accu)>1:
+ (p3,v3)=accu[-1]
+ (p4,v4)=accu[-2]
@@ -6001,15 +6285,21 @@ Last-Update: 2017-07-19
+ i+=1
+def eval_macro(lst,defs):
+ reduce_tokens(lst,defs,[])
-+ if not lst:raise PreprocError('missing tokens to evaluate')
-+ (p,v)=reduce_eval(lst)
++ if not lst:
++ raise PreprocError('missing tokens to evaluate')
++ if lst:
++ p,v=lst[0]
++ if p==IDENT and v not in defs:
++ raise PreprocError('missing macro %r'%lst)
++ p,v=reduce_eval(lst)
+ return int(v)!=0
+def extract_macro(txt):
+ t=tokenize(txt)
+ if re_fun.search(txt):
+ p,name=t[0]
+ p,v=t[1]
-+ if p!=OP:raise PreprocError('expected (')
++ if p!=OP:
++ raise PreprocError('expected (')
+ i=1
+ pindex=0
+ params={}
@@ -6078,16 +6368,20 @@ Last-Update: 2017-07-19
+ return ord(txt)
+ c=txt[1]
+ if c=='x':
-+ if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
++ if len(txt)==4 and txt[3]in string.hexdigits:
++ return int(txt[2:],16)
+ return int(txt[2:],16)
+ elif c.isdigit():
-+ if c=='0'and len(txt)==2:return 0
++ if c=='0'and len(txt)==2:
++ return 0
+ for i in 3,2,1:
+ if len(txt)>i and txt[1:1+i].isdigit():
+ return(1+i,int(txt[1:1+i],8))
+ else:
-+ try:return chr_esc[c]
-+ except KeyError:raise PreprocError('could not parse char literal %r'%txt)
++ try:
++ return chr_esc[c]
++ except KeyError:
++ raise PreprocError('could not parse char literal %r'%txt)
+def tokenize(s):
+ return tokenize_private(s)[:]
+def tokenize_private(s):
@@ -6098,27 +6392,32 @@ Last-Update: 2017-07-19
+ v=m(name)
+ if v:
+ if name==IDENT:
-+ try:
-+ g_optrans[v]
++ if v in g_optrans:
+ name=OP
-+ except KeyError:
-+ if v.lower()=="true":
-+ v=1
-+ name=NUM
-+ elif v.lower()=="false":
-+ v=0
-+ name=NUM
++ elif v.lower()=="true":
++ v=1
++ name=NUM
++ elif v.lower()=="false":
++ v=0
++ name=NUM
+ elif name==NUM:
-+ if m('oct'):v=int(v,8)
-+ elif m('hex'):v=int(m('hex'),16)
-+ elif m('n0'):v=m('n0')
++ if m('oct'):
++ v=int(v,8)
++ elif m('hex'):
++ v=int(m('hex'),16)
++ elif m('n0'):
++ v=m('n0')
+ else:
+ v=m('char')
-+ if v:v=parse_char(v)
-+ else:v=m('n2')or m('n4')
++ if v:
++ v=parse_char(v)
++ else:
++ v=m('n2')or m('n4')
+ elif name==OP:
-+ if v=='%:':v='#'
-+ elif v=='%:%:':v='##'
++ if v=='%:':
++ v='#'
++ elif v=='%:%:':
++ v='##'
+ elif name==STR:
+ v=v[1:-1]
+ ret.append((name,v))
@@ -6151,11 +6450,11 @@ Last-Update: 2017-07-19
+ self.names=[]
+ self.curfile=''
+ self.ban_includes=set()
++ self.listed=set()
+ def cached_find_resource(self,node,filename):
+ try:
+ cache=node.ctx.preproc_cache_node
+ except AttributeError:
-+ global FILE_CACHE_SIZE
+ cache=node.ctx.preproc_cache_node=Utils.lru_cache(FILE_CACHE_SIZE)
+ key=(node,filename)
+ try:
@@ -6171,27 +6470,41 @@ Last-Update: 2017-07-19
+ ret=None
+ cache[key]=ret
+ return ret
-+ def tryfind(self,filename):
++ def tryfind(self,filename,kind='"',env=None):
+ 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:
-+ if found:
-+ break
-+ found=self.cached_find_resource(n,filename)
++ found=None
++ if kind=='"':
++ if env.MSVC_VERSION:
++ for n in reversed(self.currentnode_stack):
++ found=self.cached_find_resource(n,filename)
++ if found:
++ break
++ else:
++ found=self.cached_find_resource(self.currentnode_stack[-1],filename)
++ if not found:
++ for n in self.nodepaths:
++ found=self.cached_find_resource(n,filename)
++ if found:
++ break
++ listed=self.listed
+ if found and not found in self.ban_includes:
-+ self.nodes.append(found)
++ if found not in listed:
++ listed.add(found)
++ self.nodes.append(found)
+ self.addlines(found)
+ else:
-+ if not filename in self.names:
++ if filename not in listed:
++ listed.add(filename)
+ self.names.append(filename)
+ return found
+ def filter_comments(self,node):
+ code=node.read()
+ if use_trigraphs:
-+ for(a,b)in trig_def:code=code.split(a).join(b)
++ for(a,b)in trig_def:
++ code=code.split(a).join(b)
+ code=re_nl.sub('',code)
+ code=re_cpp.sub(repl,code)
+ return re_lines.findall(code)
@@ -6199,7 +6512,6 @@ Last-Update: 2017-07-19
+ try:
+ cache=node.ctx.preproc_cache_lines
+ except AttributeError:
-+ global LINE_CACHE_SIZE
+ cache=node.ctx.preproc_cache_lines=Utils.lru_cache(LINE_CACHE_SIZE)
+ try:
+ return cache[node]
@@ -6221,8 +6533,7 @@ Last-Update: 2017-07-19
+ raise PreprocError('could not read the file %r'%node)
+ except Exception:
+ if Logs.verbose>0:
-+ Logs.error('parsing %r failed',node)
-+ traceback.print_exc()
++ Logs.error('parsing %r failed %s',node,traceback.format_exc())
+ else:
+ self.lines.extend(lines)
+ def start(self,node,env):
@@ -6240,8 +6551,6 @@ Last-Update: 2017-07-19
+ self.currentnode_stack.pop()
+ continue
+ try:
-+ ve=Logs.verbose
-+ if ve:Logs.debug('preproc: line is %s - %s state is %s',token,line,self.state)
+ state=self.state
+ if token[:2]=='if':
+ state.append(undefined)
@@ -6252,23 +6561,27 @@ Last-Update: 2017-07-19
+ continue
+ if token=='if':
+ ret=eval_macro(tokenize(line),self.defs)
-+ if ret:state[-1]=accepted
-+ else:state[-1]=ignored
++ if ret:
++ state[-1]=accepted
++ else:
++ state[-1]=ignored
+ elif token=='ifdef':
+ m=re_mac.match(line)
-+ if m and m.group()in self.defs:state[-1]=accepted
-+ else:state[-1]=ignored
++ if m and m.group()in self.defs:
++ state[-1]=accepted
++ else:
++ state[-1]=ignored
+ elif token=='ifndef':
+ m=re_mac.match(line)
-+ if m and m.group()in self.defs:state[-1]=ignored
-+ else:state[-1]=accepted
++ if m and m.group()in self.defs:
++ state[-1]=ignored
++ else:
++ state[-1]=accepted
+ elif token=='include'or token=='import':
+ (kind,inc)=extract_include(line,self.defs)
-+ if ve:Logs.debug('preproc: include found %s (%s) ',inc,kind)
-+ if kind=='"'or not strict_quotes:
-+ self.current_file=self.tryfind(inc)
-+ if token=='import':
-+ self.ban_includes.add(self.current_file)
++ self.current_file=self.tryfind(inc,kind,env)
++ if token=='import':
++ self.ban_includes.add(self.current_file)
+ elif token=='elif':
+ if state[-1]==accepted:
+ state[-1]=skipped
@@ -6276,8 +6589,10 @@ Last-Update: 2017-07-19
+ if eval_macro(tokenize(line),self.defs):
+ state[-1]=accepted
+ elif token=='else':
-+ if state[-1]==accepted:state[-1]=skipped
-+ elif state[-1]==ignored:state[-1]=accepted
++ if state[-1]==accepted:
++ state[-1]=skipped
++ elif state[-1]==ignored:
++ state[-1]=accepted
+ elif token=='define':
+ try:
+ self.defs[self.define_name(line)]=line
@@ -6292,11 +6607,10 @@ Last-Update: 2017-07-19
+ self.ban_includes.add(self.current_file)
+ except Exception as e:
+ if Logs.verbose:
-+ Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
++ Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,traceback.format_exc())
+ def define_name(self,line):
+ return re_mac.match(line).group()
+def scan(task):
-+ global go_absolute
+ try:
+ incn=task.generator.includes_nodes
+ except AttributeError:
@@ -6445,7 +6759,7 @@ Last-Update: 2017-07-19
+class grep_for_endianness(Task.Task):
+ color='PINK'
+ def run(self):
-+ txt=self.inputs[0].read(flags='rb').decode('iso8859-1')
++ txt=self.inputs[0].read(flags='rb').decode('latin-1')
+ if txt.find('LiTTleEnDian')>-1:
+ self.generator.tmp.append('little')
+ elif txt.find('BIGenDianSyS')>-1:
@@ -6465,7 +6779,7 @@ Last-Update: 2017-07-19
+ return tmp[0]
--- /dev/null
+++ b/waflib/Tools/ccroot.py
-@@ -0,0 +1,476 @@
+@@ -0,0 +1,479 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -6531,6 +6845,7 @@ Last-Update: 2017-07-19
+ self.env.INCPATHS=[x.path_from(cwd)for x in lst]
+class link_task(Task.Task):
+ color='YELLOW'
++ weight=3
+ inst_to=None
+ chmod=Utils.O755
+ def add_target(self,target):
@@ -6590,8 +6905,10 @@ Last-Update: 2017-07-19
+def rm_tgt(cls):
+ old=cls.run
+ def wrap(self):
-+ try:os.remove(self.outputs[0].abspath())
-+ except OSError:pass
++ try:
++ os.remove(self.outputs[0].abspath())
++ except OSError:
++ pass
+ return old(self)
+ setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
@@ -6615,7 +6932,7 @@ Last-Update: 2017-07-19
+ try:
+ inst_to=self.install_path
+ except AttributeError:
-+ inst_to=self.link_task.__class__.inst_to
++ inst_to=self.link_task.inst_to
+ if inst_to:
+ self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task)
+@taskgen_method
@@ -6707,7 +7024,7 @@ Last-Update: 2017-07-19
+ if y.tmp_use_objects:
+ self.add_objects_from_tgen(y)
+ if getattr(y,'export_includes',None):
-+ self.includes.extend(y.to_incnodes(y.export_includes))
++ self.includes=self.includes+y.to_incnodes(y.export_includes)
+ if getattr(y,'export_defines',None):
+ self.env.append_value('DEFINES',self.to_list(y.export_defines))
+ for x in names:
@@ -6775,8 +7092,8 @@ Last-Update: 2017-07-19
+ node=self.path.find_resource(self.defs)
+ if not node:
+ raise Errors.WafError('invalid def file %r'%self.defs)
-+ if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
-+ self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.get_cwd()))
++ if self.env.def_PATTERN:
++ self.env.append_value('LINKFLAGS',self.env.def_PATTERN%node.path_from(self.get_cwd()))
+ self.link_task.dep_nodes.append(node)
+ else:
+ self.link_task.inputs.append(node)
@@ -6823,7 +7140,7 @@ Last-Update: 2017-07-19
+ outs.append(node.parent.make_node(name2))
+ self.create_task('vnum',node,outs)
+ if getattr(self,'install_task',None):
-+ self.install_task.hasrun=Task.SKIP_ME
++ self.install_task.hasrun=Task.SKIPPED
+ path=self.install_task.install_to
+ if self.env.DEST_OS=='openbsd':
+ libname=self.link_task.outputs[0].name
@@ -6841,7 +7158,7 @@ Last-Update: 2017-07-19
+ try:
+ inst_to=self.install_path
+ except AttributeError:
-+ inst_to=self.link_task.__class__.inst_to
++ inst_to=self.link_task.inst_to
+ if inst_to:
+ p=Utils.subst_vars(inst_to,self.env)
+ path=os.path.join(p,name2)
@@ -7174,7 +7491,7 @@ Last-Update: 2017-07-19
+ opt.load('%s'%x)
--- /dev/null
+++ b/waflib/Tools/cs.py
-@@ -0,0 +1,98 @@
+@@ -0,0 +1,113 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -7235,10 +7552,8 @@ Last-Update: 2017-07-19
+ else:
+ out=node.change_ext('.pdb')
+ self.cs_task.outputs.append(out)
-+ try:
-+ self.install_task.source.append(out)
-+ except AttributeError:
-+ pass
++ if getattr(self,'install_task',None):
++ self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out)
+ if csdebug=='pdbonly':
+ val=['/debug+','/debug:pdbonly']
+ elif csdebug=='full':
@@ -7246,13 +7561,30 @@ Last-Update: 2017-07-19
+ else:
+ val=['/debug-']
+ self.env.append_value('CSFLAGS',val)
++@feature('cs')
++@after_method('debug_cs')
++def doc_cs(self):
++ csdoc=getattr(self,'csdoc',self.env.CSDOC)
++ if not csdoc:
++ return
++ node=self.cs_task.outputs[0]
++ out=node.change_ext('.xml')
++ self.cs_task.outputs.append(out)
++ if getattr(self,'install_task',None):
++ self.doc_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out)
++ self.env.append_value('CSFLAGS','/doc:%s'%out.abspath())
+class mcs(Task.Task):
+ color='YELLOW'
+ run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
-+ def exec_command(self,cmd,**kw):
-+ if'/noconfig'in cmd:
-+ raise ValueError('/noconfig is not allowed when using response files, check your flags!')
-+ return super(self.__class__,self).exec_command(cmd,**kw)
++ def split_argfile(self,cmd):
++ inline=[cmd[0]]
++ infile=[]
++ for x in cmd[1:]:
++ if x.lower()=='/noconfig':
++ inline.append(x)
++ else:
++ infile.append(self.quote_flag(x))
++ return(inline,infile)
+def configure(conf):
+ csc=getattr(Options.options,'cscbinary',None)
+ if csc:
@@ -7416,7 +7748,7 @@ Last-Update: 2017-07-19
+ self.env.DLIBRARY=ret.strip()
--- /dev/null
+++ b/waflib/Tools/d_scan.py
-@@ -0,0 +1,131 @@
+@@ -0,0 +1,136 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -7437,7 +7769,8 @@ Last-Update: 2017-07-19
+ i+=1
+ while i<max:
+ c=txt[i]
-+ if c==delim:break
++ if c==delim:
++ break
+ elif c=='\\':
+ i+=1
+ i+=1
@@ -7446,7 +7779,8 @@ Last-Update: 2017-07-19
+ elif c=='/':
+ buf.append(txt[begin:i])
+ i+=1
-+ if i==max:break
++ if i==max:
++ break
+ c=txt[i]
+ if c=='+':
+ i+=1
@@ -7460,7 +7794,8 @@ Last-Update: 2017-07-19
+ c=None
+ elif prev=='+'and c=='/':
+ nesting-=1
-+ if nesting==0:break
++ if nesting==0:
++ break
+ c=None
+ i+=1
+ elif c=='*':
@@ -7469,7 +7804,8 @@ Last-Update: 2017-07-19
+ while i<max:
+ prev=c
+ c=txt[i]
-+ if prev=='*'and c=='/':break
++ if prev=='*'and c=='/':
++ break
+ i+=1
+ elif c=='/':
+ i+=1
@@ -7537,7 +7873,8 @@ Last-Update: 2017-07-19
+ code="".join(filter_comments(path))
+ names=self.get_strings(code)
+ for x in names:
-+ if x in self.allnames:continue
++ if x in self.allnames:
++ continue
+ self.allnames.append(x)
+ self.tryfind(x)
+def scan(self):
@@ -7564,7 +7901,7 @@ Last-Update: 2017-07-19
+ if not'process_dbus'in self.meths:
+ self.meths.append('process_dbus')
+ self.dbus_lst.append([filename,prefix,mode])
-+@before_method('apply_core')
++@before_method('process_source')
+def process_dbus(self):
+ for filename,prefix,mode in getattr(self,'dbus_lst',[]):
+ node=self.path.find_resource(filename)
@@ -7636,12 +7973,12 @@ Last-Update: 2017-07-19
+ conf.common_flags_ldc()
--- /dev/null
+++ b/waflib/Tools/errcheck.py
-@@ -0,0 +1,167 @@
+@@ -0,0 +1,175 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy',}
++typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy','uses':'use',}
+meths_typos=['__call__','program','shlib','stlib','objects']
+import sys
+from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
@@ -7683,8 +8020,11 @@ Last-Update: 2017-07-19
+ for(k,v)in uids.items():
+ if len(v)>1:
+ Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid')
++ tg_details=tsk.generator.name
++ if Logs.verbose>2:
++ tg_details=tsk.generator
+ for tsk in v:
-+ Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tsk.generator)
++ Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tg_details)
+def check_invalid_constraints(self):
+ feat=set()
+ for x in list(TaskGen.feats.values()):
@@ -7730,15 +8070,20 @@ Last-Update: 2017-07-19
+ Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0])
+ if'.'in sp:
+ Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0])
-+ if kw.get('remove',True):
-+ try:
-+ if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
-+ Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)',self)
-+ except AttributeError:
-+ pass
+ return self.old_ant_glob(*k,**kw)
+ Node.Node.old_ant_glob=Node.Node.ant_glob
+ Node.Node.ant_glob=ant_glob
++ def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False):
++ if remove:
++ try:
++ if self.is_child_of(self.ctx.bldnode)and not quiet:
++ quiet=True
++ Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False',self)
++ except AttributeError:
++ pass
++ return self.old_ant_iter(accept,maxdepth,pats,dir,src,remove,quiet)
++ Node.Node.old_ant_iter=Node.Node.ant_iter
++ Node.Node.ant_iter=ant_iter
+ old=Task.is_before
+ def is_before(t1,t2):
+ ret=old(t1,t2)
@@ -7762,7 +8107,7 @@ Last-Update: 2017-07-19
+ else:
+ for x in('before','after'):
+ for y in self.to_list(getattr(self,x,[])):
-+ if not Task.classes.get(y,None):
++ if not Task.classes.get(y):
+ Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self)
+ TaskGen.feature('*')(check_err_order)
+ def check_compile(self):
@@ -7798,7 +8143,7 @@ Last-Update: 2017-07-19
+ elif name=='prepend':
+ raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
+ if name in self.__slots__:
-+ return object.__getattr__(self,name,default)
++ return super(ConfigSet.ConfigSet,self).__getattr__(name,default)
+ else:
+ return self[name]
+ ConfigSet.ConfigSet.__getattr__=_getattr
@@ -7811,7 +8156,7 @@ Last-Update: 2017-07-19
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+from waflib import Utils,Task
++from waflib import Utils,Task,Errors
+from waflib.Tools import ccroot,fc_config,fc_scan
+from waflib.TaskGen import extension
+from waflib.Configure import conf
@@ -7819,12 +8164,12 @@ Last-Update: 2017-07-19
+ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
-+@extension('.f','.f90','.F','.F90','.for','.FOR')
++@extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08')
+def fc_hook(self,node):
+ return self.create_compiled_task('fc',node)
+@conf
+def modfile(conf,name):
-+ return{'lower':name.lower()+'.mod','lower.MOD':name.upper()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
++ return{'lower':name.lower()+'.mod','lower.MOD':name.lower()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
+def get_fortran_tasks(tsk):
+ bld=tsk.generator.bld
+ tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
@@ -7860,7 +8205,7 @@ Last-Update: 2017-07-19
+ name=bld.modfile(x.replace('MOD@',''))
+ node=bld.srcnode.find_or_declare(name)
+ tsk.set_outputs(node)
-+ outs[id(node)].add(tsk)
++ outs[node].add(tsk)
+ for tsk in lst:
+ key=tsk.uid()
+ for x in bld.raw_deps[key]:
@@ -7870,7 +8215,7 @@ Last-Update: 2017-07-19
+ if node and node not in tsk.outputs:
+ if not node in bld.node_deps[key]:
+ bld.node_deps[key].append(node)
-+ ins[id(node)].add(tsk)
++ ins[node].add(tsk)
+ for k in ins.keys():
+ for a in ins[k]:
+ a.run_after.update(outs[k])
@@ -7909,7 +8254,7 @@ Last-Update: 2017-07-19
+ kw['output']=0
+ try:
+ (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
-+ except Exception:
++ except Errors.WafError:
+ return-1
+ if bld.out:
+ bld.to_log('out: %s\n'%bld.out)
@@ -7917,7 +8262,7 @@ Last-Update: 2017-07-19
+ bld.to_log('err: %s\n'%bld.err)
--- /dev/null
+++ b/waflib/Tools/fc_config.py
-@@ -0,0 +1,287 @@
+@@ -0,0 +1,299 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -7977,7 +8322,7 @@ Last-Update: 2017-07-19
+ v.LINKFLAGS_fcshlib=['-dynamiclib']
+ v.fcshlib_PATTERN='lib%s.dylib'
+ v.FRAMEWORKPATH_ST='-F%s'
-+ v.FRAMEWORK_ST='-framework %s'
++ v.FRAMEWORK_ST=['-framework']
+ v.LINKFLAGS_fcstlib=[]
+ v.FCSHLIB_MARKER=''
+ v.FCSTLIB_MARKER=''
@@ -7987,7 +8332,7 @@ Last-Update: 2017-07-19
+ v=conf.env
+ v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
+ v.fcshlib_PATTERN='%s.dll'
-+ v.implib_PATTERN='lib%s.dll.a'
++ v.implib_PATTERN='%s.dll.a'
+ v.IMPLIB_ST='-Wl,--out-implib,%s'
+ v.FCFLAGS_fcshlib=[]
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
@@ -8196,7 +8541,7 @@ Last-Update: 2017-07-19
+ self.env.fcshlib_PATTERN=self.env.pyext_PATTERN
+@conf
+def detect_openmp(self):
-+ for x in('-qopenmp','-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:
@@ -8205,6 +8550,18 @@ Last-Update: 2017-07-19
+ break
+ else:
+ self.fatal('Could not find OpenMP')
++@conf
++def check_gfortran_o_space(self):
++ if self.env.FC_NAME!='GFORTRAN'or int(self.env.FC_VERSION[0])>4:
++ return
++ self.env.stash()
++ self.env.FCLNK_TGT_F=['-o','']
++ try:
++ self.check_fc(msg='Checking if the -o link must be split from arguments',fragment=FC_FRAGMENT,features='fc fcshlib')
++ except self.errors.ConfigurationError:
++ self.env.revert()
++ else:
++ self.env.commit()
--- /dev/null
+++ b/waflib/Tools/fc_scan.py
@@ -0,0 +1,64 @@
@@ -8274,7 +8631,7 @@ Last-Update: 2017-07-19
+ self.names.append(filename)
--- /dev/null
+++ b/waflib/Tools/flex.py
-@@ -0,0 +1,37 @@
+@@ -0,0 +1,38 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -8291,7 +8648,8 @@ Last-Update: 2017-07-19
+ bld=tsk.generator.bld
+ wd=bld.variant_dir
+ def to_list(xx):
-+ if isinstance(xx,str):return[xx]
++ if isinstance(xx,str):
++ return[xx]
+ return xx
+ tsk.last_cmd=lst=[]
+ lst.extend(to_list(env.FLEX))
@@ -8386,7 +8744,7 @@ Last-Update: 2017-07-19
+ conf.load('asm')
--- /dev/null
+++ b/waflib/Tools/gcc.py
-@@ -0,0 +1,103 @@
+@@ -0,0 +1,104 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -8431,7 +8789,7 @@ Last-Update: 2017-07-19
+ v=conf.env
+ v.cprogram_PATTERN='%s.exe'
+ v.cshlib_PATTERN='%s.dll'
-+ v.implib_PATTERN='lib%s.dll.a'
++ v.implib_PATTERN='%s.dll.a'
+ v.IMPLIB_ST='-Wl,--out-implib,%s'
+ v.CFLAGS_cshlib=[]
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
@@ -8490,6 +8848,7 @@ Last-Update: 2017-07-19
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
++ conf.check_gcc_o_space()
--- /dev/null
+++ b/waflib/Tools/gdc.py
@@ -0,0 +1,35 @@
@@ -8530,7 +8889,7 @@ Last-Update: 2017-07-19
+ conf.d_platform_flags()
--- /dev/null
+++ b/waflib/Tools/gfortran.py
-@@ -0,0 +1,68 @@
+@@ -0,0 +1,71 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -8570,8 +8929,10 @@ Last-Update: 2017-07-19
+ version_re=re.compile(r"GNU\s*Fortran",re.I).search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
-+ if out:match=version_re(out)
-+ else:match=version_re(err)
++ if out:
++ match=version_re(out)
++ else:
++ match=version_re(err)
+ if not match:
+ conf.fatal('Could not determine the compiler type')
+ cmd=fc+['-dM','-E','-']
@@ -8599,9 +8960,10 @@ Last-Update: 2017-07-19
+ conf.fc_add_flags()
+ conf.gfortran_flags()
+ conf.gfortran_modifier_platform()
++ conf.check_gfortran_o_space()
--- /dev/null
+++ b/waflib/Tools/glib2.py
-@@ -0,0 +1,241 @@
+@@ -0,0 +1,242 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -8638,7 +9000,8 @@ Last-Update: 2017-07-19
+ get=self.env.get_flat
+ cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
+ ret=bld.exec_command(cmd1)
-+ if ret:return ret
++ if ret:
++ return ret
+ c='''#include "%s"\n'''%self.outputs[0].name
+ self.outputs[1].write(c)
+ cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
@@ -8701,7 +9064,7 @@ Last-Update: 2017-07-19
+ if hasattr(self,'settings_enum_namespace'):
+ raise Errors.WafError("Tried to add gsettings enums to %r more than once"%self.name)
+ self.settings_enum_namespace=namespace
-+ if type(filename_list)!='list':
++ if not isinstance(filename_list,list):
+ filename_list=[filename_list]
+ self.settings_enum_files=filename_list
+@feature('glib2')
@@ -8914,7 +9277,7 @@ Last-Update: 2017-07-19
+ dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
--- /dev/null
+++ b/waflib/Tools/gxx.py
-@@ -0,0 +1,103 @@
+@@ -0,0 +1,104 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -8959,7 +9322,7 @@ Last-Update: 2017-07-19
+ v=conf.env
+ v.cxxprogram_PATTERN='%s.exe'
+ v.cxxshlib_PATTERN='%s.dll'
-+ v.implib_PATTERN='lib%s.dll.a'
++ v.implib_PATTERN='%s.dll.a'
+ v.IMPLIB_ST='-Wl,--out-implib,%s'
+ v.CXXFLAGS_cxxshlib=[]
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
@@ -9018,6 +9381,7 @@ Last-Update: 2017-07-19
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
++ conf.check_gcc_o_space('cxx')
--- /dev/null
+++ b/waflib/Tools/icc.py
@@ -0,0 +1,20 @@
@@ -9066,12 +9430,12 @@ Last-Update: 2017-07-19
+ conf.link_add_flags()
--- /dev/null
+++ b/waflib/Tools/ifort.py
-@@ -0,0 +1,301 @@
+@@ -0,0 +1,303 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import os,re
++import os,re,traceback
+from waflib import Utils,Logs,Errors
+from waflib.Tools import fc,fc_config,fc_scan,ar,ccroot
+from waflib.Configure import conf
@@ -9127,7 +9491,7 @@ Last-Update: 2017-07-19
+ conf.env.FC_VERSION=(k['major'],k['minor'])
+def configure(conf):
+ if Utils.is_win32:
-+ compiler,version,path,includes,libdirs,arch=conf.detect_ifort(True)
++ compiler,version,path,includes,libdirs,arch=conf.detect_ifort()
+ v=conf.env
+ v.DEST_CPU=arch
+ v.PATH=path
@@ -9136,8 +9500,7 @@ Last-Update: 2017-07-19
+ v.MSVC_COMPILER=compiler
+ try:
+ v.MSVC_VERSION=float(version)
-+ except Exception:
-+ raise
++ except ValueError:
+ v.MSVC_VERSION=float(version[:-3])
+ conf.find_ifort_win32()
+ conf.ifort_modifier_win32()
@@ -9154,42 +9517,44 @@ Last-Update: 2017-07-19
+ version_pattern=re.compile('^...?.?\....?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran')
-+ except WindowsError:
++ except OSError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran')
-+ except WindowsError:
++ except OSError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
-+ except WindowsError:
++ except OSError:
+ break
+ index+=1
+ if not version_pattern.match(version):
+ continue
+ targets={}
+ for target,arch in all_ifort_platforms:
-+ if target=='intel64':targetDir='EM64T_NATIVE'
-+ else:targetDir=target
++ if target=='intel64':
++ targetDir='EM64T_NATIVE'
++ else:
++ targetDir=target
+ try:
+ Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
+ pass
+ else:
-+ batch_file=os.path.join(path,'bin','iclvars.bat')
++ batch_file=os.path.join(path,'bin','ifortvars.bat')
+ if os.path.isfile(batch_file):
+ targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
+ for target,arch in all_ifort_platforms:
+ try:
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
+ continue
+ else:
-+ batch_file=os.path.join(path,'bin','iclvars.bat')
++ batch_file=os.path.join(path,'bin','ifortvars.bat')
+ if os.path.isfile(batch_file):
+ targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
+ major=version[0:2]
@@ -9253,7 +9618,7 @@ Last-Update: 2017-07-19
+ try:
+ conf.cmd_and_log(fc+['/help'],env=env)
+ except UnicodeError:
-+ st=Utils.ex_stack()
++ st=traceback.format_exc()
+ if conf.logger:
+ conf.logger.error(st)
+ conf.fatal('ifort: Unicode error - check the code page?')
@@ -9282,7 +9647,7 @@ Last-Update: 2017-07-19
+ return
+ self.is_done=True
+ try:
-+ vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat)
++ vs=self.conf.get_ifort_version_win32(self.compiler,self.version,self.bat_target,self.bat)
+ except Errors.ConfigurationError:
+ self.is_valid=False
+ return
@@ -9322,7 +9687,8 @@ Last-Update: 2017-07-19
+ v.IFORT_MANIFEST=(compiler=='intel'and version>=11)
+ fc=conf.find_program(compiler_name,var='FC',path_list=path)
+ env=dict(conf.environ)
-+ if path:env.update(PATH=';'.join(path))
++ if path:
++ env.update(PATH=';'.join(path))
+ if not conf.cmd_and_log(fc+['/nologo','/help'],env=env):
+ conf.fatal('not intel fortran compiler could not be identified')
+ v.FC_NAME='IFORT'
@@ -9370,11 +9736,12 @@ Last-Update: 2017-07-19
+ self.env.DO_MANIFEST=True
--- /dev/null
+++ b/waflib/Tools/intltool.py
-@@ -0,0 +1,97 @@
+@@ -0,0 +1,101 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from __future__ import with_statement
+import os,re
+from waflib import Context,Task,Utils,Logs
+import waflib.Tools.ccroot
@@ -9392,8 +9759,10 @@ Last-Update: 2017-07-19
+@before_method('process_source')
+@feature('intltool_in')
+def apply_intltool_in_f(self):
-+ try:self.meths.remove('process_source')
-+ except ValueError:pass
++ try:
++ self.meths.remove('process_source')
++ except ValueError:
++ pass
+ self.ensure_localedir()
+ podir=getattr(self,'podir','.')
+ podirnode=self.path.find_dir(podir)
@@ -9421,20 +9790,21 @@ Last-Update: 2017-07-19
+ self.add_install_files(install_to=inst,install_from=task.outputs)
+@feature('intltool_po')
+def apply_intltool_po(self):
-+ try:self.meths.remove('process_source')
-+ except ValueError:pass
++ try:
++ self.meths.remove('process_source')
++ except ValueError:
++ pass
+ 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:
-+ file=open(linguas.abspath())
-+ langs=[]
-+ for line in file.readlines():
-+ if not line.startswith('#'):
-+ langs+=line.split()
-+ file.close()
++ with open(linguas.abspath())as f:
++ langs=[]
++ for line in f.readlines():
++ if not line.startswith('#'):
++ langs+=line.split()
+ re_linguas=re.compile('[-a-zA-Z_@.]+')
+ for lang in langs:
+ if re_linguas.match(lang):
@@ -9470,11 +9840,12 @@ Last-Update: 2017-07-19
+ conf.check(header_name='locale.h')
--- /dev/null
+++ b/waflib/Tools/irixcc.py
-@@ -0,0 +1,50 @@
+@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from waflib import Errors
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
@@ -9491,7 +9862,7 @@ Last-Update: 2017-07-19
+ conf.fatal('irixcc was not found')
+ try:
+ conf.cmd_and_log(cc+['-version'])
-+ except Exception:
++ except Errors.WafError:
+ conf.fatal('%r -version could not be executed'%cc)
+ v.CC=cc
+ v.CC_NAME='irix'
@@ -9523,7 +9894,7 @@ Last-Update: 2017-07-19
+ conf.link_add_flags()
--- /dev/null
+++ b/waflib/Tools/javaw.py
-@@ -0,0 +1,296 @@
+@@ -0,0 +1,299 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -9592,6 +9963,7 @@ Last-Update: 2017-07-19
+ if names:
+ tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
+@feature('javac')
++@before_method('propagate_uselib_vars')
+@after_method('apply_java')
+def use_javac_files(self):
+ lst=[]
@@ -9615,7 +9987,8 @@ Last-Update: 2017-07-19
+@feature('javac')
+@after_method('apply_java','propagate_uselib_vars','use_javac_files')
+def set_classpath(self):
-+ self.env.append_value('CLASSPATH',getattr(self,'classpath',[]))
++ if getattr(self,'classpath',None):
++ self.env.append_unique('CLASSPATH',getattr(self,'classpath',[]))
+ for x in self.tasks:
+ x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
+@feature('jar')
@@ -9637,9 +10010,11 @@ Last-Update: 2017-07-19
+ if manifest:
+ jarcreate=getattr(self,'jarcreate','cfm')
+ if not isinstance(manifest,Node.Node):
-+ node=self.path.find_or_declare(manifest)
++ node=self.path.find_resource(manifest)
+ else:
+ node=manifest
++ if not node:
++ self.bld.fatal('invalid manifest file %r for %r'%(manifest,self))
+ tsk.dep_nodes.append(node)
+ jaropts.insert(0,node.abspath())
+ else:
@@ -9689,7 +10064,6 @@ Last-Update: 2017-07-19
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
-+ global JAR_RE
+ try:
+ self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False)if id(x)!=id(self.outputs[0])]
+ except Exception:
@@ -9709,10 +10083,10 @@ Last-Update: 2017-07-19
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
-+ global SOURCE_RE
+ self.inputs=[]
+ for x in self.srcdir:
-+ self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
++ if x.exists():
++ self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
+ return super(javac,self).runnable_status()
+ def post_run(self):
+ for node in self.generator.outdir.ant_glob('**/*.class'):
@@ -9882,7 +10256,7 @@ Last-Update: 2017-07-19
+ conf.find_program('luac',var='LUAC')
--- /dev/null
+++ b/waflib/Tools/md5_tstamp.py
-@@ -0,0 +1,25 @@
+@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -9897,7 +10271,6 @@ Last-Update: 2017-07-19
+ cache=self.ctx.hashes_md5_tstamp
+ if filename in cache and cache[filename][0]==st.st_mtime:
+ return cache[filename][1]
-+ global STRONGEST
+ if STRONGEST:
+ ret=Utils.h_file(filename)
+ else:
@@ -9910,12 +10283,12 @@ Last-Update: 2017-07-19
+Node.Node.h_file=h_file
--- /dev/null
+++ b/waflib/Tools/msvc.py
-@@ -0,0 +1,660 @@
+@@ -0,0 +1,704 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import os,sys,re
++import os,sys,re,traceback
+from waflib import Utils,Logs,Options,Errors
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
@@ -9940,7 +10313,7 @@ Last-Update: 2017-07-19
+version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
+wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
+'''.split()
-+all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('amd64_x86','x86'),('amd64_arm','arm')]
++all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('x86_arm64','arm64'),('amd64_x86','x86'),('amd64_arm','arm'),('amd64_arm64','arm64')]
+all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
+all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+def options(opt):
@@ -9954,7 +10327,7 @@ Last-Update: 2017-07-19
+ platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
+ desired_versions=getattr(Options.options,'msvc_version','').split(',')
+ if desired_versions==['']:
-+ desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys())))
++ desired_versions=conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys())))
+ lazy_detect=getattr(Options.options,'msvc_lazy',True)
+ if conf.env.MSVC_LAZY_AUTODETECT is False:
+ lazy_detect=False
@@ -9967,11 +10340,17 @@ Last-Update: 2017-07-19
+ del val[arch]
+ conf.env.MSVC_INSTALLED_VERSIONS=versiondict
+ for version in desired_versions:
++ Logs.debug('msvc: detecting %r - %r',version,desired_versions)
+ try:
+ targets=versiondict[version]
+ except KeyError:
+ continue
++ seen=set()
+ for arch in platforms:
++ if arch in seen:
++ continue
++ else:
++ seen.add(arch)
+ try:
+ cfg=targets[arch]
+ except KeyError:
@@ -10021,7 +10400,7 @@ Last-Update: 2017-07-19
+ try:
+ conf.cmd_and_log(cxx+['/help'],env=env)
+ except UnicodeError:
-+ st=Utils.ex_stack()
++ st=traceback.format_exc()
+ if conf.logger:
+ conf.logger.error(st)
+ conf.fatal('msvc: Unicode error - check the code page?')
@@ -10033,43 +10412,14 @@ Last-Update: 2017-07-19
+ finally:
+ conf.env[compiler_name]=''
+ return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
-+@conf
-+def gather_wsdk_versions(conf,versions):
-+ version_pattern=re.compile('^v..?.?\...?.?')
-+ try:
-+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
-+ except WindowsError:
-+ try:
-+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
-+ except WindowsError:
-+ return
-+ index=0
-+ while 1:
-+ try:
-+ version=Utils.winreg.EnumKey(all_versions,index)
-+ except WindowsError:
-+ break
-+ index+=1
-+ if not version_pattern.match(version):
-+ continue
-+ try:
-+ msvc_version=Utils.winreg.OpenKey(all_versions,version)
-+ path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
-+ except WindowsError:
-+ continue
-+ if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
-+ targets={}
-+ for target,arch in all_msvc_platforms:
-+ targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd'))
-+ versions['wsdk '+version[1:]]=targets
+def gather_wince_supported_platforms():
+ supported_wince_platforms=[]
+ try:
+ ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
-+ except WindowsError:
++ except OSError:
+ try:
+ ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
-+ except WindowsError:
++ except OSError:
+ ce_sdk=''
+ if not ce_sdk:
+ return supported_wince_platforms
@@ -10078,15 +10428,15 @@ Last-Update: 2017-07-19
+ try:
+ sdk_device=Utils.winreg.EnumKey(ce_sdk,index)
+ sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
-+ except WindowsError:
++ except OSError:
+ break
+ index+=1
+ try:
+ path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
-+ except WindowsError:
++ except OSError:
+ try:
+ path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
-+ except WindowsError:
++ except OSError:
+ continue
+ path,xml=os.path.split(path)
+ path=str(path)
@@ -10107,17 +10457,17 @@ Last-Update: 2017-07-19
+ prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
-+ except WindowsError:
++ except OSError:
+ prefix='SOFTWARE\\Microsoft\\'+vcver
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
-+ except WindowsError:
++ except OSError:
+ continue
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
-+ except WindowsError:
++ except OSError:
+ break
+ index+=1
+ match=version_pattern.match(version)
@@ -10156,13 +10506,45 @@ Last-Update: 2017-07-19
+ self.is_valid=True
+ (self.bindirs,self.incdirs,self.libdirs)=vs
+ def __str__(self):
-+ return str((self.bindirs,self.incdirs,self.libdirs))
++ return str((self.compiler,self.cpu,self.version,self.bat_target,self.bat))
+ def __repr__(self):
-+ return repr((self.bindirs,self.incdirs,self.libdirs))
++ return repr((self.compiler,self.cpu,self.version,self.bat_target,self.bat))
++@conf
++def gather_wsdk_versions(conf,versions):
++ version_pattern=re.compile('^v..?.?\...?.?')
++ try:
++ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
++ except OSError:
++ try:
++ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
++ except OSError:
++ return
++ index=0
++ while 1:
++ try:
++ version=Utils.winreg.EnumKey(all_versions,index)
++ except OSError:
++ break
++ index+=1
++ if not version_pattern.match(version):
++ continue
++ try:
++ msvc_version=Utils.winreg.OpenKey(all_versions,version)
++ path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
++ except OSError:
++ continue
++ if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
++ targets={}
++ for target,arch in all_msvc_platforms:
++ targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd'))
++ versions['wsdk '+version[1:]]=targets
+@conf
+def gather_msvc_targets(conf,versions,version,vc_path):
+ targets={}
-+ if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
++ if os.path.isfile(os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')):
++ for target,realtarget in all_msvc_platforms[::-1]:
++ targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat'))
++ elif os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
+ for target,realtarget in all_msvc_platforms[::-1]:
+ targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'vcvarsall.bat'))
+ elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
@@ -10170,7 +10552,7 @@ Last-Update: 2017-07-19
+ elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
+ targets['x86']=target_compiler(conf,'msvc','x86',version,'',os.path.join(vc_path,'Bin','vcvars32.bat'))
+ if targets:
-+ versions['msvc '+version]=targets
++ versions['msvc %s'%version]=targets
+@conf
+def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
+ for device,platforms in supported_platforms:
@@ -10197,16 +10579,48 @@ Last-Update: 2017-07-19
+ if targets:
+ versions['winphone '+version]=targets
+@conf
++def gather_vswhere_versions(conf,versions):
++ try:
++ import json
++ except ImportError:
++ Logs.error('Visual Studio 2017 detection requires Python 2.6')
++ return
++ prg_path=os.environ.get('ProgramFiles(x86)',os.environ.get('ProgramFiles','C:\\Program Files (x86)'))
++ vswhere=os.path.join(prg_path,'Microsoft Visual Studio','Installer','vswhere.exe')
++ args=[vswhere,'-products','*','-legacy','-format','json']
++ try:
++ txt=conf.cmd_and_log(args)
++ except Errors.WafError as e:
++ Logs.debug('msvc: vswhere.exe failed %s',e)
++ return
++ if sys.version_info[0]<3:
++ txt=txt.decode(Utils.console_encoding())
++ arr=json.loads(txt)
++ arr.sort(key=lambda x:x['installationVersion'])
++ for entry in arr:
++ ver=entry['installationVersion']
++ ver=str('.'.join(ver.split('.')[:2]))
++ path=str(os.path.abspath(entry['installationPath']))
++ if os.path.exists(path)and('msvc %s'%ver)not in versions:
++ conf.gather_msvc_targets(versions,ver,path)
++@conf
+def gather_msvc_versions(conf,versions):
+ vc_paths=[]
+ for(v,version,reg)in gather_msvc_detected_versions():
+ try:
+ try:
+ msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
-+ except WindowsError:
++ except OSError:
+ msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
+ path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
++ try:
++ msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7")
++ path,type=Utils.winreg.QueryValueEx(msvc_version,version)
++ except OSError:
++ continue
++ else:
++ vc_paths.append((version,os.path.abspath(str(path))))
+ continue
+ else:
+ vc_paths.append((version,os.path.abspath(str(path))))
@@ -10230,29 +10644,31 @@ Last-Update: 2017-07-19
+ version_pattern=re.compile('^...?.?\....?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
-+ except WindowsError:
++ except OSError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
-+ except WindowsError:
++ except OSError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
-+ except WindowsError:
++ except OSError:
+ break
+ index+=1
+ if not version_pattern.match(version):
+ continue
+ targets={}
+ for target,arch in all_icl_platforms:
-+ if target=='intel64':targetDir='EM64T_NATIVE'
-+ else:targetDir=target
++ if target=='intel64':
++ targetDir='EM64T_NATIVE'
++ else:
++ targetDir=target
+ try:
+ Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
+ pass
+ else:
+ batch_file=os.path.join(path,'bin','iclvars.bat')
@@ -10262,7 +10678,7 @@ Last-Update: 2017-07-19
+ try:
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
+ continue
+ else:
+ batch_file=os.path.join(path,'bin','iclvars.bat')
@@ -10275,28 +10691,30 @@ Last-Update: 2017-07-19
+ version_pattern=re.compile('^...?.?\...?.?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
-+ except WindowsError:
++ except OSError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
-+ except WindowsError:
++ except OSError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
-+ except WindowsError:
++ except OSError:
+ break
+ index+=1
+ if not version_pattern.match(version):
+ continue
+ targets={}
+ for target,arch in all_icl_platforms:
-+ if target=='intel64':targetDir='EM64T_NATIVE'
-+ else:targetDir=target
++ if target=='intel64':
++ targetDir='EM64T_NATIVE'
++ else:
++ targetDir=target
+ try:
+ try:
+ defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
-+ except WindowsError:
++ except OSError:
+ if targetDir=='EM64T_NATIVE':
+ defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
+ else:
@@ -10305,7 +10723,7 @@ Last-Update: 2017-07-19
+ Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
-+ except WindowsError:
++ except OSError:
+ pass
+ else:
+ batch_file=os.path.join(path,'bin','iclvars.bat')
@@ -10329,11 +10747,13 @@ Last-Update: 2017-07-19
+ return self.setup_msvc(self.get_msvc_versions())
+@conf
+def get_msvc_versions(self):
-+ dct={}
++ dct=Utils.ordered_iter_dict()
+ self.gather_icl_versions(dct)
+ self.gather_intel_composer_versions(dct)
+ self.gather_wsdk_versions(dct)
+ self.gather_msvc_versions(dct)
++ self.gather_vswhere_versions(dct)
++ Logs.debug('msvc: detected versions %r',list(dct.keys()))
+ return dct
+@conf
+def find_lt_names_msvc(self,libname,is_static=False):
@@ -10374,7 +10794,7 @@ Last-Update: 2017-07-19
+ return None
+ (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
+ if lt_path!=None and lt_libname!=None:
-+ if lt_static==True:
++ if lt_static:
+ return os.path.join(lt_path,lt_libname)
+ if lt_path!=None:
+ _libpaths=[lt_path]+self.env.LIBPATH
@@ -10433,7 +10853,7 @@ Last-Update: 2017-07-19
+ v.MSVC_COMPILER=compiler
+ try:
+ v.MSVC_VERSION=float(version)
-+ except TypeError:
++ except ValueError:
+ v.MSVC_VERSION=float(version[:-3])
+def _get_prog_names(conf,compiler):
+ if compiler=='intel':
@@ -10457,13 +10877,14 @@ Last-Update: 2017-07-19
+ v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
+ cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
+ env=dict(conf.environ)
-+ if path:env.update(PATH=';'.join(path))
++ if path:
++ env.update(PATH=';'.join(path))
+ if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
+ conf.fatal('the msvc compiler could not be identified')
+ v.CC=v.CXX=cxx
+ v.CC_NAME=v.CXX_NAME='msvc'
+ if not v.LINK_CXX:
-+ v.LINK_CXX=conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name)
++ conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name,var='LINK_CXX')
+ if not v.LINK_CC:
+ v.LINK_CC=v.LINK_CXX
+ if not v.AR:
@@ -10502,11 +10923,6 @@ Last-Update: 2017-07-19
+ v.CXX_TGT_F=['/FC']+v.CXX_TGT_F
+ v.CPPPATH_ST='/I%s'
+ v.AR_TGT_F=v.CCLNK_TGT_F=v.CXXLNK_TGT_F='/OUT:'
-+ v.CFLAGS_CONSOLE=v.CXXFLAGS_CONSOLE=['/SUBSYSTEM:CONSOLE']
-+ v.CFLAGS_NATIVE=v.CXXFLAGS_NATIVE=['/SUBSYSTEM:NATIVE']
-+ v.CFLAGS_POSIX=v.CXXFLAGS_POSIX=['/SUBSYSTEM:POSIX']
-+ v.CFLAGS_WINDOWS=v.CXXFLAGS_WINDOWS=['/SUBSYSTEM:WINDOWS']
-+ v.CFLAGS_WINDOWSCE=v.CXXFLAGS_WINDOWSCE=['/SUBSYSTEM:WINDOWSCE']
+ v.CFLAGS_CRT_MULTITHREADED=v.CXXFLAGS_CRT_MULTITHREADED=['/MT']
+ v.CFLAGS_CRT_MULTITHREADED_DLL=v.CXXFLAGS_CRT_MULTITHREADED_DLL=['/MD']
+ v.CFLAGS_CRT_MULTITHREADED_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DBG=['/MTd']
@@ -10526,6 +10942,7 @@ Last-Update: 2017-07-19
+ v.LINKFLAGS_cstlib=[]
+ v.cstlib_PATTERN=v.cxxstlib_PATTERN='%s.lib'
+ v.cprogram_PATTERN=v.cxxprogram_PATTERN='%s.exe'
++ v.def_PATTERN='/def:%s'
+@after_method('apply_link')
+@feature('c','cxx')
+def apply_flags_msvc(self):
@@ -10565,7 +10982,7 @@ Last-Update: 2017-07-19
+@after_method('propagate_uselib_vars')
+def make_winphone_app(self):
+ make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
-+ conf.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib'])
++ self.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib'])
+@feature('winapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
@@ -10606,20 +11023,21 @@ Last-Update: 2017-07-19
+ cls.run=run
--- /dev/null
+++ b/waflib/Tools/perl.py
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
-+from waflib import Task,Options,Utils
++from waflib import Task,Options,Utils,Errors
+from waflib.Configure import conf
+from waflib.TaskGen import extension,feature,before_method
+@before_method('apply_incpaths','apply_link','propagate_uselib_vars')
+@feature('perlext')
+def init_perlext(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
-+ if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
++ if not'PERLEXT'in self.uselib:
++ self.uselib.append('PERLEXT')
+ self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.perlext_PATTERN
+@extension('.xs')
+def xsubpp_file(self,node):
@@ -10655,7 +11073,7 @@ Last-Update: 2017-07-19
+ self.start_msg('perl module %s'%module)
+ try:
+ r=self.cmd_and_log(cmd)
-+ except Exception:
++ except Errors.WafError:
+ self.end_msg(False)
+ return None
+ self.end_msg(r or True)
@@ -10693,13 +11111,13 @@ Last-Update: 2017-07-19
+ opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
--- /dev/null
+++ b/waflib/Tools/python.py
-@@ -0,0 +1,407 @@
+@@ -0,0 +1,410 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,sys
-+from waflib import Utils,Options,Errors,Logs,Task,Node
++from waflib import Errors,Logs,Node,Options,Task,Utils
+from waflib.TaskGen import extension,before_method,after_method,feature
+from waflib.Configure import conf
+FRAG='''
@@ -10740,7 +11158,7 @@ Last-Update: 2017-07-19
+ self.install_32=True
+@extension('.py')
+def process_py(self,node):
-+ assert(getattr(self,'install_path')),'add features="py"'
++ assert(hasattr(self,'install_path')),'add features="py"'
+ if self.install_path:
+ if self.install_from:
+ self.add_install_files(install_to=self.install_path,install_from=node,cwd=self.install_from,relative_trick=True)
@@ -11053,7 +11471,7 @@ Last-Update: 2017-07-19
+ conf.start_msg(msg)
+ try:
+ ret=conf.cmd_and_log(conf.env.PYTHON+['-c',PYTHON_MODULE_TEMPLATE%module_name])
-+ except Exception:
++ except Errors.WafError:
+ conf.end_msg(False)
+ conf.fatal('Could not find the python module %r'%module_name)
+ ret=ret.strip()
@@ -11078,13 +11496,16 @@ Last-Update: 2017-07-19
+ conf.end_msg(ret)
+def configure(conf):
+ v=conf.env
-+ if Options.options.pythondir:
++ if getattr(Options.options,'pythondir',None):
+ v.PYTHONDIR=Options.options.pythondir
-+ if Options.options.pythonarchdir:
++ if getattr(Options.options,'pythonarchdir',None):
+ v.PYTHONARCHDIR=Options.options.pythonarchdir
-+ if Options.options.nopycache:
++ if getattr(Options.options,'nopycache',None):
+ v.NOPYCACHE=Options.options.nopycache
-+ conf.find_program('python',var='PYTHON',value=Options.options.python or sys.executable)
++ if not v.PYTHON:
++ v.PYTHON=[getattr(Options.options,'python',None)or sys.executable]
++ v.PYTHON=Utils.to_list(v.PYTHON)
++ conf.find_program('python',var='PYTHON')
+ v.PYFLAGS=''
+ v.PYFLAGS_OPT='-O'
+ v.PYC=getattr(Options.options,'pyc',1)
@@ -11103,11 +11524,12 @@ Last-Update: 2017-07-19
+ pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
--- /dev/null
+++ b/waflib/Tools/qt5.py
-@@ -0,0 +1,492 @@
+@@ -0,0 +1,497 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from __future__ import with_statement
+try:
+ from xml.sax import make_parser
+ from xml.sax.handler import ContentHandler
@@ -11154,7 +11576,7 @@ Last-Update: 2017-07-19
+ if self.generator:
+ self.generator.tasks.append(tsk)
+ gen=self.generator.bld.producer
-+ gen.outstanding.appendleft(tsk)
++ gen.outstanding.append(tsk)
+ gen.total+=1
+ return tsk
+ else:
@@ -11204,6 +11626,7 @@ Last-Update: 2017-07-19
+ color='BLUE'
+class XMLHandler(ContentHandler):
+ def __init__(self):
++ ContentHandler.__init__(self)
+ self.buf=[]
+ self.files=[]
+ def startElement(self,name,attrs):
@@ -11216,7 +11639,7 @@ Last-Update: 2017-07-19
+ self.buf.append(cars)
+@extension(*EXT_RCC)
+def create_rcc_task(self,node):
-+ rcnode=node.change_ext('_rc.cpp')
++ rcnode=node.change_ext('_rc.%d.cpp'%self.idx)
+ self.create_task('rcc',node,rcnode)
+ cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
+ try:
@@ -11226,8 +11649,13 @@ Last-Update: 2017-07-19
+ return cpptask
+@extension(*EXT_UI)
+def create_uic_task(self,node):
-+ uictask=self.create_task('ui5',node)
-+ uictask.outputs=[node.parent.find_or_declare(self.env.ui_PATTERN%node.name[:-3])]
++ try:
++ uic_cache=self.bld.uic_cache
++ except AttributeError:
++ uic_cache=self.bld.uic_cache={}
++ if node not in uic_cache:
++ uictask=uic_cache[node]=self.create_task('ui5',node)
++ uictask.outputs=[node.parent.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]
@@ -11250,22 +11678,23 @@ Last-Update: 2017-07-19
+ 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')))
++ qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.%d.qm'%self.idx)))
+ 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')]
++ cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if a.inputs 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')
++ rcnode=self.path.find_or_declare(rcnode+('.%d.qrc'%self.idx))
+ 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
++ if len(flag)<2:
++ continue
+ f=flag[0:2]
+ if f in('-D','-I','/D','/I'):
+ if(f[0]=='/'):
@@ -11289,22 +11718,25 @@ Last-Update: 2017-07-19
+ parser=make_parser()
+ curHandler=XMLHandler()
+ parser.setContentHandler(curHandler)
-+ fi=open(self.inputs[0].abspath(),'r')
-+ try:
-+ parser.parse(fi)
-+ finally:
-+ fi.close()
++ with open(self.inputs[0].abspath(),'r')as f:
++ parser.parse(f)
+ 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)
++ if nd:
++ nodes.append(nd)
++ else:
++ names.append(x)
+ return(nodes,names)
++ def quote_flag(self,x):
++ return x
+class moc(Task.Task):
+ color='BLUE'
+ run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
++ def quote_flag(self,x):
++ return x
+class ui5(Task.Task):
+ color='BLUE'
+ run_str='${QT_UIC} ${SRC} -o ${TGT}'
@@ -11345,7 +11777,6 @@ Last-Update: 2017-07-19
+ break
+ else:
+ self.fatal('Could not build a simple Qt application')
-+ from waflib import Utils
+ if Utils.unversioned_sys_platform()=='freebsd':
+ frag='#include <QApplication>\nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n'
+ try:
@@ -11437,7 +11868,7 @@ Last-Update: 2017-07-19
+ 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')
++ self.fatal('this uic compiler is for qt3 or qt4, 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')
@@ -11474,7 +11905,6 @@ Last-Update: 2017-07-19
+ for k in('','5')if Utils.is_win32 else['']:
+ for p in('lib',''):
+ yield(p,name,k,x)
-+ raise StopIteration
+ for tup in lib_names():
+ k=''.join(tup)
+ path=os.path.join(qtlibs,k)
@@ -11502,24 +11932,24 @@ Last-Update: 2017-07-19
+ for i in self.qt5_vars:
+ uselib=i.upper()
+ if Utils.unversioned_sys_platform()=='darwin':
-+ frameworkName=i+'.framework'
-+ qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,i)
++ fwk=i.replace('Qt5','Qt')
++ frameworkName=fwk+'.framework'
++ qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,fwk)
+ if os.path.exists(qtDynamicLib):
-+ env.append_unique('FRAMEWORK_'+uselib,i)
++ env.append_unique('FRAMEWORK_'+uselib,fwk)
++ env.append_unique('FRAMEWORKPATH_'+uselib,env.QTLIBS)
+ 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(env.QTLIBS,frameworkName,'Headers'))
+ else:
-+ for j in('','d'):
-+ k='_DEBUG'if j=='d'else''
-+ ret=self.find_single_qt5_lib(i+j,uselib+k,env.QTLIBS,qtincludes,force_static)
-+ if not force_static and not ret:
-+ ret=self.find_single_qt5_lib(i+j,uselib+k,env.QTLIBS,qtincludes,True)
-+ self.msg('Checking for %s'%(i+j),ret,'GREEN'if ret else'YELLOW')
++ ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,force_static)
++ if not force_static and not ret:
++ ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,True)
++ self.msg('Checking for %s'%i,ret,'GREEN'if ret else'YELLOW')
+ else:
+ path='%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(self.environ.get('PKG_CONFIG_PATH',''),env.QTLIBS,env.QTLIBS)
-+ for i in self.qt5_vars_debug+self.qt5_vars:
++ for i in self.qt5_vars:
+ self.check_cfg(package=i,args='--cflags --libs',mandatory=False,force_static=force_static,pkg_config_path=path)
+@conf
+def simplify_qt5_libs(self):
@@ -11539,7 +11969,6 @@ Last-Update: 2017-07-19
+ 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
@@ -11558,7 +11987,6 @@ Last-Update: 2017-07-19
+ 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):
+ self.qt5_vars=Utils.to_list(getattr(self,'qt5_vars',[]))
@@ -11569,19 +11997,18 @@ Last-Update: 2017-07-19
+ pat=pat.replace('.dll','.lib')
+ if self.environ.get('QT5_FORCE_STATIC'):
+ pat=self.env.cxxstlib_PATTERN
-+ re_qt=re.compile(pat%'(?P<name>Qt5.*)'+'$')
++ if Utils.unversioned_sys_platform()=='darwin':
++ pat="%s\.framework"
++ re_qt=re.compile(pat%'Qt5?(?P<name>.*)'+'$')
+ for x in dirlst:
+ m=re_qt.match(x)
+ if m:
-+ self.qt5_vars.append(m.group('name'))
++ self.qt5_vars.append("Qt5%s"%m.group('name'))
+ if not self.qt5_vars:
+ self.fatal('cannot find any Qt5 library (%r)'%self.env.QTLIBS)
+ qtextralibs=getattr(Options.options,'qtextralibs',None)
+ if qtextralibs:
+ self.qt5_vars.extend(qtextralibs.split(','))
-+ if not hasattr(self,'qt5_vars_debug'):
-+ self.qt5_vars_debug=[a+'_DEBUG'for a in self.qt5_vars]
-+ self.qt5_vars_debug=Utils.to_list(self.qt5_vars_debug)
+@conf
+def set_qt5_defines(self):
+ if sys.platform!='win32':
@@ -11589,7 +12016,6 @@ Last-Update: 2017-07-19
+ for x in self.qt5_vars:
+ y=x.replace('Qt5','Qt')[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')
+ for i in'qtdir qtbin qtlibs'.split():
@@ -11604,7 +12030,7 @@ Last-Update: 2017-07-19
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
-+from waflib import Options,Utils,Task
++from waflib import Errors,Options,Task,Utils
+from waflib.TaskGen import before_method,feature,extension
+from waflib.Configure import conf
+@feature('rubyext')
@@ -11625,12 +12051,12 @@ Last-Update: 2017-07-19
+ ruby=self.find_program('ruby',var='RUBY',value=Options.options.rubybinary)
+ try:
+ version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
-+ except Exception:
++ except Errors.WafError:
+ self.fatal('could not determine ruby version')
+ self.env.RUBY_VERSION=version
+ try:
-+ ver=tuple(map(int,version.split(".")))
-+ except Exception:
++ ver=tuple(map(int,version.split('.')))
++ except Errors.WafError:
+ self.fatal('unsupported ruby version %r'%version)
+ cver=''
+ if minver:
@@ -11683,7 +12109,7 @@ Last-Update: 2017-07-19
+ self.start_msg('Ruby module %s'%module_name)
+ try:
+ self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name])
-+ except Exception:
++ except Errors.WafError:
+ self.end_msg(False)
+ self.fatal('Could not find the ruby module %r'%module_name)
+ self.end_msg(True)
@@ -11698,11 +12124,12 @@ Last-Update: 2017-07-19
+ opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
--- /dev/null
+++ b/waflib/Tools/suncc.py
-@@ -0,0 +1,47 @@
+@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from waflib import Errors
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
@@ -11711,7 +12138,7 @@ Last-Update: 2017-07-19
+ cc=conf.find_program('cc',var='CC')
+ try:
+ conf.cmd_and_log(cc+['-flags'])
-+ except Exception:
++ except Errors.WafError:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v.CC_NAME='sun'
+ conf.get_suncc_version(cc)
@@ -11748,11 +12175,12 @@ Last-Update: 2017-07-19
+ conf.link_add_flags()
--- /dev/null
+++ b/waflib/Tools/suncxx.py
-@@ -0,0 +1,47 @@
+@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from waflib import Errors
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
@@ -11761,7 +12189,7 @@ Last-Update: 2017-07-19
+ cc=conf.find_program(['CC','c++'],var='CXX')
+ try:
+ conf.cmd_and_log(cc+['-flags'])
-+ except Exception:
++ except Errors.WafError:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v.CXX_NAME='sun'
+ conf.get_suncc_version(cc)
@@ -11798,7 +12226,7 @@ Last-Update: 2017-07-19
+ conf.link_add_flags()
--- /dev/null
+++ b/waflib/Tools/tex.py
-@@ -0,0 +1,324 @@
+@@ -0,0 +1,327 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -11810,17 +12238,20 @@ Last-Update: 2017-07-19
+def bibunitscan(self):
+ node=self.inputs[0]
+ nodes=[]
-+ if not node:return nodes
++ if not node:
++ return nodes
+ code=node.read()
+ for match in re_bibunit.finditer(code):
+ path=match.group('file')
+ if path:
++ found=None
+ for k in('','.bib'):
+ Logs.debug('tex: trying %s%s',path,k)
+ fi=node.parent.find_resource(path+k)
+ if fi:
++ found=True
+ nodes.append(fi)
-+ else:
++ if not found:
+ Logs.debug('tex: could not find %s',path)
+ Logs.debug('tex: found the following bibunit files: %s',nodes)
+ return nodes
@@ -11865,13 +12296,13 @@ Last-Update: 2017-07-19
+ nodes=[]
+ names=[]
+ seen=[]
-+ if not node:return(nodes,names)
++ if not node:
++ return(nodes,names)
+ def parse_node(node):
+ if node in seen:
+ return
+ seen.append(node)
+ code=node.read()
-+ global re_tex
+ for match in re_tex.finditer(code):
+ multibib=match.group('type')
+ if multibib and multibib.startswith('bibliography'):
@@ -12125,13 +12556,13 @@ Last-Update: 2017-07-19
+ v.DVIPSFLAGS='-Ppdf'
--- /dev/null
+++ b/waflib/Tools/vala.py
-@@ -0,0 +1,214 @@
+@@ -0,0 +1,218 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
-+from waflib import Context,Task,Utils,Logs,Options,Errors,Node
++from waflib import Build,Context,Errors,Logs,Node,Options,Task,Utils
+from waflib.TaskGen import extension,taskgen_method
+from waflib.Configure import conf
+class valac(Task.Task):
@@ -12228,8 +12659,10 @@ Last-Update: 2017-07-19
+ package_obj=self.bld.get_tgen_by_name(package)
+ except Errors.WafError:
+ continue
++ package_obj.post()
+ package_name=package_obj.target
-+ for task in package_obj.tasks:
++ task=getattr(package_obj,'valatask',None)
++ if task:
+ for output in task.outputs:
+ if output.name==package_name+".vapi":
+ valatask.set_run_after(task)
@@ -12259,19 +12692,13 @@ Last-Update: 2017-07-19
+ valatask.outputs.append(self.dump_deps_node)
+ if self.is_lib and valatask.install_binding:
+ headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
-+ try:
-+ self.install_vheader.source=headers_list
-+ except AttributeError:
++ if headers_list:
+ self.install_vheader=self.add_install_files(install_to=valatask.header_path,install_from=headers_list)
+ vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
-+ try:
-+ self.install_vapi.source=vapi_list
-+ except AttributeError:
++ if vapi_list:
+ self.install_vapi=self.add_install_files(install_to=valatask.vapi_path,install_from=vapi_list)
+ gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
-+ try:
-+ self.install_gir.source=gir_list
-+ except AttributeError:
++ if gir_list:
+ self.install_gir=self.add_install_files(install_to=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),install_from=gir_list)
+ if hasattr(self,'vala_resources'):
+ nodes=self.to_nodes(self.vala_resources)
@@ -12291,12 +12718,20 @@ Last-Update: 2017-07-19
+ c_node=valatask.vala_dir_node.find_or_declare(name)
+ valatask.outputs.append(c_node)
+ self.source.append(c_node)
++@extension('.vapi')
++def vapi_file(self,node):
++ try:
++ valatask=self.valatask
++ except AttributeError:
++ valatask=self.valatask=self.create_task('valac')
++ self.init_vala_task()
++ valatask.inputs.append(node)
+@conf
+def find_valac(self,valac_name,min_version):
+ valac=self.find_program(valac_name,var='VALAC')
+ try:
+ output=self.cmd_and_log(valac+['--version'])
-+ except Exception:
++ except Errors.WafError:
+ valac_version=None
+ else:
+ ver=re.search(r'\d+.\d+.\d+',output).group().split('.')
@@ -12342,12 +12777,12 @@ Last-Update: 2017-07-19
+ valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
--- /dev/null
+++ b/waflib/Tools/waf_unit_test.py
-@@ -0,0 +1,143 @@
+@@ -0,0 +1,172 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import os,sys
++import os,shlex,sys
+from waflib.TaskGen import feature,after_method,taskgen_method
+from waflib import Utils,Task,Logs,Options
+from waflib.Tools import ccroot
@@ -12361,6 +12796,39 @@ Last-Update: 2017-07-19
+status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str))
+sys.exit(status)
+"""
++@taskgen_method
++def handle_ut_cwd(self,key):
++ cwd=getattr(self,key,None)
++ if cwd:
++ if isinstance(cwd,str):
++ if os.path.isabs(cwd):
++ self.ut_cwd=self.bld.root.make_node(cwd)
++ else:
++ self.ut_cwd=self.path.make_node(cwd)
++@feature('test_scripts')
++def make_interpreted_test(self):
++ for x in['test_scripts_source','test_scripts_template']:
++ if not hasattr(self,x):
++ Logs.warn('a test_scripts taskgen i missing %s'%x)
++ return
++ self.ut_run,lst=Task.compile_fun(self.test_scripts_template,shell=getattr(self,'test_scripts_shell',False))
++ script_nodes=self.to_nodes(self.test_scripts_source)
++ for script_node in script_nodes:
++ tsk=self.create_task('utest',[script_node])
++ tsk.vars=lst+tsk.vars
++ tsk.env['SCRIPT']=script_node.path_from(tsk.get_cwd())
++ self.handle_ut_cwd('test_scripts_cwd')
++ env=getattr(self,'test_scripts_env',None)
++ if env:
++ self.ut_env=env
++ else:
++ self.ut_env=dict(os.environ)
++ paths=getattr(self,'test_scripts_paths',{})
++ for(k,v)in paths.items():
++ p=self.ut_env.get(k,'').split(os.pathsep)
++ if isinstance(v,str):
++ v=v.split(os.pathsep)
++ self.ut_env[k]=os.pathsep.join(p+v)
+@feature('test')
+@after_method('apply_link','process_use')
+def make_test(self):
@@ -12370,14 +12838,7 @@ Last-Update: 2017-07-19
+ if getattr(self,'ut_str',None):
+ self.ut_run,lst=Task.compile_fun(self.ut_str,shell=getattr(self,'ut_shell',False))
+ tsk.vars=lst+tsk.vars
-+ if getattr(self,'ut_cwd',None):
-+ if isinstance(self.ut_cwd,str):
-+ if os.path.isabs(self.ut_cwd):
-+ self.ut_cwd=self.bld.root.make_node(self.ut_cwd)
-+ else:
-+ self.ut_cwd=self.path.make_node(self.ut_cwd)
-+ else:
-+ self.ut_cwd=tsk.inputs[0].parent
++ self.handle_ut_cwd('ut_cwd')
+ if not hasattr(self,'ut_paths'):
+ paths=[]
+ for x in self.tmp_use_sorted:
@@ -12400,14 +12861,20 @@ Last-Update: 2017-07-19
+ add_path('LD_LIBRARY_PATH')
+ else:
+ add_path('LD_LIBRARY_PATH')
++ if not hasattr(self,'ut_cmd'):
++ self.ut_cmd=getattr(Options.options,'testcmd',False)
+@taskgen_method
+def add_test_results(self,tup):
+ Logs.debug("ut: %r",tup)
-+ self.utest_result=tup
++ try:
++ self.utest_results.append(tup)
++ except AttributeError:
++ self.utest_results=[tup]
+ try:
+ self.bld.utest_results.append(tup)
+ except AttributeError:
+ self.bld.utest_results=[tup]
++@Task.deep_inputs
+class utest(Task.Task):
+ color='PINK'
+ after=['vnum','inst']
@@ -12430,23 +12897,20 @@ Last-Update: 2017-07-19
+ if hasattr(self.generator,'ut_run'):
+ return self.generator.ut_run(self)
+ self.ut_exec=getattr(self.generator,'ut_exec',[self.inputs[0].abspath()])
-+ if getattr(self.generator,'ut_fun',None):
-+ self.generator.ut_fun(self)
-+ testcmd=getattr(self.generator,'ut_cmd',False)or getattr(Options.options,'testcmd',False)
-+ if testcmd:
-+ self.ut_exec=(testcmd%' '.join(self.ut_exec)).split(' ')
++ ut_cmd=getattr(self.generator,'ut_cmd',False)
++ if ut_cmd:
++ self.ut_exec=shlex.split(ut_cmd%' '.join(self.ut_exec))
+ return self.exec_command(self.ut_exec)
+ def exec_command(self,cmd,**kw):
+ Logs.debug('runner: %r',cmd)
+ if getattr(Options.options,'dump_test_scripts',False):
-+ global SCRIPT_TEMPLATE
+ script_code=SCRIPT_TEMPLATE%{'python':sys.executable,'env':self.get_test_env(),'cwd':self.get_cwd().abspath(),'cmd':cmd}
+ script_file=self.inputs[0].abspath()+'_run.py'
+ Utils.writef(script_file,script_code)
+ os.chmod(script_file,Utils.O755)
+ if Logs.verbose>1:
+ Logs.info('Test debug file written as %r'%script_file)
-+ proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
++ proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,shell=isinstance(cmd,str))
+ (stdout,stderr)=proc.communicate()
+ self.waf_unit_test_results=tup=(self.inputs[0].abspath(),proc.returncode,stdout,stderr)
+ testlock.acquire()
@@ -12455,21 +12919,21 @@ Last-Update: 2017-07-19
+ finally:
+ testlock.release()
+ def get_cwd(self):
-+ return self.generator.ut_cwd
++ return getattr(self.generator,'ut_cwd',self.inputs[0].parent)
+def summary(bld):
+ lst=getattr(bld,'utest_results',[])
+ if lst:
+ Logs.pprint('CYAN','execution summary')
+ total=len(lst)
+ tfail=len([x for x in lst if x[1]])
-+ Logs.pprint('CYAN',' tests that pass %d/%d'%(total-tfail,total))
++ Logs.pprint('GREEN',' tests that pass %d/%d'%(total-tfail,total))
+ for(f,code,out,err)in lst:
+ if not code:
-+ Logs.pprint('CYAN',' %s'%f)
-+ Logs.pprint('CYAN',' tests that fail %d/%d'%(tfail,total))
++ Logs.pprint('GREEN',' %s'%f)
++ Logs.pprint('GREEN'if tfail==0 else'RED',' tests that fail %d/%d'%(tfail,total))
+ for(f,code,out,err)in lst:
+ if code:
-+ Logs.pprint('CYAN',' %s'%f)
++ Logs.pprint('RED',' %s'%f)
+def set_exit_code(bld):
+ lst=getattr(bld,'utest_results',[])
+ for(f,code,out,err)in lst:
@@ -12484,11 +12948,11 @@ Last-Update: 2017-07-19
+ opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
+ opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
+ opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests')
-+ opt.add_option('--testcmd',action='store',default=False,help='Run the unit tests using the test-cmd string'' example "--test-cmd="valgrind --error-exitcode=1'' %s" to run under valgrind',dest='testcmd')
++ opt.add_option('--testcmd',action='store',default=False,dest='testcmd',help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind')
+ opt.add_option('--dump-test-scripts',action='store_true',default=False,help='Create python scripts to help debug tests',dest='dump_test_scripts')
--- /dev/null
+++ b/waflib/Tools/winres.py
-@@ -0,0 +1,51 @@
+@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -12512,7 +12976,8 @@ Last-Update: 2017-07-19
+ def filter_comments(self,node):
+ code=node.read()
+ if c_preproc.use_trigraphs:
-+ for(a,b)in c_preproc.trig_def:code=code.split(a).join(b)
++ for(a,b)in c_preproc.trig_def:
++ code=code.split(a).join(b)
+ code=c_preproc.re_nl.sub('',code)
+ code=c_preproc.re_cpp.sub(c_preproc.repl,code)
+ ret=[]
@@ -12636,12 +13101,13 @@ Last-Update: 2017-07-19
+ conf.link_add_flags()
--- /dev/null
+++ b/waflib/Utils.py
-@@ -0,0 +1,597 @@
+@@ -0,0 +1,615 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
-+import atexit,os,sys,errno,traceback,inspect,re,datetime,platform,base64,signal,functools
++from __future__ import with_statement
++import atexit,os,sys,errno,inspect,re,datetime,platform,base64,signal,functools,time
+try:
+ import cPickle
+except ImportError:
@@ -12656,7 +13122,7 @@ Last-Update: 2017-07-19
+try:
+ TimeoutExpired=subprocess.TimeoutExpired
+except AttributeError:
-+ class TimeoutExpired(object):
++ class TimeoutExpired(Exception):
+ pass
+from collections import deque,defaultdict
+try:
@@ -12759,46 +13225,47 @@ Last-Update: 2017-07-19
+ node.key=key
+ node.val=val
+ self.table[key]=node
++class lazy_generator(object):
++ def __init__(self,fun,params):
++ self.fun=fun
++ self.params=params
++ def __iter__(self):
++ return self
++ def __next__(self):
++ try:
++ it=self.it
++ except AttributeError:
++ it=self.it=self.fun(*self.params)
++ return next(it)
++ next=__next__
+is_win32=os.sep=='\\'or sys.platform=='win32'
-+def readf(fname,m='r',encoding='ISO8859-1'):
++def readf(fname,m='r',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
-+ f=open(fname,m)
-+ try:
++ with open(fname,m)as f:
+ txt=f.read()
-+ finally:
-+ f.close()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
-+ f=open(fname,m)
-+ try:
++ with open(fname,m)as f:
+ txt=f.read()
-+ finally:
-+ f.close()
+ return txt
-+def writef(fname,data,m='w',encoding='ISO8859-1'):
++def writef(fname,data,m='w',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
-+ f=open(fname,m)
-+ try:
++ with open(fname,m)as f:
+ f.write(data)
-+ finally:
-+ f.close()
+def h_file(fname):
-+ f=open(fname,'rb')
+ m=md5()
-+ try:
++ with open(fname,'rb')as f:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
-+ finally:
-+ f.close()
+ return m.digest()
-+def readf_win32(f,m='r',encoding='ISO8859-1'):
++def readf_win32(f,m='r',encoding='latin-1'):
+ flags=os.O_NOINHERIT|os.O_RDONLY
+ if'b'in m:
+ flags|=os.O_BINARY
@@ -12810,23 +13277,17 @@ Last-Update: 2017-07-19
+ raise IOError('Cannot read from %r'%f)
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
-+ f=os.fdopen(fd,m)
-+ try:
++ with os.fdopen(fd,m)as f:
+ txt=f.read()
-+ finally:
-+ f.close()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
-+ f=os.fdopen(fd,m)
-+ try:
++ with os.fdopen(fd,m)as f:
+ txt=f.read()
-+ finally:
-+ f.close()
+ return txt
-+def writef_win32(f,data,m='w',encoding='ISO8859-1'):
++def writef_win32(f,data,m='w',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
@@ -12839,24 +13300,18 @@ Last-Update: 2017-07-19
+ fd=os.open(f,flags)
+ except OSError:
+ raise OSError('Cannot write to %r'%f)
-+ f=os.fdopen(fd,m)
-+ try:
++ with os.fdopen(fd,m)as f:
+ 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 OSError('Cannot read from %r'%fname)
-+ f=os.fdopen(fd,'rb')
+ m=md5()
-+ try:
++ with os.fdopen(fd,'rb')as f:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
-+ finally:
-+ f.close()
+ return m.digest()
+readf_unix=readf
+writef_unix=writef
@@ -12915,13 +13370,25 @@ Last-Update: 2017-07-19
+ ret+=256**(3-i)*int(ver[i])
+ return ret
+ return ver
-+def ex_stack():
-+ return traceback.format_exc()
+def to_list(val):
+ if isinstance(val,str):
+ return val.split()
+ else:
+ return val
++def console_encoding():
++ try:
++ import ctypes
++ except ImportError:
++ pass
++ else:
++ try:
++ codepage=ctypes.windll.kernel32.GetConsoleCP()
++ except AttributeError:
++ pass
++ else:
++ if codepage:
++ return'cp%d'%codepage
++ return sys.stdout.encoding or('cp1252'if is_win32 else'latin-1')
+def split_path_unix(path):
+ return path.split('/')
+def split_path_cygwin(path):
@@ -12933,16 +13400,18 @@ Last-Update: 2017-07-19
+re_sp=re.compile('[/\\\\]+')
+def split_path_win32(path):
+ if path.startswith('\\\\'):
-+ ret=re_sp.split(path)[2:]
-+ ret[0]='\\'+ret[0]
++ ret=re_sp.split(path)[1:]
++ ret[0]='\\\\'+ret[0]
++ if ret[0]=='\\\\?':
++ return ret[1:]
+ return ret
+ return re_sp.split(path)
+msysroot=None
+def split_path_msys(path):
-+ if path.startswith(('/','\\'))and not path.startswith(('\\','\\\\')):
++ if path.startswith(('/','\\'))and not path.startswith(('//','\\\\')):
+ global msysroot
+ if not msysroot:
-+ msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'iso8859-1')
++ msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'latin-1')
+ msysroot=msysroot.strip()
+ path=os.path.normpath(msysroot+os.sep+path)
+ return split_path_win32(path)
@@ -12994,6 +13463,11 @@ Last-Update: 2017-07-19
+ fu=re.sub('_+','_',fu)
+ fu=fu.upper()
+ return fu
++re_sh=re.compile('\\s|\'|"')
++def shell_escape(cmd):
++ if isinstance(cmd,str):
++ return cmd
++ return' '.join(repr(x)if re_sh.search(x)else x for x in cmd)
+def h_list(lst):
+ return md5(repr(lst).encode()).digest()
+def h_fun(fun):
@@ -13023,7 +13497,7 @@ Last-Update: 2017-07-19
+ else:
+ ret=str(h_fun(ins))
+ if sys.hexversion>0x3000000:
-+ ret=ret.encode('iso8859-1','xmlcharrefreplace')
++ ret=ret.encode('latin-1','xmlcharrefreplace')
+ return ret
+reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
+def subst_vars(expr,params):
@@ -13070,9 +13544,11 @@ Last-Update: 2017-07-19
+ pass
+class Timer(object):
+ def __init__(self):
-+ self.start_time=datetime.datetime.utcnow()
++ self.start_time=self.now()
+ def __str__(self):
-+ delta=datetime.datetime.utcnow()-self.start_time
++ delta=self.now()-self.start_time
++ if not isinstance(delta,datetime.timedelta):
++ delta=datetime.timedelta(seconds=delta)
+ days=delta.days
+ hours,rem=divmod(delta.seconds,3600)
+ minutes,seconds=divmod(rem,60)
@@ -13085,6 +13561,11 @@ Last-Update: 2017-07-19
+ if days or hours or minutes:
+ result+='%dm'%minutes
+ return'%s%.3fs'%(result,seconds)
++ def now(self):
++ return datetime.datetime.utcnow()
++ if hasattr(time,'perf_counter'):
++ def now(self):
++ return time.perf_counter()
+def read_la_file(path):
+ sp=re.compile(r'^([^=]+)=\'(.*)\'$')
+ dc={}
@@ -13112,7 +13593,7 @@ Last-Update: 2017-07-19
+ return None
+ try:
+ result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
-+ except WindowsError:
++ except OSError:
+ pass
+ else:
+ if os.path.isfile(result):
@@ -13138,7 +13619,7 @@ Last-Update: 2017-07-19
+ kwargs['env']=dict(os.environ)
+ try:
+ obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs]))
-+ except TypeError:
++ except(TypeError,AttributeError):
+ return run_regular_process(cmd,kwargs,cargs)
+ proc=get_process()
+ if not proc:
@@ -13150,7 +13631,9 @@ Last-Update: 2017-07-19
+ if not obj:
+ raise OSError('Preforked sub-process %r died'%proc.pid)
+ process_pool.append(proc)
-+ ret,out,err,ex,trace=cPickle.loads(base64.b64decode(obj))
++ lst=cPickle.loads(base64.b64decode(obj))
++ assert len(lst)==5
++ ret,out,err,ex,trace=lst
+ if ex:
+ if ex=='OSError':
+ raise OSError(trace)
@@ -13231,7 +13714,7 @@ Last-Update: 2017-07-19
+ k.wait()
+if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f:
+ atexit.register(atexit_pool)
-+if sys.platform=='cli'or not sys.executable:
++if os.environ.get('WAF_NO_PREFORK')or sys.platform=='cli'or not sys.executable:
+ run_process=run_regular_process
+ get_process=alloc_process_pool=nada
--- /dev/null
@@ -13491,7 +13974,7 @@ Last-Update: 2017-07-19
+
--- /dev/null
+++ b/waflib/extras/compat15.py
-@@ -0,0 +1,301 @@
+@@ -0,0 +1,305 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
@@ -13588,7 +14071,7 @@ Last-Update: 2017-07-19
+Options.OptionsContext.tool_options=Context.Context.load
+Options.Handler=Options.OptionsContext
+Task.simple_task_type=Task.task_type_from_func=Task.task_factory
-+Task.TaskBase.classes=Task.classes
++Task.Task.classes=Task.classes
+def setitem(self,key,value):
+ if key.startswith('CCFLAGS'):
+ key=key[1:]
@@ -13735,10 +14218,12 @@ Last-Update: 2017-07-19
+ lst=y.to_list(y.add_objects)
+ lst.reverse()
+ for u in lst:
-+ if u in seen:continue
++ if u in seen:
++ continue
+ added=1
+ names=[u]+names
-+ if added:continue
++ if added:
++ continue
+ y.post()
+ seen.append(x)
+ for t in getattr(y,'compiled_tasks',[]):
@@ -13752,8 +14237,10 @@ Last-Update: 2017-07-19
+ self.link_task.inputs.append(node)
+@TaskGen.taskgen_method
+def add_obj_file(self,file):
-+ if not hasattr(self,'obj_files'):self.obj_files=[]
-+ if not'process_obj_files'in self.meths:self.meths.append('process_obj_files')
++ if not hasattr(self,'obj_files'):
++ self.obj_files=[]
++ if not'process_obj_files'in self.meths:
++ self.meths.append('process_obj_files')
+ self.obj_files.append(file)
+old_define=Configure.ConfigurationContext.__dict__['define']
+@Configure.conf
@@ -13795,15 +14282,15 @@ Last-Update: 2017-07-19
+TaskGen.before=before
--- /dev/null
+++ b/waflib/fixpy2.py
-@@ -0,0 +1,54 @@
+@@ -0,0 +1,47 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
++from __future__ import with_statement
+import os
+all_modifs={}
+def fixdir(dir):
-+ global all_modifs
+ for k in all_modifs:
+ for v in all_modifs[k]:
+ modif(os.path.join(dir,'waflib'),k,v)
@@ -13818,20 +14305,13 @@ Last-Update: 2017-07-19
+ modif(dir,x,fun)
+ return
+ filename=os.path.join(dir,name)
-+ f=open(filename,'r')
-+ try:
++ with open(filename,'r')as f:
+ txt=f.read()
-+ finally:
-+ f.close()
+ txt=fun(txt)
-+ f=open(filename,'w')
-+ try:
++ with open(filename,'w')as f:
+ f.write(txt)
-+ finally:
-+ f.close()
+def subst(*k):
+ def do_subst(fun):
-+ global all_modifs
+ for x in k:
+ try:
+ all_modifs[x].append(fun)
@@ -13842,7 +14322,7 @@ Last-Update: 2017-07-19
+@subst('*')
+def r1(code):
+ code=code.replace('as e:',',e:')
-+ code=code.replace(".decode(sys.stdout.encoding or'iso8859-1',errors='replace')",'')
++ code=code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')",'')
+ return code.replace('.encode()','')
+@subst('Runner.py')
+def r4(code):
@@ -13869,7 +14349,7 @@ Last-Update: 2017-07-19
+try:
+ TimeoutExpired=subprocess.TimeoutExpired
+except AttributeError:
-+ class TimeoutExpired(object):
++ class TimeoutExpired(Exception):
+ pass
+def run():
+ txt=sys.stdin.readline().strip()
diff --git a/debian/patches/05_add-keywords.patch b/debian/patches/05_add-keywords.patch
index 19f1627..91b0883 100644
--- a/debian/patches/05_add-keywords.patch
+++ b/debian/patches/05_add-keywords.patch
@@ -3,8 +3,8 @@ Author: Mateusz Łukasik <mati75@linuxmint.pl>
--- a/etc/mpv.desktop
+++ b/etc/mpv.desktop
-@@ -32,3 +32,4 @@ Terminal=false
+@@ -34,3 +34,4 @@ Terminal=false
Categories=AudioVideo;Audio;Video;Player;TV;
- MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;audio/x-vorbis+ogg;video/x-ogm+ogg;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;video/mp2t;audio/flac;audio/mp4;
+ MimeType=application/ogg;application/x-ogg;application/mxf;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/aiff;audio/x-aiff;audio/m4a;audio/x-m4a;application/x-extension-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/mpeg2;audio/mpeg3;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/musepack;audio/x-musepack;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg2;video/x-mpeg3;video/mp4v-es;video/x-m4v;video/mp4;application/x-extension-mp4;video/divx;video/vnd.divx;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;audio/x-ms-asf;application/vnd.ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/avi;video/x-flic;video/fli;video/x-flc;video/flv;video/x-flv;video/x-theora;video/x-theora+ogg;video/x-matroska;video/mkv;audio/x-matroska;application/x-matroska;video/webm;audio/webm;audio/vorbis;audio/x-vorbis;audio/x-vorbis+ogg;video/x-ogm;video/x-ogm+ogg;application/x-ogm;application/x-ogm-audio;application/x-ogm-video;application/x-shorten;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;audio/eac3;audio/amr-wb;video/mp2t;audio/flac;audio/mp4;application/x-mpegurl;video/vnd.mpegurl;application/vnd.apple.mpegurl;audio/x-pn-au;video/3gp;video/3gpp;video/3gpp2;audio/3gpp;audio/3gpp2;video/dv;audio/dv;audio/opus;audio/vnd.dts;audio/vnd.dts.hd;audio/x-adpcm;application/x-cue;audio/m3u;
X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb
+Keywords=mpv;media;player;video;audio;tv;
diff --git a/debian/patches/06_ffmpeg-abi.patch b/debian/patches/06_ffmpeg-abi.patch
index 41d0c88..0d17e77 100644
--- a/debian/patches/06_ffmpeg-abi.patch
+++ b/debian/patches/06_ffmpeg-abi.patch
@@ -8,13 +8,16 @@ Bug-Debian: https://bugs.debian.org/831537
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/player/main.c
+++ b/player/main.c
-@@ -428,18 +428,6 @@ int mp_initialize(struct MPContext *mpct
+@@ -381,21 +381,6 @@ int mp_initialize(struct MPContext *mpct
if (handle_help_options(mpctx))
- return -2;
+ return 1; // help
- if (!print_libav_versions(mp_null_log, 0)) {
- // Using mismatched libraries can be legitimate, but even then it's
- // a bad idea. We don't acknowledge its usefulness and stability.
+- // Distro maintainers who patch this out should be aware that mpv
+- // intentionally ignores ABI in some places where it's not possible to
+- // get by without violating it.
- print_libav_versions(mpctx->log, MSGL_FATAL);
- MP_FATAL(mpctx, "\nmpv was compiled against a different version of "
- "FFmpeg/Libav than the shared\nlibrary it is linked against. "
@@ -24,6 +27,6 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
- return -1;
- }
-
- if (!mpctx->playlist->first && !opts->player_idle_mode)
- return -3;
-
+ if (!mpctx->playlist->first && !opts->player_idle_mode) {
+ // nothing to play
+ mp_print_version(mpctx->log, true);