~ubuntu-branches/ubuntu/raring/xmms2/raring

« back to all changes in this revision

Viewing changes to waflib/Build.py

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-11-25 19:23:15 UTC
  • mto: This revision was merged to the branch mainline in revision 51.
  • Revision ID: package-import@ubuntu.com-20121125192315-m9z6nu9wwlzrrz9z
ImportĀ upstreamĀ versionĀ 0.8+dfsg

Show diffs side-by-side

added added

removed removed

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