1 | #! /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 | |
---|
5 | import os,sys,errno,re,shutil,stat |
---|
6 | try: |
---|
7 | import cPickle |
---|
8 | except ImportError: |
---|
9 | import pickle as cPickle |
---|
10 | from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors |
---|
11 | import waflib.Node |
---|
12 | CACHE_DIR='c4che' |
---|
13 | CACHE_SUFFIX='_cache.py' |
---|
14 | INSTALL=1337 |
---|
15 | UNINSTALL=-1337 |
---|
16 | SAVED_ATTRS='root node_deps raw_deps task_sigs'.split() |
---|
17 | CFG_FILES='cfg_files' |
---|
18 | POST_AT_ONCE=0 |
---|
19 | POST_LAZY=1 |
---|
20 | POST_BOTH=2 |
---|
21 | class BuildContext(Context.Context): |
---|
22 | '''executes the build''' |
---|
23 | cmd='build' |
---|
24 | variant='' |
---|
25 | def __init__(self,**kw): |
---|
26 | super(BuildContext,self).__init__(**kw) |
---|
27 | self.is_install=0 |
---|
28 | self.top_dir=kw.get('top_dir',Context.top_dir) |
---|
29 | self.run_dir=kw.get('run_dir',Context.run_dir) |
---|
30 | self.post_mode=POST_AT_ONCE |
---|
31 | self.out_dir=kw.get('out_dir',Context.out_dir) |
---|
32 | self.cache_dir=kw.get('cache_dir',None) |
---|
33 | if not self.cache_dir: |
---|
34 | self.cache_dir=os.path.join(self.out_dir,CACHE_DIR) |
---|
35 | self.all_envs={} |
---|
36 | self.task_sigs={} |
---|
37 | self.node_deps={} |
---|
38 | self.raw_deps={} |
---|
39 | self.cache_dir_contents={} |
---|
40 | self.task_gen_cache_names={} |
---|
41 | self.launch_dir=Context.launch_dir |
---|
42 | self.jobs=Options.options.jobs |
---|
43 | self.targets=Options.options.targets |
---|
44 | self.keep=Options.options.keep |
---|
45 | self.progress_bar=Options.options.progress_bar |
---|
46 | self.deps_man=Utils.defaultdict(list) |
---|
47 | self.current_group=0 |
---|
48 | self.groups=[] |
---|
49 | self.group_names={} |
---|
50 | def get_variant_dir(self): |
---|
51 | if not self.variant: |
---|
52 | return self.out_dir |
---|
53 | return os.path.join(self.out_dir,self.variant) |
---|
54 | variant_dir=property(get_variant_dir,None) |
---|
55 | def __call__(self,*k,**kw): |
---|
56 | kw['bld']=self |
---|
57 | ret=TaskGen.task_gen(*k,**kw) |
---|
58 | self.task_gen_cache_names={} |
---|
59 | self.add_to_group(ret,group=kw.get('group',None)) |
---|
60 | return ret |
---|
61 | def rule(self,*k,**kw): |
---|
62 | def f(rule): |
---|
63 | ret=self(*k,**kw) |
---|
64 | ret.rule=rule |
---|
65 | return ret |
---|
66 | return f |
---|
67 | def __copy__(self): |
---|
68 | raise Errors.WafError('build contexts are not supposed to be copied') |
---|
69 | def install_files(self,*k,**kw): |
---|
70 | pass |
---|
71 | def install_as(self,*k,**kw): |
---|
72 | pass |
---|
73 | def symlink_as(self,*k,**kw): |
---|
74 | pass |
---|
75 | def load_envs(self): |
---|
76 | node=self.root.find_node(self.cache_dir) |
---|
77 | if not node: |
---|
78 | raise Errors.WafError('The project was not configured: run "waf configure" first!') |
---|
79 | lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True) |
---|
80 | if not lst: |
---|
81 | raise Errors.WafError('The cache directory is empty: reconfigure the project') |
---|
82 | for x in lst: |
---|
83 | name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/') |
---|
84 | env=ConfigSet.ConfigSet(x.abspath()) |
---|
85 | self.all_envs[name]=env |
---|
86 | for f in env[CFG_FILES]: |
---|
87 | newnode=self.root.find_resource(f) |
---|
88 | try: |
---|
89 | h=Utils.h_file(newnode.abspath()) |
---|
90 | except(IOError,AttributeError): |
---|
91 | Logs.error('cannot find %r'%f) |
---|
92 | h=Utils.SIG_NIL |
---|
93 | newnode.sig=h |
---|
94 | def init_dirs(self): |
---|
95 | if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)): |
---|
96 | raise Errors.WafError('The project was not configured: run "waf configure" first!') |
---|
97 | self.path=self.srcnode=self.root.find_dir(self.top_dir) |
---|
98 | self.bldnode=self.root.make_node(self.variant_dir) |
---|
99 | self.bldnode.mkdir() |
---|
100 | def execute(self): |
---|
101 | self.restore() |
---|
102 | if not self.all_envs: |
---|
103 | self.load_envs() |
---|
104 | self.execute_build() |
---|
105 | def execute_build(self): |
---|
106 | Logs.info("Waf: Entering directory `%s'"%self.variant_dir) |
---|
107 | self.recurse([self.run_dir]) |
---|
108 | self.pre_build() |
---|
109 | self.timer=Utils.Timer() |
---|
110 | try: |
---|
111 | self.compile() |
---|
112 | finally: |
---|
113 | if self.progress_bar==1 and sys.stderr.isatty(): |
---|
114 | c=len(self.returned_tasks)or 1 |
---|
115 | m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL) |
---|
116 | Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on}) |
---|
117 | Logs.info("Waf: Leaving directory `%s'"%self.variant_dir) |
---|
118 | self.post_build() |
---|
119 | def restore(self): |
---|
120 | try: |
---|
121 | env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py')) |
---|
122 | except EnvironmentError: |
---|
123 | pass |
---|
124 | else: |
---|
125 | if env['version']<Context.HEXVERSION: |
---|
126 | raise Errors.WafError('Version mismatch! reconfigure the project') |
---|
127 | for t in env['tools']: |
---|
128 | self.setup(**t) |
---|
129 | dbfn=os.path.join(self.variant_dir,Context.DBFILE) |
---|
130 | try: |
---|
131 | data=Utils.readf(dbfn,'rb') |
---|
132 | except(IOError,EOFError): |
---|
133 | Logs.debug('build: Could not load the build cache %s (missing)'%dbfn) |
---|
134 | else: |
---|
135 | try: |
---|
136 | waflib.Node.pickle_lock.acquire() |
---|
137 | waflib.Node.Nod3=self.node_class |
---|
138 | try: |
---|
139 | data=cPickle.loads(data) |
---|
140 | except Exception ,e: |
---|
141 | Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e)) |
---|
142 | else: |
---|
143 | for x in SAVED_ATTRS: |
---|
144 | setattr(self,x,data[x]) |
---|
145 | finally: |
---|
146 | waflib.Node.pickle_lock.release() |
---|
147 | self.init_dirs() |
---|
148 | def store(self): |
---|
149 | data={} |
---|
150 | for x in SAVED_ATTRS: |
---|
151 | data[x]=getattr(self,x) |
---|
152 | db=os.path.join(self.variant_dir,Context.DBFILE) |
---|
153 | try: |
---|
154 | waflib.Node.pickle_lock.acquire() |
---|
155 | waflib.Node.Nod3=self.node_class |
---|
156 | x=cPickle.dumps(data,-1) |
---|
157 | finally: |
---|
158 | waflib.Node.pickle_lock.release() |
---|
159 | Utils.writef(db+'.tmp',x,m='wb') |
---|
160 | try: |
---|
161 | st=os.stat(db) |
---|
162 | os.remove(db) |
---|
163 | if not Utils.is_win32: |
---|
164 | os.chown(db+'.tmp',st.st_uid,st.st_gid) |
---|
165 | except(AttributeError,OSError): |
---|
166 | pass |
---|
167 | os.rename(db+'.tmp',db) |
---|
168 | def compile(self): |
---|
169 | Logs.debug('build: compile()') |
---|
170 | self.producer=Runner.Parallel(self,self.jobs) |
---|
171 | self.producer.biter=self.get_build_iterator() |
---|
172 | self.returned_tasks=[] |
---|
173 | try: |
---|
174 | self.producer.start() |
---|
175 | except KeyboardInterrupt: |
---|
176 | self.store() |
---|
177 | raise |
---|
178 | else: |
---|
179 | if self.producer.dirty: |
---|
180 | self.store() |
---|
181 | if self.producer.error: |
---|
182 | raise Errors.BuildError(self.producer.error) |
---|
183 | def setup(self,tool,tooldir=None,funs=None): |
---|
184 | if isinstance(tool,list): |
---|
185 | for i in tool:self.setup(i,tooldir) |
---|
186 | return |
---|
187 | module=Context.load_tool(tool,tooldir) |
---|
188 | if hasattr(module,"setup"):module.setup(self) |
---|
189 | def get_env(self): |
---|
190 | try: |
---|
191 | return self.all_envs[self.variant] |
---|
192 | except KeyError: |
---|
193 | return self.all_envs[''] |
---|
194 | def set_env(self,val): |
---|
195 | self.all_envs[self.variant]=val |
---|
196 | env=property(get_env,set_env) |
---|
197 | def add_manual_dependency(self,path,value): |
---|
198 | if path is None: |
---|
199 | raise ValueError('Invalid input') |
---|
200 | if isinstance(path,waflib.Node.Node): |
---|
201 | node=path |
---|
202 | elif os.path.isabs(path): |
---|
203 | node=self.root.find_resource(path) |
---|
204 | else: |
---|
205 | node=self.path.find_resource(path) |
---|
206 | if isinstance(value,list): |
---|
207 | self.deps_man[id(node)].extend(value) |
---|
208 | else: |
---|
209 | self.deps_man[id(node)].append(value) |
---|
210 | def launch_node(self): |
---|
211 | try: |
---|
212 | return self.p_ln |
---|
213 | except AttributeError: |
---|
214 | self.p_ln=self.root.find_dir(self.launch_dir) |
---|
215 | return self.p_ln |
---|
216 | def hash_env_vars(self,env,vars_lst): |
---|
217 | if not env.table: |
---|
218 | env=env.parent |
---|
219 | if not env: |
---|
220 | return Utils.SIG_NIL |
---|
221 | idx=str(id(env))+str(vars_lst) |
---|
222 | try: |
---|
223 | cache=self.cache_env |
---|
224 | except AttributeError: |
---|
225 | cache=self.cache_env={} |
---|
226 | else: |
---|
227 | try: |
---|
228 | return self.cache_env[idx] |
---|
229 | except KeyError: |
---|
230 | pass |
---|
231 | lst=[env[a]for a in vars_lst] |
---|
232 | ret=Utils.h_list(lst) |
---|
233 | Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst) |
---|
234 | cache[idx]=ret |
---|
235 | return ret |
---|
236 | def get_tgen_by_name(self,name): |
---|
237 | cache=self.task_gen_cache_names |
---|
238 | if not cache: |
---|
239 | for g in self.groups: |
---|
240 | for tg in g: |
---|
241 | try: |
---|
242 | cache[tg.name]=tg |
---|
243 | except AttributeError: |
---|
244 | pass |
---|
245 | try: |
---|
246 | return cache[name] |
---|
247 | except KeyError: |
---|
248 | raise Errors.WafError('Could not find a task generator for the name %r'%name) |
---|
249 | def progress_line(self,state,total,col1,col2): |
---|
250 | if not sys.stderr.isatty(): |
---|
251 | return'' |
---|
252 | n=len(str(total)) |
---|
253 | Utils.rot_idx+=1 |
---|
254 | ind=Utils.rot_chr[Utils.rot_idx%4] |
---|
255 | pc=(100.*state)/total |
---|
256 | eta=str(self.timer) |
---|
257 | fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind) |
---|
258 | left=fs%(state,total,col1,pc,col2) |
---|
259 | right='][%s%s%s]'%(col1,eta,col2) |
---|
260 | cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2) |
---|
261 | if cols<7:cols=7 |
---|
262 | ratio=((cols*state)//total)-1 |
---|
263 | bar=('='*ratio+'>').ljust(cols) |
---|
264 | msg=Logs.indicator%(left,bar,right) |
---|
265 | return msg |
---|
266 | def declare_chain(self,*k,**kw): |
---|
267 | return TaskGen.declare_chain(*k,**kw) |
---|
268 | def pre_build(self): |
---|
269 | for m in getattr(self,'pre_funs',[]): |
---|
270 | m(self) |
---|
271 | def post_build(self): |
---|
272 | for m in getattr(self,'post_funs',[]): |
---|
273 | m(self) |
---|
274 | def add_pre_fun(self,meth): |
---|
275 | try: |
---|
276 | self.pre_funs.append(meth) |
---|
277 | except AttributeError: |
---|
278 | self.pre_funs=[meth] |
---|
279 | def add_post_fun(self,meth): |
---|
280 | try: |
---|
281 | self.post_funs.append(meth) |
---|
282 | except AttributeError: |
---|
283 | self.post_funs=[meth] |
---|
284 | def get_group(self,x): |
---|
285 | if not self.groups: |
---|
286 | self.add_group() |
---|
287 | if x is None: |
---|
288 | return self.groups[self.current_group] |
---|
289 | if x in self.group_names: |
---|
290 | return self.group_names[x] |
---|
291 | return self.groups[x] |
---|
292 | def add_to_group(self,tgen,group=None): |
---|
293 | assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.TaskBase)) |
---|
294 | tgen.bld=self |
---|
295 | self.get_group(group).append(tgen) |
---|
296 | def get_group_name(self,g): |
---|
297 | if not isinstance(g,list): |
---|
298 | g=self.groups[g] |
---|
299 | for x in self.group_names: |
---|
300 | if id(self.group_names[x])==id(g): |
---|
301 | return x |
---|
302 | return'' |
---|
303 | def get_group_idx(self,tg): |
---|
304 | se=id(tg) |
---|
305 | for i in range(len(self.groups)): |
---|
306 | for t in self.groups[i]: |
---|
307 | if id(t)==se: |
---|
308 | return i |
---|
309 | return None |
---|
310 | def add_group(self,name=None,move=True): |
---|
311 | if name and name in self.group_names: |
---|
312 | Logs.error('add_group: name %s already present'%name) |
---|
313 | g=[] |
---|
314 | self.group_names[name]=g |
---|
315 | self.groups.append(g) |
---|
316 | if move: |
---|
317 | self.current_group=len(self.groups)-1 |
---|
318 | def set_group(self,idx): |
---|
319 | if isinstance(idx,str): |
---|
320 | g=self.group_names[idx] |
---|
321 | for i in range(len(self.groups)): |
---|
322 | if id(g)==id(self.groups[i]): |
---|
323 | self.current_group=i |
---|
324 | break |
---|
325 | else: |
---|
326 | self.current_group=idx |
---|
327 | def total(self): |
---|
328 | total=0 |
---|
329 | for group in self.groups: |
---|
330 | for tg in group: |
---|
331 | try: |
---|
332 | total+=len(tg.tasks) |
---|
333 | except AttributeError: |
---|
334 | total+=1 |
---|
335 | return total |
---|
336 | def get_targets(self): |
---|
337 | to_post=[] |
---|
338 | min_grp=0 |
---|
339 | for name in self.targets.split(','): |
---|
340 | tg=self.get_tgen_by_name(name) |
---|
341 | if not tg: |
---|
342 | raise Errors.WafError('target %r does not exist'%name) |
---|
343 | m=self.get_group_idx(tg) |
---|
344 | if m>min_grp: |
---|
345 | min_grp=m |
---|
346 | to_post=[tg] |
---|
347 | elif m==min_grp: |
---|
348 | to_post.append(tg) |
---|
349 | return(min_grp,to_post) |
---|
350 | def get_all_task_gen(self): |
---|
351 | lst=[] |
---|
352 | for g in self.groups: |
---|
353 | lst.extend(g) |
---|
354 | return lst |
---|
355 | def post_group(self): |
---|
356 | if self.targets=='*': |
---|
357 | for tg in self.groups[self.cur]: |
---|
358 | try: |
---|
359 | f=tg.post |
---|
360 | except AttributeError: |
---|
361 | pass |
---|
362 | else: |
---|
363 | f() |
---|
364 | elif self.targets: |
---|
365 | if self.cur<self._min_grp: |
---|
366 | for tg in self.groups[self.cur]: |
---|
367 | try: |
---|
368 | f=tg.post |
---|
369 | except AttributeError: |
---|
370 | pass |
---|
371 | else: |
---|
372 | f() |
---|
373 | else: |
---|
374 | for tg in self._exact_tg: |
---|
375 | tg.post() |
---|
376 | else: |
---|
377 | ln=self.launch_node() |
---|
378 | if ln.is_child_of(self.bldnode): |
---|
379 | Logs.warn('Building from the build directory, forcing --targets=*') |
---|
380 | ln=self.srcnode |
---|
381 | elif not ln.is_child_of(self.srcnode): |
---|
382 | Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath())) |
---|
383 | ln=self.srcnode |
---|
384 | for tg in self.groups[self.cur]: |
---|
385 | try: |
---|
386 | f=tg.post |
---|
387 | except AttributeError: |
---|
388 | pass |
---|
389 | else: |
---|
390 | if tg.path.is_child_of(ln): |
---|
391 | f() |
---|
392 | def get_tasks_group(self,idx): |
---|
393 | tasks=[] |
---|
394 | for tg in self.groups[idx]: |
---|
395 | try: |
---|
396 | tasks.extend(tg.tasks) |
---|
397 | except AttributeError: |
---|
398 | tasks.append(tg) |
---|
399 | return tasks |
---|
400 | def get_build_iterator(self): |
---|
401 | self.cur=0 |
---|
402 | if self.targets and self.targets!='*': |
---|
403 | (self._min_grp,self._exact_tg)=self.get_targets() |
---|
404 | global lazy_post |
---|
405 | if self.post_mode!=POST_LAZY: |
---|
406 | while self.cur<len(self.groups): |
---|
407 | self.post_group() |
---|
408 | self.cur+=1 |
---|
409 | self.cur=0 |
---|
410 | while self.cur<len(self.groups): |
---|
411 | if self.post_mode!=POST_AT_ONCE: |
---|
412 | self.post_group() |
---|
413 | tasks=self.get_tasks_group(self.cur) |
---|
414 | Task.set_file_constraints(tasks) |
---|
415 | Task.set_precedence_constraints(tasks) |
---|
416 | self.cur_tasks=tasks |
---|
417 | self.cur+=1 |
---|
418 | if not tasks: |
---|
419 | continue |
---|
420 | yield tasks |
---|
421 | while 1: |
---|
422 | yield[] |
---|
423 | class inst(Task.Task): |
---|
424 | color='CYAN' |
---|
425 | def uid(self): |
---|
426 | lst=[self.dest,self.path]+self.source |
---|
427 | return Utils.h_list(repr(lst)) |
---|
428 | def post(self): |
---|
429 | buf=[] |
---|
430 | for x in self.source: |
---|
431 | if isinstance(x,waflib.Node.Node): |
---|
432 | y=x |
---|
433 | else: |
---|
434 | y=self.path.find_resource(x) |
---|
435 | if not y: |
---|
436 | if Logs.verbose: |
---|
437 | Logs.warn('Could not find %s immediately (may cause broken builds)'%x) |
---|
438 | idx=self.generator.bld.get_group_idx(self) |
---|
439 | for tg in self.generator.bld.groups[idx]: |
---|
440 | if not isinstance(tg,inst)and id(tg)!=id(self): |
---|
441 | tg.post() |
---|
442 | y=self.path.find_resource(x) |
---|
443 | if y: |
---|
444 | break |
---|
445 | else: |
---|
446 | raise Errors.WafError('Could not find %r in %r'%(x,self.path)) |
---|
447 | buf.append(y) |
---|
448 | self.inputs=buf |
---|
449 | def runnable_status(self): |
---|
450 | ret=super(inst,self).runnable_status() |
---|
451 | if ret==Task.SKIP_ME: |
---|
452 | return Task.RUN_ME |
---|
453 | return ret |
---|
454 | def __str__(self): |
---|
455 | return'' |
---|
456 | def run(self): |
---|
457 | return self.generator.exec_task() |
---|
458 | def get_install_path(self,destdir=True): |
---|
459 | dest=Utils.subst_vars(self.dest,self.env) |
---|
460 | dest=dest.replace('/',os.sep) |
---|
461 | if destdir and Options.options.destdir: |
---|
462 | dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep)) |
---|
463 | return dest |
---|
464 | def exec_install_files(self): |
---|
465 | destpath=self.get_install_path() |
---|
466 | if not destpath: |
---|
467 | raise Errors.WafError('unknown installation path %r'%self.generator) |
---|
468 | for x,y in zip(self.source,self.inputs): |
---|
469 | if self.relative_trick: |
---|
470 | destfile=os.path.join(destpath,y.path_from(self.path)) |
---|
471 | else: |
---|
472 | destfile=os.path.join(destpath,y.name) |
---|
473 | self.generator.bld.do_install(y.abspath(),destfile,chmod=self.chmod,tsk=self) |
---|
474 | def exec_install_as(self): |
---|
475 | destfile=self.get_install_path() |
---|
476 | self.generator.bld.do_install(self.inputs[0].abspath(),destfile,chmod=self.chmod,tsk=self) |
---|
477 | def exec_symlink_as(self): |
---|
478 | destfile=self.get_install_path() |
---|
479 | src=self.link |
---|
480 | if self.relative_trick: |
---|
481 | src=os.path.relpath(src,os.path.dirname(destfile)) |
---|
482 | self.generator.bld.do_link(src,destfile,tsk=self) |
---|
483 | class InstallContext(BuildContext): |
---|
484 | '''installs the targets on the system''' |
---|
485 | cmd='install' |
---|
486 | def __init__(self,**kw): |
---|
487 | super(InstallContext,self).__init__(**kw) |
---|
488 | self.uninstall=[] |
---|
489 | self.is_install=INSTALL |
---|
490 | def copy_fun(self,src,tgt,**kw): |
---|
491 | if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'): |
---|
492 | tgt='\\\\?\\'+tgt |
---|
493 | shutil.copy2(src,tgt) |
---|
494 | os.chmod(tgt,kw.get('chmod',Utils.O644)) |
---|
495 | def do_install(self,src,tgt,**kw): |
---|
496 | d,_=os.path.split(tgt) |
---|
497 | if not d: |
---|
498 | raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt)) |
---|
499 | Utils.check_dir(d) |
---|
500 | srclbl=src.replace(self.srcnode.abspath()+os.sep,'') |
---|
501 | if not Options.options.force: |
---|
502 | try: |
---|
503 | st1=os.stat(tgt) |
---|
504 | st2=os.stat(src) |
---|
505 | except OSError: |
---|
506 | pass |
---|
507 | else: |
---|
508 | if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size: |
---|
509 | if not self.progress_bar: |
---|
510 | Logs.info('- install %s (from %s)'%(tgt,srclbl)) |
---|
511 | return False |
---|
512 | if not self.progress_bar: |
---|
513 | Logs.info('+ install %s (from %s)'%(tgt,srclbl)) |
---|
514 | try: |
---|
515 | os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode)) |
---|
516 | except EnvironmentError: |
---|
517 | pass |
---|
518 | try: |
---|
519 | os.remove(tgt) |
---|
520 | except OSError: |
---|
521 | pass |
---|
522 | try: |
---|
523 | self.copy_fun(src,tgt,**kw) |
---|
524 | except IOError: |
---|
525 | try: |
---|
526 | os.stat(src) |
---|
527 | except EnvironmentError: |
---|
528 | Logs.error('File %r does not exist'%src) |
---|
529 | raise Errors.WafError('Could not install the file %r'%tgt) |
---|
530 | def do_link(self,src,tgt,**kw): |
---|
531 | d,_=os.path.split(tgt) |
---|
532 | Utils.check_dir(d) |
---|
533 | link=False |
---|
534 | if not os.path.islink(tgt): |
---|
535 | link=True |
---|
536 | elif os.readlink(tgt)!=src: |
---|
537 | link=True |
---|
538 | if link: |
---|
539 | try:os.remove(tgt) |
---|
540 | except OSError:pass |
---|
541 | if not self.progress_bar: |
---|
542 | Logs.info('+ symlink %s (to %s)'%(tgt,src)) |
---|
543 | os.symlink(src,tgt) |
---|
544 | else: |
---|
545 | if not self.progress_bar: |
---|
546 | Logs.info('- symlink %s (to %s)'%(tgt,src)) |
---|
547 | def run_task_now(self,tsk,postpone): |
---|
548 | tsk.post() |
---|
549 | if not postpone: |
---|
550 | if tsk.runnable_status()==Task.ASK_LATER: |
---|
551 | raise self.WafError('cannot post the task %r'%tsk) |
---|
552 | tsk.run() |
---|
553 | def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True,task=None): |
---|
554 | tsk=inst(env=env or self.env) |
---|
555 | tsk.bld=self |
---|
556 | tsk.path=cwd or self.path |
---|
557 | tsk.chmod=chmod |
---|
558 | tsk.task=task |
---|
559 | if isinstance(files,waflib.Node.Node): |
---|
560 | tsk.source=[files] |
---|
561 | else: |
---|
562 | tsk.source=Utils.to_list(files) |
---|
563 | tsk.dest=dest |
---|
564 | tsk.exec_task=tsk.exec_install_files |
---|
565 | tsk.relative_trick=relative_trick |
---|
566 | if add:self.add_to_group(tsk) |
---|
567 | self.run_task_now(tsk,postpone) |
---|
568 | return tsk |
---|
569 | def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True,task=None): |
---|
570 | tsk=inst(env=env or self.env) |
---|
571 | tsk.bld=self |
---|
572 | tsk.path=cwd or self.path |
---|
573 | tsk.chmod=chmod |
---|
574 | tsk.source=[srcfile] |
---|
575 | tsk.task=task |
---|
576 | tsk.dest=dest |
---|
577 | tsk.exec_task=tsk.exec_install_as |
---|
578 | if add:self.add_to_group(tsk) |
---|
579 | self.run_task_now(tsk,postpone) |
---|
580 | return tsk |
---|
581 | def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False,task=None): |
---|
582 | if Utils.is_win32: |
---|
583 | return |
---|
584 | tsk=inst(env=env or self.env) |
---|
585 | tsk.bld=self |
---|
586 | tsk.dest=dest |
---|
587 | tsk.path=cwd or self.path |
---|
588 | tsk.source=[] |
---|
589 | tsk.task=task |
---|
590 | tsk.link=src |
---|
591 | tsk.relative_trick=relative_trick |
---|
592 | tsk.exec_task=tsk.exec_symlink_as |
---|
593 | if add:self.add_to_group(tsk) |
---|
594 | self.run_task_now(tsk,postpone) |
---|
595 | return tsk |
---|
596 | class UninstallContext(InstallContext): |
---|
597 | '''removes the targets installed''' |
---|
598 | cmd='uninstall' |
---|
599 | def __init__(self,**kw): |
---|
600 | super(UninstallContext,self).__init__(**kw) |
---|
601 | self.is_install=UNINSTALL |
---|
602 | def rm_empty_dirs(self,tgt): |
---|
603 | while tgt: |
---|
604 | tgt=os.path.dirname(tgt) |
---|
605 | try: |
---|
606 | os.rmdir(tgt) |
---|
607 | except OSError: |
---|
608 | break |
---|
609 | def do_install(self,src,tgt,**kw): |
---|
610 | if not self.progress_bar: |
---|
611 | Logs.info('- remove %s'%tgt) |
---|
612 | self.uninstall.append(tgt) |
---|
613 | try: |
---|
614 | os.remove(tgt) |
---|
615 | except OSError ,e: |
---|
616 | if e.errno!=errno.ENOENT: |
---|
617 | if not getattr(self,'uninstall_error',None): |
---|
618 | self.uninstall_error=True |
---|
619 | Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') |
---|
620 | if Logs.verbose>1: |
---|
621 | Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno)) |
---|
622 | self.rm_empty_dirs(tgt) |
---|
623 | def do_link(self,src,tgt,**kw): |
---|
624 | try: |
---|
625 | if not self.progress_bar: |
---|
626 | Logs.info('- remove %s'%tgt) |
---|
627 | os.remove(tgt) |
---|
628 | except OSError: |
---|
629 | pass |
---|
630 | self.rm_empty_dirs(tgt) |
---|
631 | def execute(self): |
---|
632 | try: |
---|
633 | def runnable_status(self): |
---|
634 | return Task.SKIP_ME |
---|
635 | setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status) |
---|
636 | setattr(Task.Task,'runnable_status',runnable_status) |
---|
637 | super(UninstallContext,self).execute() |
---|
638 | finally: |
---|
639 | setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back) |
---|
640 | class CleanContext(BuildContext): |
---|
641 | '''cleans the project''' |
---|
642 | cmd='clean' |
---|
643 | def execute(self): |
---|
644 | self.restore() |
---|
645 | if not self.all_envs: |
---|
646 | self.load_envs() |
---|
647 | self.recurse([self.run_dir]) |
---|
648 | try: |
---|
649 | self.clean() |
---|
650 | finally: |
---|
651 | self.store() |
---|
652 | def clean(self): |
---|
653 | Logs.debug('build: clean called') |
---|
654 | if self.bldnode!=self.srcnode: |
---|
655 | lst=[] |
---|
656 | for e in self.all_envs.values(): |
---|
657 | lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES]) |
---|
658 | for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True): |
---|
659 | if n in lst: |
---|
660 | continue |
---|
661 | n.delete() |
---|
662 | self.root.children={} |
---|
663 | for v in'node_deps task_sigs raw_deps'.split(): |
---|
664 | setattr(self,v,{}) |
---|
665 | class ListContext(BuildContext): |
---|
666 | '''lists the targets to execute''' |
---|
667 | cmd='list' |
---|
668 | def execute(self): |
---|
669 | self.restore() |
---|
670 | if not self.all_envs: |
---|
671 | self.load_envs() |
---|
672 | self.recurse([self.run_dir]) |
---|
673 | self.pre_build() |
---|
674 | self.timer=Utils.Timer() |
---|
675 | for g in self.groups: |
---|
676 | for tg in g: |
---|
677 | try: |
---|
678 | f=tg.post |
---|
679 | except AttributeError: |
---|
680 | pass |
---|
681 | else: |
---|
682 | f() |
---|
683 | try: |
---|
684 | self.get_tgen_by_name('') |
---|
685 | except Exception: |
---|
686 | pass |
---|
687 | lst=list(self.task_gen_cache_names.keys()) |
---|
688 | lst.sort() |
---|
689 | for k in lst: |
---|
690 | Logs.pprint('GREEN',k) |
---|
691 | class StepContext(BuildContext): |
---|
692 | '''executes tasks in a step-by-step fashion, for debugging''' |
---|
693 | cmd='step' |
---|
694 | def __init__(self,**kw): |
---|
695 | super(StepContext,self).__init__(**kw) |
---|
696 | self.files=Options.options.files |
---|
697 | def compile(self): |
---|
698 | if not self.files: |
---|
699 | Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') |
---|
700 | BuildContext.compile(self) |
---|
701 | return |
---|
702 | targets=None |
---|
703 | if self.targets and self.targets!='*': |
---|
704 | targets=self.targets.split(',') |
---|
705 | for g in self.groups: |
---|
706 | for tg in g: |
---|
707 | if targets and tg.name not in targets: |
---|
708 | continue |
---|
709 | try: |
---|
710 | f=tg.post |
---|
711 | except AttributeError: |
---|
712 | pass |
---|
713 | else: |
---|
714 | f() |
---|
715 | for pat in self.files.split(','): |
---|
716 | matcher=self.get_matcher(pat) |
---|
717 | for tg in g: |
---|
718 | if isinstance(tg,Task.TaskBase): |
---|
719 | lst=[tg] |
---|
720 | else: |
---|
721 | lst=tg.tasks |
---|
722 | for tsk in lst: |
---|
723 | do_exec=False |
---|
724 | for node in getattr(tsk,'inputs',[]): |
---|
725 | if matcher(node,output=False): |
---|
726 | do_exec=True |
---|
727 | break |
---|
728 | for node in getattr(tsk,'outputs',[]): |
---|
729 | if matcher(node,output=True): |
---|
730 | do_exec=True |
---|
731 | break |
---|
732 | if do_exec: |
---|
733 | ret=tsk.run() |
---|
734 | Logs.info('%s -> exit %r'%(str(tsk),ret)) |
---|
735 | def get_matcher(self,pat): |
---|
736 | inn=True |
---|
737 | out=True |
---|
738 | if pat.startswith('in:'): |
---|
739 | out=False |
---|
740 | pat=pat.replace('in:','') |
---|
741 | elif pat.startswith('out:'): |
---|
742 | inn=False |
---|
743 | pat=pat.replace('out:','') |
---|
744 | anode=self.root.find_node(pat) |
---|
745 | pattern=None |
---|
746 | if not anode: |
---|
747 | if not pat.startswith('^'): |
---|
748 | pat='^.+?%s'%pat |
---|
749 | if not pat.endswith('$'): |
---|
750 | pat='%s$'%pat |
---|
751 | pattern=re.compile(pat) |
---|
752 | def match(node,output): |
---|
753 | if output==True and not out: |
---|
754 | return False |
---|
755 | if output==False and not inn: |
---|
756 | return False |
---|
757 | if anode: |
---|
758 | return anode==node |
---|
759 | else: |
---|
760 | return pattern.match(node.abspath()) |
---|
761 | return match |
---|