[0fa325b] | 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 |
---|
| 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=self.out_dir+os.sep+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.cache_global=Options.cache_global |
---|
| 46 | self.nocache=Options.options.nocache |
---|
| 47 | self.progress_bar=Options.options.progress_bar |
---|
| 48 | self.deps_man=Utils.defaultdict(list) |
---|
| 49 | self.current_group=0 |
---|
| 50 | self.groups=[] |
---|
| 51 | self.group_names={} |
---|
| 52 | def get_variant_dir(self): |
---|
| 53 | if not self.variant: |
---|
| 54 | return self.out_dir |
---|
| 55 | return os.path.join(self.out_dir,self.variant) |
---|
| 56 | variant_dir=property(get_variant_dir,None) |
---|
| 57 | def __call__(self,*k,**kw): |
---|
| 58 | kw['bld']=self |
---|
| 59 | ret=TaskGen.task_gen(*k,**kw) |
---|
| 60 | self.task_gen_cache_names={} |
---|
| 61 | self.add_to_group(ret,group=kw.get('group',None)) |
---|
| 62 | return ret |
---|
| 63 | def rule(self,*k,**kw): |
---|
| 64 | def f(rule): |
---|
| 65 | ret=self(*k,**kw) |
---|
| 66 | ret.rule=rule |
---|
| 67 | return ret |
---|
| 68 | return f |
---|
| 69 | def __copy__(self): |
---|
| 70 | raise Errors.WafError('build contexts are not supposed to be copied') |
---|
| 71 | def install_files(self,*k,**kw): |
---|
| 72 | pass |
---|
| 73 | def install_as(self,*k,**kw): |
---|
| 74 | pass |
---|
| 75 | def symlink_as(self,*k,**kw): |
---|
| 76 | pass |
---|
| 77 | def load_envs(self): |
---|
| 78 | node=self.root.find_node(self.cache_dir) |
---|
| 79 | if not node: |
---|
| 80 | raise Errors.WafError('The project was not configured: run "waf configure" first!') |
---|
| 81 | lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True) |
---|
| 82 | if not lst: |
---|
| 83 | raise Errors.WafError('The cache directory is empty: reconfigure the project') |
---|
| 84 | for x in lst: |
---|
| 85 | name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/') |
---|
| 86 | env=ConfigSet.ConfigSet(x.abspath()) |
---|
| 87 | self.all_envs[name]=env |
---|
| 88 | for f in env[CFG_FILES]: |
---|
| 89 | newnode=self.root.find_resource(f) |
---|
| 90 | try: |
---|
| 91 | h=Utils.h_file(newnode.abspath()) |
---|
| 92 | except(IOError,AttributeError): |
---|
| 93 | Logs.error('cannot find %r'%f) |
---|
| 94 | h=Utils.SIG_NIL |
---|
| 95 | newnode.sig=h |
---|
| 96 | def init_dirs(self): |
---|
| 97 | if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)): |
---|
| 98 | raise Errors.WafError('The project was not configured: run "waf configure" first!') |
---|
| 99 | self.path=self.srcnode=self.root.find_dir(self.top_dir) |
---|
| 100 | self.bldnode=self.root.make_node(self.variant_dir) |
---|
| 101 | self.bldnode.mkdir() |
---|
| 102 | def execute(self): |
---|
| 103 | self.restore() |
---|
| 104 | if not self.all_envs: |
---|
| 105 | self.load_envs() |
---|
| 106 | self.execute_build() |
---|
| 107 | def execute_build(self): |
---|
| 108 | Logs.info("Waf: Entering directory `%s'"%self.variant_dir) |
---|
| 109 | self.recurse([self.run_dir]) |
---|
| 110 | self.pre_build() |
---|
| 111 | self.timer=Utils.Timer() |
---|
| 112 | if self.progress_bar: |
---|
| 113 | sys.stderr.write(Logs.colors.cursor_off) |
---|
| 114 | try: |
---|
| 115 | self.compile() |
---|
| 116 | finally: |
---|
| 117 | if self.progress_bar==1: |
---|
| 118 | c=len(self.returned_tasks)or 1 |
---|
| 119 | self.to_log(self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL)) |
---|
| 120 | print('') |
---|
| 121 | sys.stdout.flush() |
---|
| 122 | sys.stderr.write(Logs.colors.cursor_on) |
---|
| 123 | Logs.info("Waf: Leaving directory `%s'"%self.variant_dir) |
---|
| 124 | self.post_build() |
---|
| 125 | def restore(self): |
---|
| 126 | try: |
---|
| 127 | env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py')) |
---|
| 128 | except(IOError,OSError): |
---|
| 129 | pass |
---|
| 130 | else: |
---|
| 131 | if env['version']<Context.HEXVERSION: |
---|
| 132 | raise Errors.WafError('Version mismatch! reconfigure the project') |
---|
| 133 | for t in env['tools']: |
---|
| 134 | self.setup(**t) |
---|
[c101fe1] | 135 | dbfn=os.path.join(self.variant_dir,Context.DBFILE) |
---|
[0fa325b] | 136 | try: |
---|
[c101fe1] | 137 | data=Utils.readf(dbfn,'rb') |
---|
| 138 | except(IOError,EOFError): |
---|
| 139 | Logs.debug('build: Could not load the build cache %s (missing)'%dbfn) |
---|
| 140 | else: |
---|
[0fa325b] | 141 | try: |
---|
[c101fe1] | 142 | waflib.Node.pickle_lock.acquire() |
---|
| 143 | waflib.Node.Nod3=self.node_class |
---|
[0fa325b] | 144 | try: |
---|
[c101fe1] | 145 | data=cPickle.loads(data) |
---|
| 146 | except Exception ,e: |
---|
| 147 | Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e)) |
---|
| 148 | else: |
---|
| 149 | for x in SAVED_ATTRS: |
---|
| 150 | setattr(self,x,data[x]) |
---|
| 151 | finally: |
---|
| 152 | waflib.Node.pickle_lock.release() |
---|
[0fa325b] | 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 |
---|
[c101fe1] | 162 | x=cPickle.dumps(data,-1) |
---|
[0fa325b] | 163 | finally: |
---|
| 164 | waflib.Node.pickle_lock.release() |
---|
[c101fe1] | 165 | Utils.writef(db+'.tmp',x,m='wb') |
---|
[0fa325b] | 166 | try: |
---|
| 167 | st=os.stat(db) |
---|
[c101fe1] | 168 | os.remove(db) |
---|
[0fa325b] | 169 | if not Utils.is_win32: |
---|
| 170 | os.chown(db+'.tmp',st.st_uid,st.st_gid) |
---|
| 171 | except(AttributeError,OSError): |
---|
| 172 | pass |
---|
| 173 | os.rename(db+'.tmp',db) |
---|
| 174 | def compile(self): |
---|
| 175 | Logs.debug('build: compile()') |
---|
| 176 | self.producer=Runner.Parallel(self,self.jobs) |
---|
| 177 | self.producer.biter=self.get_build_iterator() |
---|
| 178 | self.returned_tasks=[] |
---|
| 179 | try: |
---|
| 180 | self.producer.start() |
---|
| 181 | except KeyboardInterrupt: |
---|
| 182 | self.store() |
---|
| 183 | raise |
---|
| 184 | else: |
---|
| 185 | if self.producer.dirty: |
---|
| 186 | self.store() |
---|
| 187 | if self.producer.error: |
---|
| 188 | raise Errors.BuildError(self.producer.error) |
---|
| 189 | def setup(self,tool,tooldir=None,funs=None): |
---|
| 190 | if isinstance(tool,list): |
---|
| 191 | for i in tool:self.setup(i,tooldir) |
---|
| 192 | return |
---|
| 193 | module=Context.load_tool(tool,tooldir) |
---|
| 194 | if hasattr(module,"setup"):module.setup(self) |
---|
| 195 | def get_env(self): |
---|
| 196 | try: |
---|
| 197 | return self.all_envs[self.variant] |
---|
| 198 | except KeyError: |
---|
| 199 | return self.all_envs[''] |
---|
| 200 | def set_env(self,val): |
---|
| 201 | self.all_envs[self.variant]=val |
---|
| 202 | env=property(get_env,set_env) |
---|
| 203 | def add_manual_dependency(self,path,value): |
---|
| 204 | if path is None: |
---|
| 205 | raise ValueError('Invalid input') |
---|
| 206 | if isinstance(path,waflib.Node.Node): |
---|
| 207 | node=path |
---|
| 208 | elif os.path.isabs(path): |
---|
| 209 | node=self.root.find_resource(path) |
---|
| 210 | else: |
---|
| 211 | node=self.path.find_resource(path) |
---|
| 212 | if isinstance(value,list): |
---|
| 213 | self.deps_man[id(node)].extend(value) |
---|
| 214 | else: |
---|
| 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: %s %r',Utils.to_hex(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 get_all_task_gen(self): |
---|
| 354 | lst=[] |
---|
| 355 | for g in self.groups: |
---|
| 356 | lst.extend(g) |
---|
| 357 | return lst |
---|
| 358 | def post_group(self): |
---|
| 359 | if self.targets=='*': |
---|
| 360 | for tg in self.groups[self.cur]: |
---|
| 361 | try: |
---|
| 362 | f=tg.post |
---|
| 363 | except AttributeError: |
---|
| 364 | pass |
---|
| 365 | else: |
---|
| 366 | f() |
---|
| 367 | elif self.targets: |
---|
| 368 | if self.cur<self._min_grp: |
---|
| 369 | for tg in self.groups[self.cur]: |
---|
| 370 | try: |
---|
| 371 | f=tg.post |
---|
| 372 | except AttributeError: |
---|
| 373 | pass |
---|
| 374 | else: |
---|
| 375 | f() |
---|
| 376 | else: |
---|
| 377 | for tg in self._exact_tg: |
---|
| 378 | tg.post() |
---|
| 379 | else: |
---|
| 380 | ln=self.launch_node() |
---|
| 381 | if ln.is_child_of(self.bldnode): |
---|
| 382 | Logs.warn('Building from the build directory, forcing --targets=*') |
---|
| 383 | ln=self.srcnode |
---|
| 384 | elif not ln.is_child_of(self.srcnode): |
---|
| 385 | Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath())) |
---|
| 386 | ln=self.srcnode |
---|
| 387 | for tg in self.groups[self.cur]: |
---|
| 388 | try: |
---|
| 389 | f=tg.post |
---|
| 390 | except AttributeError: |
---|
| 391 | pass |
---|
| 392 | else: |
---|
| 393 | if tg.path.is_child_of(ln): |
---|
| 394 | f() |
---|
| 395 | def get_tasks_group(self,idx): |
---|
| 396 | tasks=[] |
---|
| 397 | for tg in self.groups[idx]: |
---|
| 398 | try: |
---|
| 399 | tasks.extend(tg.tasks) |
---|
| 400 | except AttributeError: |
---|
| 401 | tasks.append(tg) |
---|
| 402 | return tasks |
---|
| 403 | def get_build_iterator(self): |
---|
| 404 | self.cur=0 |
---|
| 405 | if self.targets and self.targets!='*': |
---|
| 406 | (self._min_grp,self._exact_tg)=self.get_targets() |
---|
| 407 | global lazy_post |
---|
| 408 | if self.post_mode!=POST_LAZY: |
---|
| 409 | while self.cur<len(self.groups): |
---|
| 410 | self.post_group() |
---|
| 411 | self.cur+=1 |
---|
| 412 | self.cur=0 |
---|
| 413 | while self.cur<len(self.groups): |
---|
| 414 | if self.post_mode!=POST_AT_ONCE: |
---|
| 415 | self.post_group() |
---|
| 416 | tasks=self.get_tasks_group(self.cur) |
---|
| 417 | Task.set_file_constraints(tasks) |
---|
| 418 | Task.set_precedence_constraints(tasks) |
---|
| 419 | self.cur_tasks=tasks |
---|
| 420 | self.cur+=1 |
---|
| 421 | if not tasks: |
---|
| 422 | continue |
---|
| 423 | yield tasks |
---|
| 424 | while 1: |
---|
| 425 | yield[] |
---|
| 426 | class inst(Task.Task): |
---|
| 427 | color='CYAN' |
---|
| 428 | def uid(self): |
---|
| 429 | lst=[self.dest,self.path]+self.source |
---|
| 430 | return Utils.h_list(repr(lst)) |
---|
| 431 | def post(self): |
---|
| 432 | buf=[] |
---|
| 433 | for x in self.source: |
---|
| 434 | if isinstance(x,waflib.Node.Node): |
---|
| 435 | y=x |
---|
| 436 | else: |
---|
| 437 | y=self.path.find_resource(x) |
---|
| 438 | if not y: |
---|
| 439 | if Logs.verbose: |
---|
| 440 | Logs.warn('Could not find %s immediately (may cause broken builds)'%x) |
---|
| 441 | idx=self.generator.bld.get_group_idx(self) |
---|
| 442 | for tg in self.generator.bld.groups[idx]: |
---|
| 443 | if not isinstance(tg,inst)and id(tg)!=id(self): |
---|
| 444 | tg.post() |
---|
| 445 | y=self.path.find_resource(x) |
---|
| 446 | if y: |
---|
| 447 | break |
---|
| 448 | else: |
---|
| 449 | raise Errors.WafError('Could not find %r in %r'%(x,self.path)) |
---|
| 450 | buf.append(y) |
---|
| 451 | self.inputs=buf |
---|
| 452 | def runnable_status(self): |
---|
| 453 | ret=super(inst,self).runnable_status() |
---|
| 454 | if ret==Task.SKIP_ME: |
---|
| 455 | return Task.RUN_ME |
---|
| 456 | return ret |
---|
| 457 | def __str__(self): |
---|
| 458 | return'' |
---|
| 459 | def run(self): |
---|
| 460 | return self.generator.exec_task() |
---|
| 461 | def get_install_path(self,destdir=True): |
---|
| 462 | dest=Utils.subst_vars(self.dest,self.env) |
---|
| 463 | dest=dest.replace('/',os.sep) |
---|
| 464 | if destdir and Options.options.destdir: |
---|
| 465 | dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep)) |
---|
| 466 | return dest |
---|
| 467 | def exec_install_files(self): |
---|
| 468 | destpath=self.get_install_path() |
---|
| 469 | if not destpath: |
---|
| 470 | raise Errors.WafError('unknown installation path %r'%self.generator) |
---|
| 471 | for x,y in zip(self.source,self.inputs): |
---|
| 472 | if self.relative_trick: |
---|
| 473 | destfile=os.path.join(destpath,y.path_from(self.path)) |
---|
| 474 | else: |
---|
| 475 | destfile=os.path.join(destpath,y.name) |
---|
| 476 | self.generator.bld.do_install(y.abspath(),destfile,self.chmod) |
---|
| 477 | def exec_install_as(self): |
---|
| 478 | destfile=self.get_install_path() |
---|
| 479 | self.generator.bld.do_install(self.inputs[0].abspath(),destfile,self.chmod) |
---|
| 480 | def exec_symlink_as(self): |
---|
| 481 | destfile=self.get_install_path() |
---|
| 482 | src=self.link |
---|
| 483 | if self.relative_trick: |
---|
| 484 | src=os.path.relpath(src,os.path.dirname(destfile)) |
---|
| 485 | self.generator.bld.do_link(src,destfile) |
---|
| 486 | class InstallContext(BuildContext): |
---|
| 487 | '''installs the targets on the system''' |
---|
| 488 | cmd='install' |
---|
| 489 | def __init__(self,**kw): |
---|
| 490 | super(InstallContext,self).__init__(**kw) |
---|
| 491 | self.uninstall=[] |
---|
| 492 | self.is_install=INSTALL |
---|
| 493 | def do_install(self,src,tgt,chmod=Utils.O644): |
---|
| 494 | d,_=os.path.split(tgt) |
---|
| 495 | if not d: |
---|
| 496 | raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt)) |
---|
| 497 | Utils.check_dir(d) |
---|
| 498 | srclbl=src.replace(self.srcnode.abspath()+os.sep,'') |
---|
| 499 | if not Options.options.force: |
---|
| 500 | try: |
---|
| 501 | st1=os.stat(tgt) |
---|
| 502 | st2=os.stat(src) |
---|
| 503 | except OSError: |
---|
| 504 | pass |
---|
| 505 | else: |
---|
| 506 | if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size: |
---|
| 507 | if not self.progress_bar: |
---|
| 508 | Logs.info('- install %s (from %s)'%(tgt,srclbl)) |
---|
| 509 | return False |
---|
| 510 | if not self.progress_bar: |
---|
| 511 | Logs.info('+ install %s (from %s)'%(tgt,srclbl)) |
---|
| 512 | try: |
---|
| 513 | os.remove(tgt) |
---|
| 514 | except OSError: |
---|
| 515 | pass |
---|
| 516 | try: |
---|
| 517 | shutil.copy2(src,tgt) |
---|
| 518 | os.chmod(tgt,chmod) |
---|
| 519 | except IOError: |
---|
| 520 | try: |
---|
| 521 | os.stat(src) |
---|
| 522 | except(OSError,IOError): |
---|
| 523 | Logs.error('File %r does not exist'%src) |
---|
| 524 | raise Errors.WafError('Could not install the file %r'%tgt) |
---|
| 525 | def do_link(self,src,tgt): |
---|
| 526 | d,_=os.path.split(tgt) |
---|
| 527 | Utils.check_dir(d) |
---|
| 528 | link=False |
---|
| 529 | if not os.path.islink(tgt): |
---|
| 530 | link=True |
---|
| 531 | elif os.readlink(tgt)!=src: |
---|
| 532 | link=True |
---|
| 533 | if link: |
---|
| 534 | try:os.remove(tgt) |
---|
| 535 | except OSError:pass |
---|
| 536 | if not self.progress_bar: |
---|
| 537 | Logs.info('+ symlink %s (to %s)'%(tgt,src)) |
---|
| 538 | os.symlink(src,tgt) |
---|
| 539 | else: |
---|
| 540 | if not self.progress_bar: |
---|
| 541 | Logs.info('- symlink %s (to %s)'%(tgt,src)) |
---|
| 542 | def run_task_now(self,tsk,postpone): |
---|
| 543 | tsk.post() |
---|
| 544 | if not postpone: |
---|
| 545 | if tsk.runnable_status()==Task.ASK_LATER: |
---|
| 546 | raise self.WafError('cannot post the task %r'%tsk) |
---|
| 547 | tsk.run() |
---|
| 548 | def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True): |
---|
| 549 | tsk=inst(env=env or self.env) |
---|
| 550 | tsk.bld=self |
---|
| 551 | tsk.path=cwd or self.path |
---|
| 552 | tsk.chmod=chmod |
---|
| 553 | if isinstance(files,waflib.Node.Node): |
---|
| 554 | tsk.source=[files] |
---|
| 555 | else: |
---|
| 556 | tsk.source=Utils.to_list(files) |
---|
| 557 | tsk.dest=dest |
---|
| 558 | tsk.exec_task=tsk.exec_install_files |
---|
| 559 | tsk.relative_trick=relative_trick |
---|
| 560 | if add:self.add_to_group(tsk) |
---|
| 561 | self.run_task_now(tsk,postpone) |
---|
| 562 | return tsk |
---|
| 563 | def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True): |
---|
| 564 | tsk=inst(env=env or self.env) |
---|
| 565 | tsk.bld=self |
---|
| 566 | tsk.path=cwd or self.path |
---|
| 567 | tsk.chmod=chmod |
---|
| 568 | tsk.source=[srcfile] |
---|
| 569 | tsk.dest=dest |
---|
| 570 | tsk.exec_task=tsk.exec_install_as |
---|
| 571 | if add:self.add_to_group(tsk) |
---|
| 572 | self.run_task_now(tsk,postpone) |
---|
| 573 | return tsk |
---|
| 574 | def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False): |
---|
| 575 | if Utils.is_win32: |
---|
| 576 | return |
---|
| 577 | tsk=inst(env=env or self.env) |
---|
| 578 | tsk.bld=self |
---|
| 579 | tsk.dest=dest |
---|
| 580 | tsk.path=cwd or self.path |
---|
| 581 | tsk.source=[] |
---|
| 582 | tsk.link=src |
---|
| 583 | tsk.relative_trick=relative_trick |
---|
| 584 | tsk.exec_task=tsk.exec_symlink_as |
---|
| 585 | if add:self.add_to_group(tsk) |
---|
| 586 | self.run_task_now(tsk,postpone) |
---|
| 587 | return tsk |
---|
| 588 | class UninstallContext(InstallContext): |
---|
| 589 | '''removes the targets installed''' |
---|
| 590 | cmd='uninstall' |
---|
| 591 | def __init__(self,**kw): |
---|
| 592 | super(UninstallContext,self).__init__(**kw) |
---|
| 593 | self.is_install=UNINSTALL |
---|
| 594 | def do_install(self,src,tgt,chmod=Utils.O644): |
---|
| 595 | if not self.progress_bar: |
---|
| 596 | Logs.info('- remove %s'%tgt) |
---|
| 597 | self.uninstall.append(tgt) |
---|
| 598 | try: |
---|
| 599 | os.remove(tgt) |
---|
| 600 | except OSError ,e: |
---|
| 601 | if e.errno!=errno.ENOENT: |
---|
| 602 | if not getattr(self,'uninstall_error',None): |
---|
| 603 | self.uninstall_error=True |
---|
| 604 | Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') |
---|
| 605 | if Logs.verbose>1: |
---|
| 606 | Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno)) |
---|
| 607 | while tgt: |
---|
| 608 | tgt=os.path.dirname(tgt) |
---|
| 609 | try: |
---|
| 610 | os.rmdir(tgt) |
---|
| 611 | except OSError: |
---|
| 612 | break |
---|
| 613 | def do_link(self,src,tgt): |
---|
| 614 | try: |
---|
| 615 | if not self.progress_bar: |
---|
[c101fe1] | 616 | Logs.info('- remove %s'%tgt) |
---|
[0fa325b] | 617 | os.remove(tgt) |
---|
| 618 | except OSError: |
---|
| 619 | pass |
---|
| 620 | while tgt: |
---|
| 621 | tgt=os.path.dirname(tgt) |
---|
| 622 | try: |
---|
| 623 | os.rmdir(tgt) |
---|
| 624 | except OSError: |
---|
| 625 | break |
---|
| 626 | def execute(self): |
---|
| 627 | try: |
---|
| 628 | def runnable_status(self): |
---|
| 629 | return Task.SKIP_ME |
---|
| 630 | setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status) |
---|
| 631 | setattr(Task.Task,'runnable_status',runnable_status) |
---|
| 632 | super(UninstallContext,self).execute() |
---|
| 633 | finally: |
---|
| 634 | setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back) |
---|
| 635 | class CleanContext(BuildContext): |
---|
| 636 | '''cleans the project''' |
---|
| 637 | cmd='clean' |
---|
| 638 | def execute(self): |
---|
| 639 | self.restore() |
---|
| 640 | if not self.all_envs: |
---|
| 641 | self.load_envs() |
---|
| 642 | self.recurse([self.run_dir]) |
---|
| 643 | try: |
---|
| 644 | self.clean() |
---|
| 645 | finally: |
---|
| 646 | self.store() |
---|
| 647 | def clean(self): |
---|
| 648 | Logs.debug('build: clean called') |
---|
| 649 | if self.bldnode!=self.srcnode: |
---|
| 650 | lst=[] |
---|
| 651 | for e in self.all_envs.values(): |
---|
| 652 | lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES]) |
---|
| 653 | for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True): |
---|
| 654 | if n in lst: |
---|
| 655 | continue |
---|
| 656 | n.delete() |
---|
| 657 | self.root.children={} |
---|
| 658 | for v in'node_deps task_sigs raw_deps'.split(): |
---|
| 659 | setattr(self,v,{}) |
---|
| 660 | class ListContext(BuildContext): |
---|
| 661 | '''lists the targets to execute''' |
---|
| 662 | cmd='list' |
---|
| 663 | def execute(self): |
---|
| 664 | self.restore() |
---|
| 665 | if not self.all_envs: |
---|
| 666 | self.load_envs() |
---|
| 667 | self.recurse([self.run_dir]) |
---|
| 668 | self.pre_build() |
---|
| 669 | self.timer=Utils.Timer() |
---|
| 670 | for g in self.groups: |
---|
| 671 | for tg in g: |
---|
| 672 | try: |
---|
| 673 | f=tg.post |
---|
| 674 | except AttributeError: |
---|
| 675 | pass |
---|
| 676 | else: |
---|
| 677 | f() |
---|
| 678 | try: |
---|
| 679 | self.get_tgen_by_name('') |
---|
| 680 | except Exception: |
---|
| 681 | pass |
---|
| 682 | lst=list(self.task_gen_cache_names.keys()) |
---|
| 683 | lst.sort() |
---|
| 684 | for k in lst: |
---|
| 685 | Logs.pprint('GREEN',k) |
---|
| 686 | class StepContext(BuildContext): |
---|
| 687 | '''executes tasks in a step-by-step fashion, for debugging''' |
---|
| 688 | cmd='step' |
---|
| 689 | def __init__(self,**kw): |
---|
| 690 | super(StepContext,self).__init__(**kw) |
---|
| 691 | self.files=Options.options.files |
---|
| 692 | def compile(self): |
---|
| 693 | if not self.files: |
---|
| 694 | Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') |
---|
| 695 | BuildContext.compile(self) |
---|
| 696 | return |
---|
| 697 | targets=None |
---|
| 698 | if self.targets and self.targets!='*': |
---|
| 699 | targets=self.targets.split(',') |
---|
| 700 | for g in self.groups: |
---|
| 701 | for tg in g: |
---|
| 702 | if targets and tg.name not in targets: |
---|
| 703 | continue |
---|
| 704 | try: |
---|
| 705 | f=tg.post |
---|
| 706 | except AttributeError: |
---|
| 707 | pass |
---|
| 708 | else: |
---|
| 709 | f() |
---|
| 710 | for pat in self.files.split(','): |
---|
| 711 | matcher=self.get_matcher(pat) |
---|
| 712 | for tg in g: |
---|
| 713 | if isinstance(tg,Task.TaskBase): |
---|
| 714 | lst=[tg] |
---|
| 715 | else: |
---|
| 716 | lst=tg.tasks |
---|
| 717 | for tsk in lst: |
---|
| 718 | do_exec=False |
---|
| 719 | for node in getattr(tsk,'inputs',[]): |
---|
| 720 | if matcher(node,output=False): |
---|
| 721 | do_exec=True |
---|
| 722 | break |
---|
| 723 | for node in getattr(tsk,'outputs',[]): |
---|
| 724 | if matcher(node,output=True): |
---|
| 725 | do_exec=True |
---|
| 726 | break |
---|
| 727 | if do_exec: |
---|
| 728 | ret=tsk.run() |
---|
| 729 | Logs.info('%s -> exit %r'%(str(tsk),ret)) |
---|
| 730 | def get_matcher(self,pat): |
---|
| 731 | inn=True |
---|
| 732 | out=True |
---|
| 733 | if pat.startswith('in:'): |
---|
| 734 | out=False |
---|
| 735 | pat=pat.replace('in:','') |
---|
| 736 | elif pat.startswith('out:'): |
---|
| 737 | inn=False |
---|
| 738 | pat=pat.replace('out:','') |
---|
| 739 | anode=self.root.find_node(pat) |
---|
| 740 | pattern=None |
---|
| 741 | if not anode: |
---|
| 742 | if not pat.startswith('^'): |
---|
| 743 | pat='^.+?%s'%pat |
---|
| 744 | if not pat.endswith('$'): |
---|
| 745 | pat='%s$'%pat |
---|
| 746 | pattern=re.compile(pat) |
---|
| 747 | def match(node,output): |
---|
| 748 | if output==True and not out: |
---|
| 749 | return False |
---|
| 750 | if output==False and not inn: |
---|
| 751 | return False |
---|
| 752 | if anode: |
---|
| 753 | return anode==node |
---|
| 754 | else: |
---|
| 755 | return pattern.match(node.abspath()) |
---|
| 756 | return match |
---|
| 757 | BuildContext.store=Utils.nogc(BuildContext.store) |
---|
| 758 | BuildContext.restore=Utils.nogc(BuildContext.restore) |
---|