1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
#! /usr/bin/env python
# encoding: utf-8
# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy','uses':'use',}
meths_typos=['__call__','program','shlib','stlib','objects']
import sys
from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
from waflib.Tools import ccroot
def check_same_targets(self):
mp=Utils.defaultdict(list)
uids={}
def check_task(tsk):
if not isinstance(tsk,Task.Task):
return
if hasattr(tsk,'no_errcheck_out'):
return
for node in tsk.outputs:
mp[node].append(tsk)
try:
uids[tsk.uid()].append(tsk)
except KeyError:
uids[tsk.uid()]=[tsk]
for g in self.groups:
for tg in g:
try:
for tsk in tg.tasks:
check_task(tsk)
except AttributeError:
check_task(tg)
dupe=False
for(k,v)in mp.items():
if len(v)>1:
dupe=True
msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"")
Logs.error(msg)
for x in v:
if Logs.verbose>1:
Logs.error(' %d. %r',1+v.index(x),x.generator)
else:
Logs.error(' %d. %r in %r',1+v.index(x),x.generator.name,getattr(x.generator,'path',None))
Logs.error('If you think that this is an error, set no_errcheck_out on the task instance')
if not dupe:
for(k,v)in uids.items():
if len(v)>1:
Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid')
tg_details=tsk.generator.name
if Logs.verbose>2:
tg_details=tsk.generator
for tsk in v:
Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tg_details)
def check_invalid_constraints(self):
feat=set()
for x in list(TaskGen.feats.values()):
feat.union(set(x))
for(x,y)in TaskGen.task_gen.prec.items():
feat.add(x)
feat.union(set(y))
ext=set()
for x in TaskGen.task_gen.mappings.values():
ext.add(x.__name__)
invalid=ext&feat
if invalid:
Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method',list(invalid))
for cls in list(Task.classes.values()):
if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str):
raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)'%(cls,cls.hcode))
for x in('before','after'):
for y in Utils.to_list(getattr(cls,x,[])):
if not Task.classes.get(y):
Logs.error('Erroneous order constraint %r=%r on task class %r',x,y,cls.__name__)
if getattr(cls,'rule',None):
Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")',cls.__name__)
def replace(m):
oldcall=getattr(Build.BuildContext,m)
def call(self,*k,**kw):
ret=oldcall(self,*k,**kw)
for x in typos:
if x in kw:
if x=='iscopy'and'subst'in getattr(self,'features',''):
continue
Logs.error('Fix the typo %r -> %r on %r',x,typos[x],ret)
return ret
setattr(Build.BuildContext,m,call)
def enhance_lib():
for m in meths_typos:
replace(m)
def ant_glob(self,*k,**kw):
if k:
lst=Utils.to_list(k[0])
for pat in lst:
sp=pat.split('/')
if'..'in sp:
Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0])
if'.'in sp:
Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0])
return self.old_ant_glob(*k,**kw)
Node.Node.old_ant_glob=Node.Node.ant_glob
Node.Node.ant_glob=ant_glob
def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False):
if remove:
try:
if self.is_child_of(self.ctx.bldnode)and not quiet:
quiet=True
Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False',self)
except AttributeError:
pass
return self.old_ant_iter(accept,maxdepth,pats,dir,src,remove,quiet)
Node.Node.old_ant_iter=Node.Node.ant_iter
Node.Node.ant_iter=ant_iter
old=Task.is_before
def is_before(t1,t2):
ret=old(t1,t2)
if ret and old(t2,t1):
Logs.error('Contradictory order constraints in classes %r %r',t1,t2)
return ret
Task.is_before=is_before
def check_err_features(self):
lst=self.to_list(self.features)
if'shlib'in lst:
Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
for x in('c','cxx','d','fc'):
if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
Logs.error('%r features is probably missing %r',self,x)
TaskGen.feature('*')(check_err_features)
def check_err_order(self):
if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
for x in('before','after','ext_in','ext_out'):
if hasattr(self,x):
Logs.warn('Erroneous order constraint %r on non-rule based task generator %r',x,self)
else:
for x in('before','after'):
for y in self.to_list(getattr(self,x,[])):
if not Task.classes.get(y):
Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self)
TaskGen.feature('*')(check_err_order)
def check_compile(self):
check_invalid_constraints(self)
try:
ret=self.orig_compile()
finally:
check_same_targets(self)
return ret
Build.BuildContext.orig_compile=Build.BuildContext.compile
Build.BuildContext.compile=check_compile
def use_rec(self,name,**kw):
try:
y=self.bld.get_tgen_by_name(name)
except Errors.WafError:
pass
else:
idx=self.bld.get_group_idx(self)
odx=self.bld.get_group_idx(y)
if odx>idx:
msg="Invalid 'use' across build groups:"
if Logs.verbose>1:
msg+='\n target %r\n uses:\n %r'%(self,y)
else:
msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
raise Errors.WafError(msg)
self.orig_use_rec(name,**kw)
TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
TaskGen.task_gen.use_rec=use_rec
def _getattr(self,name,default=None):
if name=='append'or name=='add':
raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
elif name=='prepend':
raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
if name in self.__slots__:
return super(ConfigSet.ConfigSet,self).__getattr__(name,default)
else:
return self[name]
ConfigSet.ConfigSet.__getattr__=_getattr
def options(opt):
enhance_lib()
|