--- /dev/null
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,errno,re,shutil
+try:
+ import cPickle
+except ImportError:
+ import pickle as cPickle
+from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
+import waflib.Node
+CACHE_DIR='c4che'
+CACHE_SUFFIX='_cache.py'
+INSTALL=1337
+UNINSTALL=-1337
+SAVED_ATTRS='root node_deps raw_deps task_sigs'.split()
+CFG_FILES='cfg_files'
+POST_AT_ONCE=0
+POST_LAZY=1
+POST_BOTH=2
+class BuildContext(Context.Context):
+ '''executes the build'''
+ cmd='build'
+ variant=''
+ def __init__(self,**kw):
+ super(BuildContext,self).__init__(**kw)
+ self.is_install=0
+ self.top_dir=kw.get('top_dir',Context.top_dir)
+ self.run_dir=kw.get('run_dir',Context.run_dir)
+ self.post_mode=POST_AT_ONCE
+ self.out_dir=kw.get('out_dir',Context.out_dir)
+ self.cache_dir=kw.get('cache_dir',None)
+ if not self.cache_dir:
+ self.cache_dir=self.out_dir+os.sep+CACHE_DIR
+ self.all_envs={}
+ self.task_sigs={}
+ self.node_deps={}
+ self.raw_deps={}
+ self.cache_dir_contents={}
+ self.task_gen_cache_names={}
+ self.launch_dir=Context.launch_dir
+ self.jobs=Options.options.jobs
+ self.targets=Options.options.targets
+ self.keep=Options.options.keep
+ self.cache_global=Options.cache_global
+ self.nocache=Options.options.nocache
+ self.progress_bar=Options.options.progress_bar
+ self.deps_man=Utils.defaultdict(list)
+ self.current_group=0
+ self.groups=[]
+ self.group_names={}
+ def get_variant_dir(self):
+ if not self.variant:
+ return self.out_dir
+ return os.path.join(self.out_dir,self.variant)
+ variant_dir=property(get_variant_dir,None)
+ def __call__(self,*k,**kw):
+ kw['bld']=self
+ ret=TaskGen.task_gen(*k,**kw)
+ self.task_gen_cache_names={}
+ self.add_to_group(ret,group=kw.get('group',None))
+ 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 are not supposed to be copied')
+ def install_files(self,*k,**kw):
+ pass
+ def install_as(self,*k,**kw):
+ pass
+ def symlink_as(self,*k,**kw):
+ pass
+ def load_envs(self):
+ node=self.root.find_node(self.cache_dir)
+ if not node:
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True)
+ if not lst:
+ raise Errors.WafError('The cache directory is empty: reconfigure the project')
+ for x in lst:
+ name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/')
+ env=ConfigSet.ConfigSet(x.abspath())
+ self.all_envs[name]=env
+ for f in env[CFG_FILES]:
+ newnode=self.root.find_resource(f)
+ try:
+ h=Utils.h_file(newnode.abspath())
+ except(IOError,AttributeError):
+ Logs.error('cannot find %r'%f)
+ h=Utils.SIG_NIL
+ newnode.sig=h
+ def init_dirs(self):
+ if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ self.path=self.srcnode=self.root.find_dir(self.top_dir)
+ self.bldnode=self.root.make_node(self.variant_dir)
+ self.bldnode.mkdir()
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.execute_build()
+ def execute_build(self):
+ Logs.info("Waf: Entering directory `%s'"%self.variant_dir)
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ if self.progress_bar:
+ sys.stderr.write(Logs.colors.cursor_off)
+ try:
+ self.compile()
+ finally:
+ if self.progress_bar==1:
+ c=len(self.returned_tasks)or 1
+ self.to_log(self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL))
+ print('')
+ sys.stdout.flush()
+ sys.stderr.write(Logs.colors.cursor_on)
+ Logs.info("Waf: Leaving directory `%s'"%self.variant_dir)
+ self.post_build()
+ def restore(self):
+ try:
+ env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
+ except(IOError,OSError):
+ pass
+ else:
+ if env['version']<Context.HEXVERSION:
+ raise Errors.WafError('Version mismatch! reconfigure the project')
+ for t in env['tools']:
+ self.setup(**t)
+ dbfn=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ data=Utils.readf(dbfn,'rb')
+ except(IOError,EOFError):
+ Logs.debug('build: Could not load the build cache %s (missing)'%dbfn)
+ else:
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ try:
+ data=cPickle.loads(data)
+ except Exception ,e:
+ Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e))
+ else:
+ for x in SAVED_ATTRS:
+ setattr(self,x,data[x])
+ finally:
+ waflib.Node.pickle_lock.release()
+ self.init_dirs()
+ def store(self):
+ data={}
+ for x in SAVED_ATTRS:
+ data[x]=getattr(self,x)
+ db=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ x=cPickle.dumps(data,-1)
+ finally:
+ waflib.Node.pickle_lock.release()
+ Utils.writef(db+'.tmp',x,m='wb')
+ try:
+ st=os.stat(db)
+ os.remove(db)
+ if not Utils.is_win32:
+ os.chown(db+'.tmp',st.st_uid,st.st_gid)
+ except(AttributeError,OSError):
+ pass
+ os.rename(db+'.tmp',db)
+ def compile(self):
+ Logs.debug('build: compile()')
+ self.producer=Runner.Parallel(self,self.jobs)
+ self.producer.biter=self.get_build_iterator()
+ self.returned_tasks=[]
+ try:
+ self.producer.start()
+ except KeyboardInterrupt:
+ self.store()
+ raise
+ else:
+ if self.producer.dirty:
+ self.store()
+ if self.producer.error:
+ raise Errors.BuildError(self.producer.error)
+ def setup(self,tool,tooldir=None,funs=None):
+ if isinstance(tool,list):
+ for i in tool:self.setup(i,tooldir)
+ return
+ module=Context.load_tool(tool,tooldir)
+ if hasattr(module,"setup"):module.setup(self)
+ def get_env(self):
+ try:
+ return self.all_envs[self.variant]
+ except KeyError:
+ return self.all_envs['']
+ def set_env(self,val):
+ self.all_envs[self.variant]=val
+ env=property(get_env,set_env)
+ def add_manual_dependency(self,path,value):
+ if path is None:
+ raise ValueError('Invalid input')
+ if isinstance(path,waflib.Node.Node):
+ node=path
+ elif os.path.isabs(path):
+ node=self.root.find_resource(path)
+ else:
+ node=self.path.find_resource(path)
+ if isinstance(value,list):
+ self.deps_man[id(node)].extend(value)
+ else:
+ self.deps_man[id(node)].append(value)
+ def launch_node(self):
+ try:
+ return self.p_ln
+ except AttributeError:
+ self.p_ln=self.root.find_dir(self.launch_dir)
+ return self.p_ln
+ def hash_env_vars(self,env,vars_lst):
+ if not env.table:
+ env=env.parent
+ if not env:
+ return Utils.SIG_NIL
+ idx=str(id(env))+str(vars_lst)
+ try:
+ cache=self.cache_env
+ except AttributeError:
+ cache=self.cache_env={}
+ else:
+ try:
+ return self.cache_env[idx]
+ except KeyError:
+ pass
+ lst=[env[a]for a in vars_lst]
+ ret=Utils.h_list(lst)
+ Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
+ cache[idx]=ret
+ return ret
+ def get_tgen_by_name(self,name):
+ cache=self.task_gen_cache_names
+ if not cache:
+ for g in self.groups:
+ for tg in g:
+ try:
+ cache[tg.name]=tg
+ except AttributeError:
+ pass
+ try:
+ return cache[name]
+ except KeyError:
+ raise Errors.WafError('Could not find a task generator for the name %r'%name)
+ def progress_line(self,state,total,col1,col2):
+ n=len(str(total))
+ Utils.rot_idx+=1
+ ind=Utils.rot_chr[Utils.rot_idx%4]
+ pc=(100.*state)/total
+ eta=str(self.timer)
+ fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind)
+ left=fs%(state,total,col1,pc,col2)
+ right='][%s%s%s]'%(col1,eta,col2)
+ cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
+ if cols<7:cols=7
+ ratio=((cols*state)//total)-1
+ bar=('='*ratio+'>').ljust(cols)
+ msg=Utils.indicator%(left,bar,right)
+ return msg
+ def declare_chain(self,*k,**kw):
+ return TaskGen.declare_chain(*k,**kw)
+ def pre_build(self):
+ for m in getattr(self,'pre_funs',[]):
+ m(self)
+ def post_build(self):
+ for m in getattr(self,'post_funs',[]):
+ m(self)
+ def add_pre_fun(self,meth):
+ try:
+ self.pre_funs.append(meth)
+ except AttributeError:
+ self.pre_funs=[meth]
+ def add_post_fun(self,meth):
+ try:
+ self.post_funs.append(meth)
+ except AttributeError:
+ self.post_funs=[meth]
+ def get_group(self,x):
+ if not self.groups:
+ self.add_group()
+ if x is None:
+ return self.groups[self.current_group]
+ if x in self.group_names:
+ 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))
+ tgen.bld=self
+ self.get_group(group).append(tgen)
+ def get_group_name(self,g):
+ if not isinstance(g,list):
+ g=self.groups[g]
+ for x in self.group_names:
+ if id(self.group_names[x])==id(g):
+ return x
+ return''
+ def get_group_idx(self,tg):
+ se=id(tg)
+ for i in range(len(self.groups)):
+ for t in self.groups[i]:
+ if id(t)==se:
+ return i
+ return None
+ def add_group(self,name=None,move=True):
+ if name and name in self.group_names:
+ Logs.error('add_group: name %s already present'%name)
+ g=[]
+ self.group_names[name]=g
+ self.groups.append(g)
+ if move:
+ self.current_group=len(self.groups)-1
+ def set_group(self,idx):
+ if isinstance(idx,str):
+ g=self.group_names[idx]
+ for i in range(len(self.groups)):
+ if id(g)==id(self.groups[i]):
+ self.current_group=i
+ else:
+ self.current_group=idx
+ def total(self):
+ total=0
+ for group in self.groups:
+ for tg in group:
+ try:
+ total+=len(tg.tasks)
+ except AttributeError:
+ total+=1
+ return total
+ def get_targets(self):
+ to_post=[]
+ min_grp=0
+ for name in self.targets.split(','):
+ tg=self.get_tgen_by_name(name)
+ if not tg:
+ raise Errors.WafError('target %r does not exist'%name)
+ m=self.get_group_idx(tg)
+ if m>min_grp:
+ min_grp=m
+ to_post=[tg]
+ elif m==min_grp:
+ to_post.append(tg)
+ return(min_grp,to_post)
+ def get_all_task_gen(self):
+ lst=[]
+ for g in self.groups:
+ lst.extend(g)
+ return lst
+ def post_group(self):
+ if self.targets=='*':
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ 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()
+ else:
+ for tg in self._exact_tg:
+ tg.post()
+ else:
+ ln=self.launch_node()
+ if ln.is_child_of(self.bldnode):
+ Logs.warn('Building from the build directory, forcing --targets=*')
+ ln=self.srcnode
+ elif not ln.is_child_of(self.srcnode):
+ Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath()))
+ ln=self.srcnode
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ if tg.path.is_child_of(ln):
+ f()
+ def get_tasks_group(self,idx):
+ tasks=[]
+ for tg in self.groups[idx]:
+ try:
+ tasks.extend(tg.tasks)
+ except AttributeError:
+ 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):
+ self.post_group()
+ self.cur+=1
+ self.cur=0
+ while self.cur<len(self.groups):
+ if self.post_mode!=POST_AT_ONCE:
+ self.post_group()
+ tasks=self.get_tasks_group(self.cur)
+ Task.set_file_constraints(tasks)
+ Task.set_precedence_constraints(tasks)
+ self.cur_tasks=tasks
+ self.cur+=1
+ if not tasks:
+ continue
+ yield tasks
+ while 1:
+ yield[]
+class inst(Task.Task):
+ color='CYAN'
+ def uid(self):
+ lst=[self.dest,self.path]+self.source
+ return Utils.h_list(repr(lst))
+ def post(self):
+ buf=[]
+ for x in self.source:
+ if isinstance(x,waflib.Node.Node):
+ y=x
+ else:
+ y=self.path.find_resource(x)
+ if not y:
+ if Logs.verbose:
+ Logs.warn('Could not find %s immediately (may cause broken builds)'%x)
+ idx=self.generator.bld.get_group_idx(self)
+ for tg in self.generator.bld.groups[idx]:
+ if not isinstance(tg,inst)and id(tg)!=id(self):
+ tg.post()
+ y=self.path.find_resource(x)
+ if y:
+ break
+ else:
+ raise Errors.WafError('Could not find %r in %r'%(x,self.path))
+ buf.append(y)
+ self.inputs=buf
+ def runnable_status(self):
+ ret=super(inst,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ return Task.RUN_ME
+ return ret
+ def __str__(self):
+ return''
+ def run(self):
+ return self.generator.exec_task()
+ def get_install_path(self,destdir=True):
+ dest=Utils.subst_vars(self.dest,self.env)
+ dest=dest.replace('/',os.sep)
+ if destdir and Options.options.destdir:
+ dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
+ return dest
+ def exec_install_files(self):
+ destpath=self.get_install_path()
+ if not destpath:
+ raise Errors.WafError('unknown installation path %r'%self.generator)
+ for x,y in zip(self.source,self.inputs):
+ if self.relative_trick:
+ destfile=os.path.join(destpath,y.path_from(self.path))
+ else:
+ destfile=os.path.join(destpath,y.name)
+ self.generator.bld.do_install(y.abspath(),destfile,self.chmod)
+ def exec_install_as(self):
+ destfile=self.get_install_path()
+ self.generator.bld.do_install(self.inputs[0].abspath(),destfile,self.chmod)
+ def exec_symlink_as(self):
+ destfile=self.get_install_path()
+ src=self.link
+ if self.relative_trick:
+ src=os.path.relpath(src,os.path.dirname(destfile))
+ self.generator.bld.do_link(src,destfile)
+class InstallContext(BuildContext):
+ '''installs the targets on the system'''
+ cmd='install'
+ def __init__(self,**kw):
+ super(InstallContext,self).__init__(**kw)
+ self.uninstall=[]
+ self.is_install=INSTALL
+ def do_install(self,src,tgt,chmod=Utils.O644):
+ d,_=os.path.split(tgt)
+ if not d:
+ raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt))
+ Utils.check_dir(d)
+ srclbl=src.replace(self.srcnode.abspath()+os.sep,'')
+ if not Options.options.force:
+ try:
+ st1=os.stat(tgt)
+ st2=os.stat(src)
+ except OSError:
+ pass
+ else:
+ if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
+ if not self.progress_bar:
+ Logs.info('- install %s (from %s)'%(tgt,srclbl))
+ return False
+ if not self.progress_bar:
+ Logs.info('+ install %s (from %s)'%(tgt,srclbl))
+ try:
+ os.remove(tgt)
+ except OSError:
+ pass
+ try:
+ shutil.copy2(src,tgt)
+ os.chmod(tgt,chmod)
+ except IOError:
+ try:
+ os.stat(src)
+ except(OSError,IOError):
+ Logs.error('File %r does not exist'%src)
+ raise Errors.WafError('Could not install the file %r'%tgt)
+ def do_link(self,src,tgt):
+ d,_=os.path.split(tgt)
+ Utils.check_dir(d)
+ link=False
+ if not os.path.islink(tgt):
+ link=True
+ elif os.readlink(tgt)!=src:
+ link=True
+ if link:
+ try:os.remove(tgt)
+ except OSError:pass
+ if not self.progress_bar:
+ Logs.info('+ symlink %s (to %s)'%(tgt,src))
+ os.symlink(src,tgt)
+ else:
+ if not self.progress_bar:
+ Logs.info('- symlink %s (to %s)'%(tgt,src))
+ def run_task_now(self,tsk,postpone):
+ tsk.post()
+ if not postpone:
+ if tsk.runnable_status()==Task.ASK_LATER:
+ raise self.WafError('cannot post the task %r'%tsk)
+ tsk.run()
+ def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True):
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ if isinstance(files,waflib.Node.Node):
+ tsk.source=[files]
+ else:
+ tsk.source=Utils.to_list(files)
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_files
+ tsk.relative_trick=relative_trick
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True):
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ tsk.source=[srcfile]
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False):
+ if Utils.is_win32:
+ return
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.dest=dest
+ tsk.path=cwd or self.path
+ tsk.source=[]
+ tsk.link=src
+ tsk.relative_trick=relative_trick
+ tsk.exec_task=tsk.exec_symlink_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+class UninstallContext(InstallContext):
+ '''removes the targets installed'''
+ cmd='uninstall'
+ def __init__(self,**kw):
+ super(UninstallContext,self).__init__(**kw)
+ self.is_install=UNINSTALL
+ def do_install(self,src,tgt,chmod=Utils.O644):
+ if not self.progress_bar:
+ Logs.info('- remove %s'%tgt)
+ self.uninstall.append(tgt)
+ try:
+ os.remove(tgt)
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ if not getattr(self,'uninstall_error',None):
+ self.uninstall_error=True
+ Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
+ if Logs.verbose>1:
+ Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno))
+ while tgt:
+ tgt=os.path.dirname(tgt)
+ try:
+ os.rmdir(tgt)
+ except OSError:
+ break
+ def do_link(self,src,tgt):
+ try:
+ if not self.progress_bar:
+ Logs.info('- remove %s'%tgt)
+ os.remove(tgt)
+ except OSError:
+ pass
+ while tgt:
+ tgt=os.path.dirname(tgt)
+ try:
+ os.rmdir(tgt)
+ except OSError:
+ break
+ 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'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ try:
+ self.clean()
+ finally:
+ self.store()
+ def clean(self):
+ Logs.debug('build: clean called')
+ if self.bldnode!=self.srcnode:
+ lst=[]
+ for e in self.all_envs.values():
+ lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES])
+ for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True):
+ if n in lst:
+ continue
+ n.delete()
+ self.root.children={}
+ for v in'node_deps task_sigs raw_deps'.split():
+ setattr(self,v,{})
+class ListContext(BuildContext):
+ '''lists the targets to execute'''
+ cmd='list'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ for g in self.groups:
+ for tg in g:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ try:
+ self.get_tgen_by_name('')
+ except Exception:
+ pass
+ lst=list(self.task_gen_cache_names.keys())
+ lst.sort()
+ for k in lst:
+ Logs.pprint('GREEN',k)
+class StepContext(BuildContext):
+ '''executes tasks in a step-by-step fashion, for debugging'''
+ cmd='step'
+ def __init__(self,**kw):
+ super(StepContext,self).__init__(**kw)
+ self.files=Options.options.files
+ def compile(self):
+ if not self.files:
+ Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
+ BuildContext.compile(self)
+ return
+ targets=None
+ if self.targets and self.targets!='*':
+ targets=self.targets.split(',')
+ for g in self.groups:
+ for tg in g:
+ if targets and tg.name not in targets:
+ continue
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ for pat in self.files.split(','):
+ matcher=self.get_matcher(pat)
+ for tg in g:
+ if isinstance(tg,Task.TaskBase):
+ lst=[tg]
+ else:
+ lst=tg.tasks
+ for tsk in lst:
+ do_exec=False
+ for node in getattr(tsk,'inputs',[]):
+ if matcher(node,output=False):
+ do_exec=True
+ break
+ for node in getattr(tsk,'outputs',[]):
+ if matcher(node,output=True):
+ do_exec=True
+ break
+ if do_exec:
+ ret=tsk.run()
+ Logs.info('%s -> exit %r'%(str(tsk),ret))
+ def get_matcher(self,pat):
+ inn=True
+ out=True
+ if pat.startswith('in:'):
+ out=False
+ pat=pat.replace('in:','')
+ elif pat.startswith('out:'):
+ inn=False
+ pat=pat.replace('out:','')
+ anode=self.root.find_node(pat)
+ pattern=None
+ if not anode:
+ if not pat.startswith('^'):
+ pat='^.+?%s'%pat
+ if not pat.endswith('$'):
+ pat='%s$'%pat
+ pattern=re.compile(pat)
+ def match(node,output):
+ if output==True and not out:
+ return False
+ if output==False and not inn:
+ return False
+ if anode:
+ return anode==node
+ else:
+ return pattern.match(node.abspath())
+ return match
+BuildContext.store=Utils.nogc(BuildContext.store)
+BuildContext.restore=Utils.nogc(BuildContext.restore)