blob: 4e04239a7350291347ac6213ff3cad244ec102b8 [file] [log] [blame]
akmhoquefa8ee9b2014-03-14 09:06:24 -05001#! /usr/bin/env python
2# encoding: utf-8
3# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5import copy,re,os
6from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
7feats=Utils.defaultdict(set)
8class task_gen(object):
9 mappings={}
10 prec=Utils.defaultdict(list)
11 def __init__(self,*k,**kw):
12 self.source=''
13 self.target=''
14 self.meths=[]
15 self.prec=Utils.defaultdict(list)
16 self.mappings={}
17 self.features=[]
18 self.tasks=[]
19 if not'bld'in kw:
20 self.env=ConfigSet.ConfigSet()
21 self.idx=0
22 self.path=None
23 else:
24 self.bld=kw['bld']
25 self.env=self.bld.env.derive()
26 self.path=self.bld.path
27 try:
28 self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1
29 except AttributeError:
30 self.bld.idx={}
31 self.idx=self.bld.idx[id(self.path)]=1
32 for key,val in kw.items():
33 setattr(self,key,val)
34 def __str__(self):
35 return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
36 def __repr__(self):
37 lst=[]
38 for x in self.__dict__.keys():
39 if x not in['env','bld','compiled_tasks','tasks']:
40 lst.append("%s=%s"%(x,repr(getattr(self,x))))
41 return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
42 def get_name(self):
43 try:
44 return self._name
45 except AttributeError:
46 if isinstance(self.target,list):
47 lst=[str(x)for x in self.target]
48 name=self._name=','.join(lst)
49 else:
50 name=self._name=str(self.target)
51 return name
52 def set_name(self,name):
53 self._name=name
54 name=property(get_name,set_name)
55 def to_list(self,val):
56 if isinstance(val,str):return val.split()
57 else:return val
58 def post(self):
59 if getattr(self,'posted',None):
60 return False
61 self.posted=True
62 keys=set(self.meths)
63 self.features=Utils.to_list(self.features)
64 for x in self.features+['*']:
65 st=feats[x]
66 if not st:
67 if not x in Task.classes:
68 Logs.warn('feature %r does not exist - bind at least one method to it'%x)
69 keys.update(list(st))
70 prec={}
71 prec_tbl=self.prec or task_gen.prec
72 for x in prec_tbl:
73 if x in keys:
74 prec[x]=prec_tbl[x]
75 tmp=[]
76 for a in keys:
77 for x in prec.values():
78 if a in x:break
79 else:
80 tmp.append(a)
81 tmp.sort()
82 out=[]
83 while tmp:
84 e=tmp.pop()
85 if e in keys:out.append(e)
86 try:
87 nlst=prec[e]
88 except KeyError:
89 pass
90 else:
91 del prec[e]
92 for x in nlst:
93 for y in prec:
94 if x in prec[y]:
95 break
96 else:
97 tmp.append(x)
98 if prec:
99 raise Errors.WafError('Cycle detected in the method execution %r'%prec)
100 out.reverse()
101 self.meths=out
102 Logs.debug('task_gen: posting %s %d'%(self,id(self)))
103 for x in out:
104 try:
105 v=getattr(self,x)
106 except AttributeError:
107 raise Errors.WafError('%r is not a valid task generator method'%x)
108 Logs.debug('task_gen: -> %s (%d)'%(x,id(self)))
109 v()
110 Logs.debug('task_gen: posted %s'%self.name)
111 return True
112 def get_hook(self,node):
113 name=node.name
114 for k in self.mappings:
115 if name.endswith(k):
116 return self.mappings[k]
117 for k in task_gen.mappings:
118 if name.endswith(k):
119 return task_gen.mappings[k]
120 raise Errors.WafError("File %r has no mapping in %r (did you forget to load a waf tool?)"%(node,task_gen.mappings.keys()))
121 def create_task(self,name,src=None,tgt=None):
122 task=Task.classes[name](env=self.env.derive(),generator=self)
123 if src:
124 task.set_inputs(src)
125 if tgt:
126 task.set_outputs(tgt)
127 self.tasks.append(task)
128 return task
129 def clone(self,env):
130 newobj=self.bld()
131 for x in self.__dict__:
132 if x in['env','bld']:
133 continue
134 elif x in['path','features']:
135 setattr(newobj,x,getattr(self,x))
136 else:
137 setattr(newobj,x,copy.copy(getattr(self,x)))
138 newobj.posted=False
139 if isinstance(env,str):
140 newobj.env=self.bld.all_envs[env].derive()
141 else:
142 newobj.env=env.derive()
143 return newobj
144def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False):
145 ext_in=Utils.to_list(ext_in)
146 ext_out=Utils.to_list(ext_out)
147 if not name:
148 name=rule
149 cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
150 def x_file(self,node):
151 ext=decider and decider(self,node)or cls.ext_out
152 if ext_in:
153 _ext_in=ext_in[0]
154 tsk=self.create_task(name,node)
155 cnt=0
156 keys=list(self.mappings.keys())+list(self.__class__.mappings.keys())
157 for x in ext:
158 k=node.change_ext(x,ext_in=_ext_in)
159 tsk.outputs.append(k)
160 if reentrant!=None:
161 if cnt<int(reentrant):
162 self.source.append(k)
163 else:
164 for y in keys:
165 if k.name.endswith(y):
166 self.source.append(k)
167 break
168 cnt+=1
169 if install_path:
170 self.bld.install_files(install_path,tsk.outputs)
171 return tsk
172 for x in cls.ext_in:
173 task_gen.mappings[x]=x_file
174 return x_file
175def taskgen_method(func):
176 setattr(task_gen,func.__name__,func)
177 return func
178def feature(*k):
179 def deco(func):
180 setattr(task_gen,func.__name__,func)
181 for name in k:
182 feats[name].update([func.__name__])
183 return func
184 return deco
185def before_method(*k):
186 def deco(func):
187 setattr(task_gen,func.__name__,func)
188 for fun_name in k:
189 if not func.__name__ in task_gen.prec[fun_name]:
190 task_gen.prec[fun_name].append(func.__name__)
191 return func
192 return deco
193before=before_method
194def after_method(*k):
195 def deco(func):
196 setattr(task_gen,func.__name__,func)
197 for fun_name in k:
198 if not fun_name in task_gen.prec[func.__name__]:
199 task_gen.prec[func.__name__].append(fun_name)
200 return func
201 return deco
202after=after_method
203def extension(*k):
204 def deco(func):
205 setattr(task_gen,func.__name__,func)
206 for x in k:
207 task_gen.mappings[x]=func
208 return func
209 return deco
210@taskgen_method
211def to_nodes(self,lst,path=None):
212 tmp=[]
213 path=path or self.path
214 find=path.find_resource
215 if isinstance(lst,self.path.__class__):
216 lst=[lst]
217 for x in Utils.to_list(lst):
218 if isinstance(x,str):
219 node=find(x)
220 else:
221 node=x
222 if not node:
223 raise Errors.WafError("source not found: %r in %r"%(x,self))
224 tmp.append(node)
225 return tmp
226@feature('*')
227def process_source(self):
228 self.source=self.to_nodes(getattr(self,'source',[]))
229 for node in self.source:
230 self.get_hook(node)(self,node)
231@feature('*')
232@before_method('process_source')
233def process_rule(self):
234 if not getattr(self,'rule',None):
235 return
236 name=str(getattr(self,'name',None)or self.target or getattr(self.rule,'__name__',self.rule))
237 try:
238 cache=self.bld.cache_rule_attr
239 except AttributeError:
240 cache=self.bld.cache_rule_attr={}
241 cls=None
242 if getattr(self,'cache_rule','True'):
243 try:
244 cls=cache[(name,self.rule)]
245 except KeyError:
246 pass
247 if not cls:
248 cls=Task.task_factory(name,self.rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE'),scan=getattr(self,'scan',None))
249 if getattr(self,'scan',None):
250 cls.scan=self.scan
251 elif getattr(self,'deps',None):
252 def scan(self):
253 nodes=[]
254 for x in self.generator.to_list(getattr(self.generator,'deps',None)):
255 node=self.generator.path.find_resource(x)
256 if not node:
257 self.generator.bld.fatal('Could not find %r (was it declared?)'%x)
258 nodes.append(node)
259 return[nodes,[]]
260 cls.scan=scan
261 if getattr(self,'update_outputs',None):
262 Task.update_outputs(cls)
263 if getattr(self,'always',None):
264 Task.always_run(cls)
265 for x in['after','before','ext_in','ext_out']:
266 setattr(cls,x,getattr(self,x,[]))
267 if getattr(self,'cache_rule','True'):
268 cache[(name,self.rule)]=cls
269 tsk=self.create_task(name)
270 if getattr(self,'target',None):
271 if isinstance(self.target,str):
272 self.target=self.target.split()
273 if not isinstance(self.target,list):
274 self.target=[self.target]
275 for x in self.target:
276 if isinstance(x,str):
277 tsk.outputs.append(self.path.find_or_declare(x))
278 else:
279 x.parent.mkdir()
280 tsk.outputs.append(x)
281 if getattr(self,'install_path',None):
282 self.bld.install_files(self.install_path,tsk.outputs)
283 if getattr(self,'source',None):
284 tsk.inputs=self.to_nodes(self.source)
285 self.source=[]
286 if getattr(self,'cwd',None):
287 tsk.cwd=self.cwd
288@feature('seq')
289def sequence_order(self):
290 if self.meths and self.meths[-1]!='sequence_order':
291 self.meths.append('sequence_order')
292 return
293 if getattr(self,'seq_start',None):
294 return
295 if getattr(self.bld,'prev',None):
296 self.bld.prev.post()
297 for x in self.bld.prev.tasks:
298 for y in self.tasks:
299 y.set_run_after(x)
300 self.bld.prev=self
301re_m4=re.compile('@(\w+)@',re.M)
302class subst_pc(Task.Task):
303 def run(self):
304 if getattr(self.generator,'is_copy',None):
305 self.outputs[0].write(self.inputs[0].read('rb'),'wb')
306 if getattr(self.generator,'chmod',None):
307 os.chmod(self.outputs[0].abspath(),self.generator.chmod)
308 return None
309 if getattr(self.generator,'fun',None):
310 self.generator.fun(self)
311 code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','ISO8859-1'))
312 if getattr(self.generator,'subst_fun',None):
313 code=self.generator.subst_fun(self,code)
314 if code:
315 self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
316 return
317 code=code.replace('%','%%')
318 lst=[]
319 def repl(match):
320 g=match.group
321 if g(1):
322 lst.append(g(1))
323 return"%%(%s)s"%g(1)
324 return''
325 code=re_m4.sub(repl,code)
326 try:
327 d=self.generator.dct
328 except AttributeError:
329 d={}
330 for x in lst:
331 tmp=getattr(self.generator,x,'')or self.env.get_flat(x)or self.env.get_flat(x.upper())
332 d[x]=str(tmp)
333 code=code%d
334 self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
335 self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst
336 try:delattr(self,'cache_sig')
337 except AttributeError:pass
338 if getattr(self.generator,'chmod',None):
339 os.chmod(self.outputs[0].abspath(),self.generator.chmod)
340 def sig_vars(self):
341 bld=self.generator.bld
342 env=self.env
343 upd=self.m.update
344 if getattr(self.generator,'fun',None):
345 upd(Utils.h_fun(self.generator.fun))
346 if getattr(self.generator,'subst_fun',None):
347 upd(Utils.h_fun(self.generator.subst_fun))
348 vars=self.generator.bld.raw_deps.get(self.uid(),[])
349 act_sig=bld.hash_env_vars(env,vars)
350 upd(act_sig)
351 lst=[getattr(self.generator,x,'')for x in vars]
352 upd(Utils.h_list(lst))
353 return self.m.digest()
354@extension('.pc.in')
355def add_pcfile(self,node):
356 tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
357 self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs)
358class subst(subst_pc):
359 pass
360@feature('subst')
361@before_method('process_source','process_rule')
362def process_subst(self):
363 src=Utils.to_list(getattr(self,'source',[]))
364 if isinstance(src,Node.Node):
365 src=[src]
366 tgt=Utils.to_list(getattr(self,'target',[]))
367 if isinstance(tgt,Node.Node):
368 tgt=[tgt]
369 if len(src)!=len(tgt):
370 raise Errors.WafError('invalid number of source/target for %r'%self)
371 for x,y in zip(src,tgt):
372 if not x or not y:
373 raise Errors.WafError('null source or target for %r'%self)
374 a,b=None,None
375 if isinstance(x,str)and isinstance(y,str)and x==y:
376 a=self.path.find_node(x)
377 b=self.path.get_bld().make_node(y)
378 if not os.path.isfile(b.abspath()):
379 b.sig=None
380 b.parent.mkdir()
381 else:
382 if isinstance(x,str):
383 a=self.path.find_resource(x)
384 elif isinstance(x,Node.Node):
385 a=x
386 if isinstance(y,str):
387 b=self.path.find_or_declare(y)
388 elif isinstance(y,Node.Node):
389 b=y
390 if not a:
391 raise Errors.WafError('cound not find %r for %r'%(x,self))
392 has_constraints=False
393 tsk=self.create_task('subst',a,b)
394 for k in('after','before','ext_in','ext_out'):
395 val=getattr(self,k,None)
396 if val:
397 has_constraints=True
398 setattr(tsk,k,val)
399 if not has_constraints and b.name.endswith('.h'):
400 tsk.before=[k for k in('c','cxx')if k in Task.classes]
401 inst_to=getattr(self,'install_path',None)
402 if inst_to:
403 self.bld.install_files(inst_to,b,chmod=getattr(self,'chmod',Utils.O644))
404 self.source=[]