| #! /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) |