| #! /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 sys |
| if sys.hexversion < 0x020400f0: from sets import Set as set |
| import copy,re,os |
| from waflib import Task,Utils,Logs,Errors,ConfigSet |
| feats=Utils.defaultdict(set) |
| class task_gen(object): |
| mappings={} |
| prec=Utils.defaultdict(list) |
| def __init__(self,*k,**kw): |
| self.source='' |
| self.target='' |
| self.meths=[] |
| self.prec=Utils.defaultdict(list) |
| self.mappings={} |
| self.features=[] |
| self.tasks=[] |
| if not'bld'in kw: |
| self.env=ConfigSet.ConfigSet() |
| self.idx=0 |
| self.path=None |
| else: |
| self.bld=kw['bld'] |
| self.env=self.bld.env.derive() |
| self.path=self.bld.path |
| try: |
| self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1 |
| except AttributeError: |
| self.bld.idx={} |
| self.idx=self.bld.idx[id(self.path)]=1 |
| for key,val in kw.items(): |
| setattr(self,key,val) |
| def __str__(self): |
| return"<task_gen %r declared in %s>"%(self.name,self.path.abspath()) |
| def __repr__(self): |
| lst=[] |
| for x in self.__dict__.keys(): |
| if x not in['env','bld','compiled_tasks','tasks']: |
| lst.append("%s=%s"%(x,repr(getattr(self,x)))) |
| return"bld(%s) in %s"%(", ".join(lst),self.path.abspath()) |
| def get_name(self): |
| try: |
| return self._name |
| except AttributeError: |
| if isinstance(self.target,list): |
| lst=[str(x)for x in self.target] |
| name=self._name=','.join(lst) |
| else: |
| name=self._name=str(self.target) |
| return name |
| def set_name(self,name): |
| self._name=name |
| name=property(get_name,set_name) |
| def to_list(self,val): |
| if isinstance(val,str):return val.split() |
| else:return val |
| def post(self): |
| if getattr(self,'posted',None): |
| return False |
| self.posted=True |
| keys=set(self.meths) |
| self.features=Utils.to_list(self.features) |
| for x in self.features+['*']: |
| st=feats[x] |
| if not st: |
| if not x in Task.classes: |
| Logs.warn('feature %r does not exist - bind at least one method to it'%x) |
| keys.update(list(st)) |
| prec={} |
| prec_tbl=self.prec or task_gen.prec |
| for x in prec_tbl: |
| if x in keys: |
| prec[x]=prec_tbl[x] |
| tmp=[] |
| for a in keys: |
| for x in prec.values(): |
| if a in x:break |
| else: |
| tmp.append(a) |
| out=[] |
| while tmp: |
| e=tmp.pop() |
| if e in keys:out.append(e) |
| try: |
| nlst=prec[e] |
| except KeyError: |
| pass |
| else: |
| del prec[e] |
| for x in nlst: |
| for y in prec: |
| if x in prec[y]: |
| break |
| else: |
| tmp.append(x) |
| if prec: |
| raise Errors.WafError('Cycle detected in the method execution %r'%prec) |
| out.reverse() |
| self.meths=out |
| Logs.debug('task_gen: posting %s %d'%(self,id(self))) |
| for x in out: |
| try: |
| v=getattr(self,x) |
| except AttributeError: |
| raise Errors.WafError('%r is not a valid task generator method'%x) |
| Logs.debug('task_gen: -> %s (%d)'%(x,id(self))) |
| v() |
| Logs.debug('task_gen: posted %s'%self.name) |
| return True |
| def get_hook(self,node): |
| name=node.name |
| for k in self.mappings: |
| if name.endswith(k): |
| return self.mappings[k] |
| for k in task_gen.mappings: |
| if name.endswith(k): |
| return task_gen.mappings[k] |
| raise Errors.WafError("File %r has no mapping in %r (did you forget to load a waf tool?)"%(node,task_gen.mappings.keys())) |
| def create_task(self,name,src=None,tgt=None): |
| task=Task.classes[name](env=self.env.derive(),generator=self) |
| if src: |
| task.set_inputs(src) |
| if tgt: |
| task.set_outputs(tgt) |
| self.tasks.append(task) |
| return task |
| def clone(self,env): |
| newobj=self.bld() |
| for x in self.__dict__: |
| if x in['env','bld']: |
| continue |
| elif x in['path','features']: |
| setattr(newobj,x,getattr(self,x)) |
| else: |
| setattr(newobj,x,copy.copy(getattr(self,x))) |
| newobj.posted=False |
| if isinstance(env,str): |
| newobj.env=self.bld.all_envs[env].derive() |
| else: |
| newobj.env=env.derive() |
| return newobj |
| def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False): |
| ext_in=Utils.to_list(ext_in) |
| ext_out=Utils.to_list(ext_out) |
| if not name: |
| name=rule |
| cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell) |
| def x_file(self,node): |
| ext=decider and decider(self,node)or cls.ext_out |
| if ext_in: |
| _ext_in=ext_in[0] |
| tsk=self.create_task(name,node) |
| cnt=0 |
| keys=self.mappings.keys()+self.__class__.mappings.keys() |
| for x in ext: |
| k=node.change_ext(x,ext_in=_ext_in) |
| tsk.outputs.append(k) |
| if reentrant!=None: |
| if cnt<int(reentrant): |
| self.source.append(k) |
| else: |
| for y in keys: |
| if k.name.endswith(y): |
| self.source.append(k) |
| break |
| cnt+=1 |
| if install_path: |
| self.bld.install_files(install_path,tsk.outputs) |
| return tsk |
| for x in cls.ext_in: |
| task_gen.mappings[x]=x_file |
| return x_file |
| def taskgen_method(func): |
| setattr(task_gen,func.__name__,func) |
| return func |
| def feature(*k): |
| def deco(func): |
| setattr(task_gen,func.__name__,func) |
| for name in k: |
| feats[name].update([func.__name__]) |
| return func |
| return deco |
| def before_method(*k): |
| 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__) |
| return func |
| return deco |
| before=before_method |
| def after_method(*k): |
| 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) |
| return func |
| return deco |
| after=after_method |
| def extension(*k): |
| def deco(func): |
| setattr(task_gen,func.__name__,func) |
| for x in k: |
| task_gen.mappings[x]=func |
| return func |
| return deco |
| def to_nodes(self,lst,path=None): |
| tmp=[] |
| path=path or self.path |
| find=path.find_resource |
| if isinstance(lst,self.path.__class__): |
| lst=[lst] |
| for x in Utils.to_list(lst): |
| if isinstance(x,str): |
| node=find(x) |
| else: |
| node=x |
| if not node: |
| raise Errors.WafError("source not found: %r in %r"%(x,self)) |
| tmp.append(node) |
| return tmp |
| def process_source(self): |
| self.source=self.to_nodes(getattr(self,'source',[])) |
| for node in self.source: |
| self.get_hook(node)(self,node) |
| def process_rule(self): |
| if not getattr(self,'rule',None): |
| return |
| name=str(getattr(self,'name',None)or self.target or self.rule) |
| cls=Task.task_factory(name,self.rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE')) |
| tsk=self.create_task(name) |
| if getattr(self,'target',None): |
| if isinstance(self.target,str): |
| self.target=self.target.split() |
| if not isinstance(self.target,list): |
| self.target=[self.target] |
| for x in self.target: |
| if isinstance(x,str): |
| tsk.outputs.append(self.path.find_or_declare(x)) |
| else: |
| x.parent.mkdir() |
| tsk.outputs.append(x) |
| if getattr(self,'install_path',None): |
| self.bld.install_files(self.install_path,tsk.outputs) |
| if getattr(self,'source',None): |
| tsk.inputs=self.to_nodes(self.source) |
| self.source=[] |
| if getattr(self,'scan',None): |
| cls.scan=self.scan |
| elif getattr(self,'deps',None): |
| def scan(self): |
| nodes=[] |
| for x in self.generator.to_list(self.generator.deps): |
| node=self.generator.path.find_resource(x) |
| if not node: |
| self.generator.bld.fatal('Could not find %r (was it declared?)'%x) |
| nodes.append(node) |
| return[nodes,[]] |
| cls.scan=scan |
| if getattr(self,'cwd',None): |
| tsk.cwd=self.cwd |
| if getattr(self,'update_outputs',None)or getattr(self,'on_results',None): |
| Task.update_outputs(cls) |
| if getattr(self,'always',None): |
| Task.always_run(cls) |
| for x in['after','before','ext_in','ext_out']: |
| setattr(cls,x,getattr(self,x,[])) |
| def sequence_order(self): |
| if self.meths and self.meths[-1]!='sequence_order': |
| self.meths.append('sequence_order') |
| return |
| if getattr(self,'seq_start',None): |
| return |
| if getattr(self.bld,'prev',None): |
| self.bld.prev.post() |
| for x in self.bld.prev.tasks: |
| for y in self.tasks: |
| y.set_run_after(x) |
| self.bld.prev=self |
| re_m4=re.compile('@(\w+)@',re.M) |
| class subst_pc(Task.Task): |
| def run(self): |
| code=self.inputs[0].read() |
| code=code.replace('%','%%') |
| lst=[] |
| def repl(match): |
| g=match.group |
| if g(1): |
| lst.append(g(1)) |
| return"%%(%s)s"%g(1) |
| return'' |
| code=re_m4.sub(repl,code) |
| try: |
| d=self.generator.dct |
| except AttributeError: |
| d={} |
| for x in lst: |
| tmp=getattr(self.generator,x,'')or self.env.get_flat(x)or self.env.get_flat(x.upper()) |
| d[x]=str(tmp) |
| self.outputs[0].write(code%d) |
| self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst |
| try:delattr(self,'cache_sig') |
| except AttributeError:pass |
| if getattr(self.generator,'chmod',None): |
| os.chmod(self.outputs[0].abspath(),self.generator.chmod) |
| def sig_vars(self): |
| bld=self.generator.bld |
| env=self.env |
| upd=self.m.update |
| vars=self.generator.bld.raw_deps.get(self.uid(),[]) |
| act_sig=bld.hash_env_vars(env,vars) |
| upd(act_sig) |
| lst=[getattr(self.generator,x,'')for x in vars] |
| upd(Utils.h_list(lst)) |
| return self.m.digest() |
| def add_pcfile(self,node): |
| tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in')) |
| self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs) |
| class subst(subst_pc): |
| pass |
| def process_subst(self): |
| src=self.to_nodes(getattr(self,'source',[])) |
| tgt=getattr(self,'target',[]) |
| if isinstance(tgt,self.path.__class__): |
| tgt=[tgt] |
| tgt=[isinstance(x,self.path.__class__)and x or self.path.find_or_declare(x)for x in Utils.to_list(tgt)] |
| if len(src)!=len(tgt): |
| raise Errors.WafError('invalid source or target for %r'%self) |
| for x,y in zip(src,tgt): |
| if not(x and y): |
| raise Errors.WafError('invalid source or target for %r'%self) |
| tsk=self.create_task('subst',x,y) |
| for a in('after','before','ext_in','ext_out'): |
| val=getattr(self,a,None) |
| if val: |
| setattr(tsk,a,val) |
| inst_to=getattr(self,'install_path',None) |
| if inst_to: |
| self.bld.install_files(inst_to,tgt,chmod=getattr(self,'chmod',Utils.O644)) |
| self.source=[] |
| |
| taskgen_method(to_nodes) |
| feature('*')(process_source) |
| feature('*')(process_rule) |
| before_method('process_source')(process_rule) |
| feature('seq')(sequence_order) |
| extension('.pc.in')(add_pcfile) |
| feature('subst')(process_subst) |
| before_method('process_source','process_rule')(process_subst) |