1#! /usr/bin/env python 2# encoding: utf-8 3# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file 4 5import os,shlex,sys,time,re,shutil 6from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors 7WAF_CONFIG_LOG='config.log' 8autoconfig=False 9conf_template='''# project %(app)s configured on %(now)s by 10# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) 11# using %(args)s 12#''' 13class ConfigurationContext(Context.Context): 14 '''configures the project''' 15 cmd='configure' 16 error_handlers=[] 17 def __init__(self,**kw): 18 super(ConfigurationContext,self).__init__(**kw) 19 self.environ=dict(os.environ) 20 self.all_envs={} 21 self.top_dir=None 22 self.out_dir=None 23 self.tools=[] 24 self.hash=0 25 self.files=[] 26 self.tool_cache=[] 27 self.setenv('') 28 def setenv(self,name,env=None): 29 if name not in self.all_envs or env: 30 if not env: 31 env=ConfigSet.ConfigSet() 32 self.prepare_env(env) 33 else: 34 env=env.derive() 35 self.all_envs[name]=env 36 self.variant=name 37 def get_env(self): 38 return self.all_envs[self.variant] 39 def set_env(self,val): 40 self.all_envs[self.variant]=val 41 env=property(get_env,set_env) 42 def init_dirs(self): 43 top=self.top_dir 44 if not top: 45 top=Options.options.top 46 if not top: 47 top=getattr(Context.g_module,Context.TOP,None) 48 if not top: 49 top=self.path.abspath() 50 top=os.path.abspath(top) 51 self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top) 52 assert(self.srcnode) 53 out=self.out_dir 54 if not out: 55 out=Options.options.out 56 if not out: 57 out=getattr(Context.g_module,Context.OUT,None) 58 if not out: 59 out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','') 60 out=os.path.realpath(out) 61 self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out) 62 self.bldnode.mkdir() 63 if not os.path.isdir(self.bldnode.abspath()): 64 conf.fatal('Could not create the build directory %s'%self.bldnode.abspath()) 65 def execute(self): 66 self.init_dirs() 67 self.cachedir=self.bldnode.make_node(Build.CACHE_DIR) 68 self.cachedir.mkdir() 69 path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG) 70 self.logger=Logs.make_logger(path,'cfg') 71 app=getattr(Context.g_module,'APPNAME','') 72 if app: 73 ver=getattr(Context.g_module,'VERSION','') 74 if ver: 75 app="%s (%s)"%(app,ver) 76 params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app} 77 self.to_log(conf_template%params) 78 self.msg('Setting top to',self.srcnode.abspath()) 79 self.msg('Setting out to',self.bldnode.abspath()) 80 if id(self.srcnode)==id(self.bldnode): 81 Logs.warn('Setting top == out') 82 elif id(self.path)!=id(self.srcnode): 83 if self.srcnode.is_child_of(self.path): 84 Logs.warn('Are you certain that you do not want to set top="." ?') 85 super(ConfigurationContext,self).execute() 86 self.store() 87 Context.top_dir=self.srcnode.abspath() 88 Context.out_dir=self.bldnode.abspath() 89 env=ConfigSet.ConfigSet() 90 env.argv=sys.argv 91 env.options=Options.options.__dict__ 92 env.config_cmd=self.cmd 93 env.run_dir=Context.run_dir 94 env.top_dir=Context.top_dir 95 env.out_dir=Context.out_dir 96 env.hash=self.hash 97 env.files=self.files 98 env.environ=dict(self.environ) 99 if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options,'no_lock_in_run'): 100 env.store(os.path.join(Context.run_dir,Options.lockfile)) 101 if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options,'no_lock_in_top'): 102 env.store(os.path.join(Context.top_dir,Options.lockfile)) 103 if not self.env.NO_LOCK_IN_OUT and not getattr(Options.options,'no_lock_in_out'): 104 env.store(os.path.join(Context.out_dir,Options.lockfile)) 105 def prepare_env(self,env): 106 if not env.PREFIX: 107 if Options.options.prefix or Utils.is_win32: 108 env.PREFIX=Utils.sane_path(Options.options.prefix) 109 else: 110 env.PREFIX='' 111 if not env.BINDIR: 112 if Options.options.bindir: 113 env.BINDIR=Utils.sane_path(Options.options.bindir) 114 else: 115 env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env) 116 if not env.LIBDIR: 117 if Options.options.libdir: 118 env.LIBDIR=Utils.sane_path(Options.options.libdir) 119 else: 120 env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env) 121 def store(self): 122 n=self.cachedir.make_node('build.config.py') 123 n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools)) 124 if not self.all_envs: 125 self.fatal('nothing to store in the configuration context!') 126 for key in self.all_envs: 127 tmpenv=self.all_envs[key] 128 tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX)) 129 def load(self,input,tooldir=None,funs=None,with_sys_path=True,cache=False): 130 tools=Utils.to_list(input) 131 if tooldir:tooldir=Utils.to_list(tooldir) 132 for tool in tools: 133 if cache: 134 mag=(tool,id(self.env),tooldir,funs) 135 if mag in self.tool_cache: 136 self.to_log('(tool %s is already loaded, skipping)'%tool) 137 continue 138 self.tool_cache.append(mag) 139 module=None 140 try: 141 module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path) 142 except ImportError as e: 143 self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,sys.path,e)) 144 except Exception as e: 145 self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs)) 146 self.to_log(Utils.ex_stack()) 147 raise 148 if funs is not None: 149 self.eval_rules(funs) 150 else: 151 func=getattr(module,'configure',None) 152 if func: 153 if type(func)is type(Utils.readf):func(self) 154 else:self.eval_rules(func) 155 self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs}) 156 def post_recurse(self,node): 157 super(ConfigurationContext,self).post_recurse(node) 158 self.hash=Utils.h_list((self.hash,node.read('rb'))) 159 self.files.append(node.abspath()) 160 def eval_rules(self,rules): 161 self.rules=Utils.to_list(rules) 162 for x in self.rules: 163 f=getattr(self,x) 164 if not f: 165 self.fatal('No such configuration function %r'%x) 166 f() 167def conf(f): 168 def fun(*k,**kw): 169 mandatory=True 170 if'mandatory'in kw: 171 mandatory=kw['mandatory'] 172 del kw['mandatory'] 173 try: 174 return f(*k,**kw) 175 except Errors.ConfigurationError: 176 if mandatory: 177 raise 178 fun.__name__=f.__name__ 179 setattr(ConfigurationContext,f.__name__,fun) 180 setattr(Build.BuildContext,f.__name__,fun) 181 return f 182@conf 183def add_os_flags(self,var,dest=None,dup=False): 184 try: 185 flags=shlex.split(self.environ[var]) 186 except KeyError: 187 return 188 if dup or''.join(flags)not in''.join(Utils.to_list(self.env[dest or var])): 189 self.env.append_value(dest or var,flags) 190@conf 191def cmd_to_list(self,cmd): 192 if isinstance(cmd,str): 193 if os.path.isfile(cmd): 194 return[cmd] 195 if os.sep=='/': 196 return shlex.split(cmd) 197 else: 198 try: 199 return shlex.split(cmd,posix=False) 200 except TypeError: 201 return shlex.split(cmd) 202 return cmd 203@conf 204def check_waf_version(self,mini='1.8.99',maxi='2.0.0',**kw): 205 self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw) 206 ver=Context.HEXVERSION 207 if Utils.num2ver(mini)>ver: 208 self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver)) 209 if Utils.num2ver(maxi)<ver: 210 self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver)) 211 self.end_msg('ok',**kw) 212@conf 213def find_file(self,filename,path_list=[]): 214 for n in Utils.to_list(filename): 215 for d in Utils.to_list(path_list): 216 p=os.path.expanduser(os.path.join(d,n)) 217 if os.path.exists(p): 218 return p 219 self.fatal('Could not find %r'%filename) 220@conf 221def find_program(self,filename,**kw): 222 exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py') 223 environ=kw.get('environ',getattr(self,'environ',os.environ)) 224 ret='' 225 filename=Utils.to_list(filename) 226 msg=kw.get('msg',', '.join(filename)) 227 var=kw.get('var','') 228 if not var: 229 var=re.sub(r'[-.]','_',filename[0].upper()) 230 path_list=kw.get('path_list','') 231 if path_list: 232 path_list=Utils.to_list(path_list) 233 else: 234 path_list=environ.get('PATH','').split(os.pathsep) 235 if kw.get('value'): 236 ret=self.cmd_to_list(kw['value']) 237 elif var in environ: 238 ret=self.cmd_to_list(environ[var]) 239 elif self.env[var]: 240 ret=self.cmd_to_list(self.env[var]) 241 else: 242 if not ret: 243 ret=self.find_binary(filename,exts.split(','),path_list) 244 if not ret and Utils.winreg: 245 ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename) 246 if not ret and Utils.winreg: 247 ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename) 248 ret=self.cmd_to_list(ret) 249 if ret: 250 if len(ret)==1: 251 retmsg=ret[0] 252 else: 253 retmsg=ret 254 else: 255 retmsg=False 256 self.msg('Checking for program %r'%msg,retmsg,**kw) 257 if not kw.get('quiet'): 258 self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret)) 259 if not ret: 260 self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename) 261 interpreter=kw.get('interpreter') 262 if interpreter is None: 263 if not Utils.check_exe(ret[0],env=environ): 264 self.fatal('Program %r is not executable'%ret) 265 self.env[var]=ret 266 else: 267 self.env[var]=self.env[interpreter]+ret 268 return ret 269@conf 270def find_binary(self,filenames,exts,paths): 271 for f in filenames: 272 for ext in exts: 273 exe_name=f+ext 274 if os.path.isabs(exe_name): 275 if os.path.isfile(exe_name): 276 return exe_name 277 else: 278 for path in paths: 279 x=os.path.expanduser(os.path.join(path,exe_name)) 280 if os.path.isfile(x): 281 return x 282 return None 283@conf 284def run_build(self,*k,**kw): 285 lst=[str(v)for(p,v)in kw.items()if p!='env'] 286 h=Utils.h_list(lst) 287 dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h) 288 try: 289 os.makedirs(dir) 290 except OSError: 291 pass 292 try: 293 os.stat(dir) 294 except OSError: 295 self.fatal('cannot use the configuration test folder %r'%dir) 296 cachemode=getattr(Options.options,'confcache',None) 297 if cachemode==1: 298 try: 299 proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build')) 300 except EnvironmentError: 301 pass 302 else: 303 ret=proj['cache_run_build'] 304 if isinstance(ret,str)and ret.startswith('Test does not build'): 305 self.fatal(ret) 306 return ret 307 bdir=os.path.join(dir,'testbuild') 308 if not os.path.exists(bdir): 309 os.makedirs(bdir) 310 self.test_bld=bld=Context.create_context('build',top_dir=dir,out_dir=bdir) 311 bld.init_dirs() 312 bld.progress_bar=0 313 bld.targets='*' 314 bld.logger=self.logger 315 bld.all_envs.update(self.all_envs) 316 bld.env=kw['env'] 317 bld.kw=kw 318 bld.conf=self 319 kw['build_fun'](bld) 320 ret=-1 321 try: 322 try: 323 bld.compile() 324 except Errors.WafError: 325 ret='Test does not build: %s'%Utils.ex_stack() 326 self.fatal(ret) 327 else: 328 ret=getattr(bld,'retval',0) 329 finally: 330 if cachemode==1: 331 proj=ConfigSet.ConfigSet() 332 proj['cache_run_build']=ret 333 proj.store(os.path.join(dir,'cache_run_build')) 334 else: 335 shutil.rmtree(dir) 336 return ret 337@conf 338def ret_msg(self,msg,args): 339 if isinstance(msg,str): 340 return msg 341 return msg(args) 342@conf 343def test(self,*k,**kw): 344 if not'env'in kw: 345 kw['env']=self.env.derive() 346 if kw.get('validate'): 347 kw['validate'](kw) 348 self.start_msg(kw['msg'],**kw) 349 ret=None 350 try: 351 ret=self.run_build(*k,**kw) 352 except self.errors.ConfigurationError: 353 self.end_msg(kw['errmsg'],'YELLOW',**kw) 354 if Logs.verbose>1: 355 raise 356 else: 357 self.fatal('The configuration failed') 358 else: 359 kw['success']=ret 360 if kw.get('post_check'): 361 ret=kw['post_check'](kw) 362 if ret: 363 self.end_msg(kw['errmsg'],'YELLOW',**kw) 364 self.fatal('The configuration failed %r'%ret) 365 else: 366 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) 367 return ret 368