~ubuntu-branches/ubuntu/trusty/xiphos/trusty

« back to all changes in this revision

Viewing changes to wafadmin/TaskGen.py

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs, Dmitrijs Ledkovs
  • Date: 2012-03-11 18:43:32 UTC
  • mfrom: (17.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120311184332-splq3ecpx7tyi87d
Tags: 3.1.5+dfsg-1
[ Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> ]  
* New upstream release.
* Build using webkit backend
* Contains unpacked source for waf binary (Closes: #654511)
* Update debian/copyright to latest specification

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# encoding: utf-8
 
3
import sys
 
4
if sys.hexversion < 0x020400f0: from sets import Set as set
 
5
import os,traceback,copy
 
6
import Build,Task,Utils,Logs,Options
 
7
from Logs import debug,error,warn
 
8
from Constants import*
 
9
typos={'sources':'source','targets':'target','include':'includes','define':'defines','importpath':'importpaths','install_var':'install_path','install_subdir':'install_path','inst_var':'install_path','inst_dir':'install_path','feature':'features',}
 
10
class register_obj(type):
 
11
        def __init__(cls,name,bases,dict):
 
12
                super(register_obj,cls).__init__(name,bases,dict)
 
13
                name=cls.__name__
 
14
                suffix='_taskgen'
 
15
                if name.endswith(suffix):
 
16
                        task_gen.classes[name.replace(suffix,'')]=cls
 
17
class task_gen(object):
 
18
        __metaclass__=register_obj
 
19
        mappings={}
 
20
        mapped={}
 
21
        prec=Utils.DefaultDict(list)
 
22
        traits=Utils.DefaultDict(set)
 
23
        classes={}
 
24
        def __init__(self,*kw,**kwargs):
 
25
                self.prec=Utils.DefaultDict(list)
 
26
                self.source=''
 
27
                self.target=''
 
28
                self.meths=[]
 
29
                self.mappings={}
 
30
                self.features=list(kw)
 
31
                self.tasks=[]
 
32
                self.default_chmod=O644
 
33
                self.default_install_path=None
 
34
                self.allnodes=[]
 
35
                self.bld=kwargs.get('bld',Build.bld)
 
36
                self.env=self.bld.env.copy()
 
37
                self.path=self.bld.path
 
38
                self.name=''
 
39
                self.idx=self.bld.idx[self.path.id]=self.bld.idx.get(self.path.id,0)+1
 
40
                for key,val in kwargs.iteritems():
 
41
                        setattr(self,key,val)
 
42
                self.bld.task_manager.add_task_gen(self)
 
43
                self.bld.all_task_gen.append(self)
 
44
        def __str__(self):
 
45
                return("<task_gen '%s' of type %s defined in %s>"%(self.name or self.target,self.__class__.__name__,str(self.path)))
 
46
        def __setattr__(self,name,attr):
 
47
                real=typos.get(name,name)
 
48
                if real!=name:
 
49
                        warn('typo %s -> %s'%(name,real))
 
50
                        if Logs.verbose>0:
 
51
                                traceback.print_stack()
 
52
                object.__setattr__(self,real,attr)
 
53
        def to_list(self,value):
 
54
                if isinstance(value,str):return value.split()
 
55
                else:return value
 
56
        def apply(self):
 
57
                keys=set(self.meths)
 
58
                self.features=Utils.to_list(self.features)
 
59
                for x in self.features+['*']:
 
60
                        st=task_gen.traits[x]
 
61
                        if not st:
 
62
                                warn('feature %r does not exist - bind at least one method to it'%x)
 
63
                        keys.update(st)
 
64
                prec={}
 
65
                prec_tbl=self.prec or task_gen.prec
 
66
                for x in prec_tbl:
 
67
                        if x in keys:
 
68
                                prec[x]=prec_tbl[x]
 
69
                tmp=[]
 
70
                for a in keys:
 
71
                        for x in prec.values():
 
72
                                if a in x:break
 
73
                        else:
 
74
                                tmp.append(a)
 
75
                out=[]
 
76
                while tmp:
 
77
                        e=tmp.pop()
 
78
                        if e in keys:out.append(e)
 
79
                        try:
 
80
                                nlst=prec[e]
 
81
                        except KeyError:
 
82
                                pass
 
83
                        else:
 
84
                                del prec[e]
 
85
                                for x in nlst:
 
86
                                        for y in prec:
 
87
                                                if x in prec[y]:
 
88
                                                        break
 
89
                                        else:
 
90
                                                tmp.append(x)
 
91
                if prec:raise Utils.WafError("graph has a cycle %s"%str(prec))
 
92
                out.reverse()
 
93
                self.meths=out
 
94
                debug('task_gen: posting %s %d',self,id(self))
 
95
                for x in out:
 
96
                        try:
 
97
                                v=getattr(self,x)
 
98
                        except AttributeError:
 
99
                                raise Utils.WafError("tried to retrieve %s which is not a valid method"%x)
 
100
                        debug('task_gen: -> %s (%d)',x,id(self))
 
101
                        v()
 
102
        def post(self):
 
103
                if not self.name:
 
104
                        if isinstance(self.target,list):
 
105
                                self.name=' '.join(self.target)
 
106
                        else:
 
107
                                self.name=self.target
 
108
                if getattr(self,'posted',None):
 
109
                        return
 
110
                self.apply()
 
111
                debug('task_gen: posted %s',self.name)
 
112
                self.posted=True
 
113
        def get_hook(self,ext):
 
114
                try:return self.mappings[ext]
 
115
                except KeyError:
 
116
                        try:return task_gen.mappings[ext]
 
117
                        except KeyError:return None
 
118
        def create_task(self,name,src=None,tgt=None,env=None):
 
119
                env=env or self.env
 
120
                task=Task.TaskBase.classes[name](env.copy(),generator=self)
 
121
                if src:
 
122
                        task.set_inputs(src)
 
123
                if tgt:
 
124
                        task.set_outputs(tgt)
 
125
                self.tasks.append(task)
 
126
                return task
 
127
        def name_to_obj(self,name):
 
128
                return self.bld.name_to_obj(name,self.env)
 
129
        def find_sources_in_dirs(self,dirnames,excludes=[],exts=[]):
 
130
                err_msg="'%s' attribute must be a list"
 
131
                if not isinstance(excludes,list):
 
132
                        raise Utils.WscriptError(err_msg%'excludes')
 
133
                if not isinstance(exts,list):
 
134
                        raise Utils.WscriptError(err_msg%'exts')
 
135
                lst=[]
 
136
                dirnames=self.to_list(dirnames)
 
137
                ext_lst=exts or list(self.mappings.keys())+list(task_gen.mappings.keys())
 
138
                for name in dirnames:
 
139
                        anode=self.path.find_dir(name)
 
140
                        if not anode or not anode.is_child_of(self.bld.srcnode):
 
141
                                raise Utils.WscriptError("Unable to use '%s' - either because it's not a relative path"", or it's not child of '%s'."%(name,self.bld.srcnode))
 
142
                        self.bld.rescan(anode)
 
143
                        for name in self.bld.cache_dir_contents[anode.id]:
 
144
                                if name.startswith('.'):
 
145
                                        continue
 
146
                                (base,ext)=os.path.splitext(name)
 
147
                                if ext in ext_lst and not name in lst and not name in excludes:
 
148
                                        lst.append((anode.relpath_gen(self.path)or'.')+os.path.sep+name)
 
149
                lst.sort()
 
150
                self.source=self.to_list(self.source)
 
151
                if not self.source:self.source=lst
 
152
                else:self.source+=lst
 
153
        def clone(self,env):
 
154
                newobj=task_gen(bld=self.bld)
 
155
                for x in self.__dict__:
 
156
                        if x in['env','bld']:
 
157
                                continue
 
158
                        elif x in["path","features"]:
 
159
                                setattr(newobj,x,getattr(self,x))
 
160
                        else:
 
161
                                setattr(newobj,x,copy.copy(getattr(self,x)))
 
162
                newobj.__class__=self.__class__
 
163
                if isinstance(env,str):
 
164
                        newobj.env=self.bld.all_envs[env].copy()
 
165
                else:
 
166
                        newobj.env=env.copy()
 
167
                return newobj
 
168
        def get_inst_path(self):
 
169
                return getattr(self,'_install_path',getattr(self,'default_install_path',''))
 
170
        def set_inst_path(self,val):
 
171
                self._install_path=val
 
172
        install_path=property(get_inst_path,set_inst_path)
 
173
        def get_chmod(self):
 
174
                return getattr(self,'_chmod',getattr(self,'default_chmod',O644))
 
175
        def set_chmod(self,val):
 
176
                self._chmod=val
 
177
        chmod=property(get_chmod,set_chmod)
 
178
def declare_extension(var,func):
 
179
        try:
 
180
                for x in Utils.to_list(var):
 
181
                        task_gen.mappings[x]=func
 
182
        except:
 
183
                raise Utils.WscriptError('declare_extension takes either a list or a string %r'%var)
 
184
        task_gen.mapped[func.__name__]=func
 
185
def declare_order(*k):
 
186
        assert(len(k)>1)
 
187
        n=len(k)-1
 
188
        for i in xrange(n):
 
189
                f1=k[i]
 
190
                f2=k[i+1]
 
191
                if not f1 in task_gen.prec[f2]:
 
192
                        task_gen.prec[f2].append(f1)
 
193
def declare_chain(name='',action='',ext_in='',ext_out='',reentrant=True,color='BLUE',install=0,before=[],after=[],decider=None,rule=None,scan=None):
 
194
        action=action or rule
 
195
        if isinstance(action,str):
 
196
                act=Task.simple_task_type(name,action,color=color)
 
197
        else:
 
198
                act=Task.task_type_from_func(name,action,color=color)
 
199
        act.ext_in=tuple(Utils.to_list(ext_in))
 
200
        act.ext_out=tuple(Utils.to_list(ext_out))
 
201
        act.before=Utils.to_list(before)
 
202
        act.after=Utils.to_list(after)
 
203
        act.scan=scan
 
204
        def x_file(self,node):
 
205
                if decider:
 
206
                        ext=decider(self,node)
 
207
                else:
 
208
                        ext=ext_out
 
209
                if isinstance(ext,str):
 
210
                        out_source=node.change_ext(ext)
 
211
                        if reentrant:
 
212
                                self.allnodes.append(out_source)
 
213
                elif isinstance(ext,list):
 
214
                        out_source=[node.change_ext(x)for x in ext]
 
215
                        if reentrant:
 
216
                                for i in xrange((reentrant is True)and len(out_source)or reentrant):
 
217
                                        self.allnodes.append(out_source[i])
 
218
                else:
 
219
                        raise Utils.WafError("do not know how to process %s"%str(ext))
 
220
                tsk=self.create_task(name,node,out_source)
 
221
                if node.__class__.bld.is_install:
 
222
                        tsk.install=install
 
223
        declare_extension(act.ext_in,x_file)
 
224
def bind_feature(name,methods):
 
225
        lst=Utils.to_list(methods)
 
226
        task_gen.traits[name].update(lst)
 
227
def taskgen(func):
 
228
        setattr(task_gen,func.__name__,func)
 
229
        return func
 
230
def feature(*k):
 
231
        def deco(func):
 
232
                setattr(task_gen,func.__name__,func)
 
233
                for name in k:
 
234
                        task_gen.traits[name].update([func.__name__])
 
235
                return func
 
236
        return deco
 
237
def before(*k):
 
238
        def deco(func):
 
239
                setattr(task_gen,func.__name__,func)
 
240
                for fun_name in k:
 
241
                        if not func.__name__ in task_gen.prec[fun_name]:
 
242
                                task_gen.prec[fun_name].append(func.__name__)
 
243
                return func
 
244
        return deco
 
245
def after(*k):
 
246
        def deco(func):
 
247
                setattr(task_gen,func.__name__,func)
 
248
                for fun_name in k:
 
249
                        if not fun_name in task_gen.prec[func.__name__]:
 
250
                                task_gen.prec[func.__name__].append(fun_name)
 
251
                return func
 
252
        return deco
 
253
def extension(var):
 
254
        def deco(func):
 
255
                setattr(task_gen,func.__name__,func)
 
256
                try:
 
257
                        for x in Utils.to_list(var):
 
258
                                task_gen.mappings[x]=func
 
259
                except:
 
260
                        raise Utils.WafError('extension takes either a list or a string %r'%var)
 
261
                task_gen.mapped[func.__name__]=func
 
262
                return func
 
263
        return deco
 
264
def apply_core(self):
 
265
        find_resource=self.path.find_resource
 
266
        for filename in self.to_list(self.source):
 
267
                x=self.get_hook(filename)
 
268
                if x:
 
269
                        x(self,filename)
 
270
                else:
 
271
                        node=find_resource(filename)
 
272
                        if not node:raise Utils.WafError("source not found: '%s' in '%s'"%(filename,str(self.path)))
 
273
                        self.allnodes.append(node)
 
274
        for node in self.allnodes:
 
275
                x=self.get_hook(node.suffix())
 
276
                if not x:
 
277
                        raise Utils.WafError("Cannot guess how to process %s (got mappings %r in %r) -> try conf.check_tool(..)?"%(str(node),self.__class__.mappings.keys(),self.__class__))
 
278
                x(self,node)
 
279
feature('*')(apply_core)
 
280
def exec_rule(self):
 
281
        if not getattr(self,'rule',None):
 
282
                return
 
283
        try:
 
284
                self.meths.remove('apply_core')
 
285
        except ValueError:
 
286
                pass
 
287
        func=self.rule
 
288
        vars2=[]
 
289
        if isinstance(func,str):
 
290
                (func,vars2)=Task.compile_fun('',self.rule,shell=getattr(self,'shell',True))
 
291
                func.code=self.rule
 
292
        vars=getattr(self,'vars',vars2)
 
293
        if not vars:
 
294
                if isinstance(self.rule,str):
 
295
                        vars=self.rule
 
296
                else:
 
297
                        vars=Utils.h_fun(self.rule)
 
298
        name=getattr(self,'name',None)or self.target or self.rule
 
299
        if not isinstance(name,str):
 
300
                name=str(self.idx)
 
301
        cls=Task.task_type_from_func(name,func,vars)
 
302
        tsk=self.create_task(name)
 
303
        if getattr(self,'target',None):
 
304
                cls.quiet=True
 
305
                tsk.outputs=[self.path.find_or_declare(x)for x in self.to_list(self.target)]
 
306
        if getattr(self,'source',None):
 
307
                cls.quiet=True
 
308
                tsk.inputs=[]
 
309
                for x in self.to_list(self.source):
 
310
                        y=self.path.find_resource(x)
 
311
                        if not y:
 
312
                                raise Utils.WafError('input file %r could not be found (%r)'%(x,self.path.abspath()))
 
313
                        tsk.inputs.append(y)
 
314
        if self.allnodes:
 
315
                tsk.inputs.extend(self.allnodes)
 
316
        if getattr(self,'scan',None):
 
317
                cls.scan=self.scan
 
318
        if getattr(self,'install_path',None):
 
319
                tsk.install_path=self.install_path
 
320
        if getattr(self,'cwd',None):
 
321
                tsk.cwd=self.cwd
 
322
        if getattr(self,'on_results',None):
 
323
                Task.update_outputs(cls)
 
324
        if getattr(self,'always',None):
 
325
                Task.always_run(cls)
 
326
        for x in['after','before','ext_in','ext_out']:
 
327
                setattr(cls,x,getattr(self,x,[]))
 
328
feature('*')(exec_rule)
 
329
before('apply_core')(exec_rule)
 
330
def sequence_order(self):
 
331
        if self.meths and self.meths[-1]!='sequence_order':
 
332
                self.meths.append('sequence_order')
 
333
                return
 
334
        if getattr(self,'seq_start',None):
 
335
                return
 
336
        if getattr(self.bld,'prev',None):
 
337
                self.bld.prev.post()
 
338
                for x in self.bld.prev.tasks:
 
339
                        for y in self.tasks:
 
340
                                y.set_run_after(x)
 
341
        self.bld.prev=self
 
342
feature('seq')(sequence_order)
 
343