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,re,shlex 6from waflib import Build,Utils,Task,Options,Logs,Errors,Runner 7from waflib.TaskGen import after_method,feature 8from waflib.Configure import conf 9WAF_CONFIG_H='config.h' 10DEFKEYS='define_key' 11INCKEYS='include_key' 12cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',} 13SNIP_FUNCTION=''' 14int main(int argc, char **argv) { 15 void (*p)(); 16 (void)argc; (void)argv; 17 p=(void(*)())(%s); 18 return !p; 19} 20''' 21SNIP_TYPE=''' 22int main(int argc, char **argv) { 23 (void)argc; (void)argv; 24 if ((%(type_name)s *) 0) return 0; 25 if (sizeof (%(type_name)s)) return 0; 26 return 1; 27} 28''' 29SNIP_EMPTY_PROGRAM=''' 30int main(int argc, char **argv) { 31 (void)argc; (void)argv; 32 return 0; 33} 34''' 35SNIP_FIELD=''' 36int main(int argc, char **argv) { 37 char *off; 38 (void)argc; (void)argv; 39 off = (char*) &((%(type_name)s*)0)->%(field_name)s; 40 return (size_t) off < sizeof(%(type_name)s); 41} 42''' 43MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'cygwin','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'} 44MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh','__xtensa__':'xtensa',} 45@conf 46def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None): 47 assert(isinstance(line,str)) 48 env=env or self.env 49 if posix is None: 50 posix=True 51 if'\\'in line: 52 posix=('\\ 'in line)or('\\\\'in line) 53 lex=shlex.shlex(line,posix=posix) 54 lex.whitespace_split=True 55 lex.commenters='' 56 lst=list(lex) 57 uselib=uselib_store 58 def app(var,val): 59 env.append_value('%s_%s'%(var,uselib),val) 60 def appu(var,val): 61 env.append_unique('%s_%s'%(var,uselib),val) 62 static=False 63 while lst: 64 x=lst.pop(0) 65 st=x[:2] 66 ot=x[2:] 67 if st=='-I'or st=='/I': 68 if not ot: 69 ot=lst.pop(0) 70 appu('INCLUDES',ot) 71 elif st=='-i': 72 tmp=[x,lst.pop(0)] 73 app('CFLAGS',tmp) 74 app('CXXFLAGS',tmp) 75 elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'): 76 if not ot: 77 ot=lst.pop(0) 78 app('DEFINES',ot) 79 elif st=='-l': 80 if not ot: 81 ot=lst.pop(0) 82 prefix='STLIB'if(force_static or static)else'LIB' 83 app(prefix,ot) 84 elif st=='-L': 85 if not ot: 86 ot=lst.pop(0) 87 prefix='STLIBPATH'if(force_static or static)else'LIBPATH' 88 appu(prefix,ot) 89 elif x.startswith('/LIBPATH:'): 90 prefix='STLIBPATH'if(force_static or static)else'LIBPATH' 91 appu(prefix,x.replace('/LIBPATH:','')) 92 elif x.startswith('-std='): 93 prefix='CXXFLAGS'if'++'in x else'CFLAGS' 94 app(prefix,x) 95 elif x=='-pthread'or x.startswith('+'): 96 app('CFLAGS',x) 97 app('CXXFLAGS',x) 98 app('LINKFLAGS',x) 99 elif x=='-framework': 100 appu('FRAMEWORK',lst.pop(0)) 101 elif x.startswith('-F'): 102 appu('FRAMEWORKPATH',x[2:]) 103 elif x=='-Wl,-rpath'or x=='-Wl,-R': 104 app('RPATH',lst.pop(0).lstrip('-Wl,')) 105 elif x.startswith('-Wl,-R,'): 106 app('RPATH',x[7:]) 107 elif x.startswith('-Wl,-R'): 108 app('RPATH',x[6:]) 109 elif x.startswith('-Wl,-rpath,'): 110 app('RPATH',x[11:]) 111 elif x=='-Wl,-Bstatic'or x=='-Bstatic': 112 static=True 113 elif x=='-Wl,-Bdynamic'or x=='-Bdynamic': 114 static=False 115 elif x.startswith('-Wl'): 116 app('LINKFLAGS',x) 117 elif x.startswith(('-m','-f','-dynamic')): 118 app('CFLAGS',x) 119 app('CXXFLAGS',x) 120 elif x.startswith('-bundle'): 121 app('LINKFLAGS',x) 122 elif x.startswith(('-undefined','-Xlinker')): 123 arg=lst.pop(0) 124 app('LINKFLAGS',[x,arg]) 125 elif x.startswith(('-arch','-isysroot')): 126 tmp=[x,lst.pop(0)] 127 app('CFLAGS',tmp) 128 app('CXXFLAGS',tmp) 129 app('LINKFLAGS',tmp) 130 elif x.endswith(('.a','.so','.dylib','.lib')): 131 appu('LINKFLAGS',x) 132@conf 133def validate_cfg(self,kw): 134 if not'path'in kw: 135 if not self.env.PKGCONFIG: 136 self.find_program('pkg-config',var='PKGCONFIG') 137 kw['path']=self.env.PKGCONFIG 138 if'atleast_pkgconfig_version'in kw: 139 if not'msg'in kw: 140 kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version'] 141 return 142 if not'okmsg'in kw: 143 kw['okmsg']='yes' 144 if not'errmsg'in kw: 145 kw['errmsg']='not found' 146 if'modversion'in kw: 147 if not'msg'in kw: 148 kw['msg']='Checking for %r version'%kw['modversion'] 149 if not'uselib_store'in kw: 150 kw['uselib_store']=kw['modversion'] 151 if not'define_name'in kw: 152 kw['define_name']='%s_VERSION'%Utils.quote_define_name(kw['uselib_store']) 153 return 154 if not'package'in kw: 155 raise ValueError('a package name is required') 156 if not'uselib_store'in kw: 157 kw['uselib_store']=kw['package'].upper() 158 if not'define_name'in kw: 159 kw['define_name']=self.have_define(kw['uselib_store']) 160 if not'msg'in kw: 161 kw['msg']='Checking for %r'%(kw['package']or kw['path']) 162 for x in cfg_ver: 163 y=x.replace('-','_') 164 if y in kw: 165 package=kw['package'] 166 if Logs.verbose: 167 Logs.warn('Passing %r to conf.check_cfg() is obsolete, pass parameters directly, eg:',y) 168 Logs.warn(" conf.check_cfg(package='%s', args=['--libs', '--cflags', '%s >= 1.6'])",package,package) 169 if not'msg'in kw: 170 kw['msg']='Checking for %r %s %s'%(package,cfg_ver[x],kw[y]) 171 break 172@conf 173def exec_cfg(self,kw): 174 path=Utils.to_list(kw['path']) 175 env=self.env.env or None 176 if kw.get('pkg_config_path'): 177 if not env: 178 env=dict(self.environ) 179 env['PKG_CONFIG_PATH']=kw['pkg_config_path'] 180 def define_it(): 181 define_name=kw['define_name'] 182 if kw.get('global_define',1): 183 self.define(define_name,1,False) 184 else: 185 self.env.append_unique('DEFINES_%s'%kw['uselib_store'],"%s=1"%define_name) 186 if kw.get('add_have_to_env',1): 187 self.env[define_name]=1 188 if'atleast_pkgconfig_version'in kw: 189 cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']] 190 self.cmd_and_log(cmd,env=env) 191 if not'okmsg'in kw: 192 kw['okmsg']='yes' 193 return 194 for x in cfg_ver: 195 y=x.replace('-','_') 196 if y in kw: 197 self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']],env=env) 198 if not'okmsg'in kw: 199 kw['okmsg']='yes' 200 define_it() 201 break 202 if'modversion'in kw: 203 version=self.cmd_and_log(path+['--modversion',kw['modversion']],env=env).strip() 204 self.define(kw['define_name'],version) 205 return version 206 lst=[]+path 207 defi=kw.get('define_variable') 208 if not defi: 209 defi=self.env.PKG_CONFIG_DEFINES or{} 210 for key,val in defi.items(): 211 lst.append('--define-variable=%s=%s'%(key,val)) 212 static=kw.get('force_static',False) 213 if'args'in kw: 214 args=Utils.to_list(kw['args']) 215 if'--static'in args or'--static-libs'in args: 216 static=True 217 lst+=args 218 lst.extend(Utils.to_list(kw['package'])) 219 if'variables'in kw: 220 v_env=kw.get('env',self.env) 221 vars=Utils.to_list(kw['variables']) 222 for v in vars: 223 val=self.cmd_and_log(lst+['--variable='+v],env=env).strip() 224 var='%s_%s'%(kw['uselib_store'],v) 225 v_env[var]=val 226 if not'okmsg'in kw: 227 kw['okmsg']='yes' 228 return 229 ret=self.cmd_and_log(lst,env=env) 230 if not'okmsg'in kw: 231 kw['okmsg']='yes' 232 define_it() 233 self.parse_flags(ret,kw['uselib_store'],kw.get('env',self.env),force_static=static,posix=kw.get('posix')) 234 return ret 235@conf 236def check_cfg(self,*k,**kw): 237 if k: 238 lst=k[0].split() 239 kw['package']=lst[0] 240 kw['args']=' '.join(lst[1:]) 241 self.validate_cfg(kw) 242 if'msg'in kw: 243 self.start_msg(kw['msg'],**kw) 244 ret=None 245 try: 246 ret=self.exec_cfg(kw) 247 except self.errors.WafError: 248 if'errmsg'in kw: 249 self.end_msg(kw['errmsg'],'YELLOW',**kw) 250 if Logs.verbose>1: 251 raise 252 else: 253 self.fatal('The configuration failed') 254 else: 255 if not ret: 256 ret=True 257 kw['success']=ret 258 if'okmsg'in kw: 259 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) 260 return ret 261def build_fun(bld): 262 if bld.kw['compile_filename']: 263 node=bld.srcnode.make_node(bld.kw['compile_filename']) 264 node.write(bld.kw['code']) 265 o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog') 266 for k,v in bld.kw.items(): 267 setattr(o,k,v) 268 if not bld.kw.get('quiet'): 269 bld.conf.to_log("==>\n%s\n<=="%bld.kw['code']) 270@conf 271def validate_c(self,kw): 272 if not'build_fun'in kw: 273 kw['build_fun']=build_fun 274 if not'env'in kw: 275 kw['env']=self.env.derive() 276 env=kw['env'] 277 if not'compiler'in kw and not'features'in kw: 278 kw['compiler']='c' 279 if env.CXX_NAME and Task.classes.get('cxx'): 280 kw['compiler']='cxx' 281 if not self.env.CXX: 282 self.fatal('a c++ compiler is required') 283 else: 284 if not self.env.CC: 285 self.fatal('a c compiler is required') 286 if not'compile_mode'in kw: 287 kw['compile_mode']='c' 288 if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx': 289 kw['compile_mode']='cxx' 290 if not'type'in kw: 291 kw['type']='cprogram' 292 if not'features'in kw: 293 if not'header_name'in kw or kw.get('link_header_test',True): 294 kw['features']=[kw['compile_mode'],kw['type']] 295 else: 296 kw['features']=[kw['compile_mode']] 297 else: 298 kw['features']=Utils.to_list(kw['features']) 299 if not'compile_filename'in kw: 300 kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'') 301 def to_header(dct): 302 if'header_name'in dct: 303 dct=Utils.to_list(dct['header_name']) 304 return''.join(['#include <%s>\n'%x for x in dct]) 305 return'' 306 if'framework_name'in kw: 307 fwkname=kw['framework_name'] 308 if not'uselib_store'in kw: 309 kw['uselib_store']=fwkname.upper() 310 if not kw.get('no_header',False): 311 if not'header_name'in kw: 312 kw['header_name']=[] 313 fwk='%s/%s.h'%(fwkname,fwkname) 314 if kw.get('remove_dot_h'): 315 fwk=fwk[:-2] 316 kw['header_name']=Utils.to_list(kw['header_name'])+[fwk] 317 kw['msg']='Checking for framework %s'%fwkname 318 kw['framework']=fwkname 319 if'function_name'in kw: 320 fu=kw['function_name'] 321 if not'msg'in kw: 322 kw['msg']='Checking for function %s'%fu 323 kw['code']=to_header(kw)+SNIP_FUNCTION%fu 324 if not'uselib_store'in kw: 325 kw['uselib_store']=fu.upper() 326 if not'define_name'in kw: 327 kw['define_name']=self.have_define(fu) 328 elif'type_name'in kw: 329 tu=kw['type_name'] 330 if not'header_name'in kw: 331 kw['header_name']='stdint.h' 332 if'field_name'in kw: 333 field=kw['field_name'] 334 kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field} 335 if not'msg'in kw: 336 kw['msg']='Checking for field %s in %s'%(field,tu) 337 if not'define_name'in kw: 338 kw['define_name']=self.have_define((tu+'_'+field).upper()) 339 else: 340 kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu} 341 if not'msg'in kw: 342 kw['msg']='Checking for type %s'%tu 343 if not'define_name'in kw: 344 kw['define_name']=self.have_define(tu.upper()) 345 elif'header_name'in kw: 346 if not'msg'in kw: 347 kw['msg']='Checking for header %s'%kw['header_name'] 348 l=Utils.to_list(kw['header_name']) 349 assert len(l),'list of headers in header_name is empty' 350 kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM 351 if not'uselib_store'in kw: 352 kw['uselib_store']=l[0].upper() 353 if not'define_name'in kw: 354 kw['define_name']=self.have_define(l[0]) 355 if'lib'in kw: 356 if not'msg'in kw: 357 kw['msg']='Checking for library %s'%kw['lib'] 358 if not'uselib_store'in kw: 359 kw['uselib_store']=kw['lib'].upper() 360 if'stlib'in kw: 361 if not'msg'in kw: 362 kw['msg']='Checking for static library %s'%kw['stlib'] 363 if not'uselib_store'in kw: 364 kw['uselib_store']=kw['stlib'].upper() 365 if'fragment'in kw: 366 kw['code']=kw['fragment'] 367 if not'msg'in kw: 368 kw['msg']='Checking for code snippet' 369 if not'errmsg'in kw: 370 kw['errmsg']='no' 371 for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')): 372 if flagsname in kw: 373 if not'msg'in kw: 374 kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname]) 375 if not'errmsg'in kw: 376 kw['errmsg']='no' 377 if not'execute'in kw: 378 kw['execute']=False 379 if kw['execute']: 380 kw['features'].append('test_exec') 381 kw['chmod']=Utils.O755 382 if not'errmsg'in kw: 383 kw['errmsg']='not found' 384 if not'okmsg'in kw: 385 kw['okmsg']='yes' 386 if not'code'in kw: 387 kw['code']=SNIP_EMPTY_PROGRAM 388 if self.env[INCKEYS]: 389 kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code'] 390 if kw.get('merge_config_header',False)or env.merge_config_header: 391 kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code']) 392 env.DEFINES=[] 393 if not kw.get('success'):kw['success']=None 394 if'define_name'in kw: 395 self.undefine(kw['define_name']) 396 if not'msg'in kw: 397 self.fatal('missing "msg" in conf.check(...)') 398@conf 399def post_check(self,*k,**kw): 400 is_success=0 401 if kw['execute']: 402 if kw['success']is not None: 403 if kw.get('define_ret',False): 404 is_success=kw['success'] 405 else: 406 is_success=(kw['success']==0) 407 else: 408 is_success=(kw['success']==0) 409 if kw.get('define_name'): 410 comment=kw.get('comment','') 411 define_name=kw['define_name'] 412 if kw['execute']and kw.get('define_ret')and isinstance(is_success,str): 413 if kw.get('global_define',1): 414 self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment) 415 else: 416 if kw.get('quote',1): 417 succ='"%s"'%is_success 418 else: 419 succ=int(is_success) 420 val='%s=%s'%(define_name,succ) 421 var='DEFINES_%s'%kw['uselib_store'] 422 self.env.append_value(var,val) 423 else: 424 if kw.get('global_define',1): 425 self.define_cond(define_name,is_success,comment=comment) 426 else: 427 var='DEFINES_%s'%kw['uselib_store'] 428 self.env.append_value(var,'%s=%s'%(define_name,int(is_success))) 429 if kw.get('add_have_to_env',1): 430 if kw.get('uselib_store'): 431 self.env[self.have_define(kw['uselib_store'])]=1 432 else: 433 self.env[define_name]=int(is_success) 434 if'header_name'in kw: 435 if kw.get('auto_add_header_name',False): 436 self.env.append_value(INCKEYS,Utils.to_list(kw['header_name'])) 437 if is_success and'uselib_store'in kw: 438 from waflib.Tools import ccroot 439 _vars=set([]) 440 for x in kw['features']: 441 if x in ccroot.USELIB_VARS: 442 _vars|=ccroot.USELIB_VARS[x] 443 for k in _vars: 444 x=k.lower() 445 if x in kw: 446 self.env.append_value(k+'_'+kw['uselib_store'],kw[x]) 447 return is_success 448@conf 449def check(self,*k,**kw): 450 self.validate_c(kw) 451 self.start_msg(kw['msg'],**kw) 452 ret=None 453 try: 454 ret=self.run_build(*k,**kw) 455 except self.errors.ConfigurationError: 456 self.end_msg(kw['errmsg'],'YELLOW',**kw) 457 if Logs.verbose>1: 458 raise 459 else: 460 self.fatal('The configuration failed') 461 else: 462 kw['success']=ret 463 ret=self.post_check(*k,**kw) 464 if not ret: 465 self.end_msg(kw['errmsg'],'YELLOW',**kw) 466 self.fatal('The configuration failed %r'%ret) 467 else: 468 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) 469 return ret 470class test_exec(Task.Task): 471 color='PINK' 472 def run(self): 473 if getattr(self.generator,'rpath',None): 474 if getattr(self.generator,'define_ret',False): 475 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()]) 476 else: 477 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()]) 478 else: 479 env=self.env.env or{} 480 env.update(dict(os.environ)) 481 for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'): 482 env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'') 483 if getattr(self.generator,'define_ret',False): 484 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env) 485 else: 486 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env) 487@feature('test_exec') 488@after_method('apply_link') 489def test_exec_fun(self): 490 self.create_task('test_exec',self.link_task.outputs[0]) 491@conf 492def check_cxx(self,*k,**kw): 493 kw['compiler']='cxx' 494 return self.check(*k,**kw) 495@conf 496def check_cc(self,*k,**kw): 497 kw['compiler']='c' 498 return self.check(*k,**kw) 499@conf 500def set_define_comment(self,key,comment): 501 coms=self.env.DEFINE_COMMENTS 502 if not coms: 503 coms=self.env.DEFINE_COMMENTS={} 504 coms[key]=comment or'' 505@conf 506def get_define_comment(self,key): 507 coms=self.env.DEFINE_COMMENTS or{} 508 return coms.get(key,'') 509@conf 510def define(self,key,val,quote=True,comment=''): 511 assert isinstance(key,str) 512 if not key: 513 return 514 if val is True: 515 val=1 516 elif val in(False,None): 517 val=0 518 if isinstance(val,int)or isinstance(val,float): 519 s='%s=%s' 520 else: 521 s=quote and'%s="%s"'or'%s=%s' 522 app=s%(key,str(val)) 523 ban=key+'=' 524 lst=self.env.DEFINES 525 for x in lst: 526 if x.startswith(ban): 527 lst[lst.index(x)]=app 528 break 529 else: 530 self.env.append_value('DEFINES',app) 531 self.env.append_unique(DEFKEYS,key) 532 self.set_define_comment(key,comment) 533@conf 534def undefine(self,key,comment=''): 535 assert isinstance(key,str) 536 if not key: 537 return 538 ban=key+'=' 539 lst=[x for x in self.env.DEFINES if not x.startswith(ban)] 540 self.env.DEFINES=lst 541 self.env.append_unique(DEFKEYS,key) 542 self.set_define_comment(key,comment) 543@conf 544def define_cond(self,key,val,comment=''): 545 assert isinstance(key,str) 546 if not key: 547 return 548 if val: 549 self.define(key,1,comment=comment) 550 else: 551 self.undefine(key,comment=comment) 552@conf 553def is_defined(self,key): 554 assert key and isinstance(key,str) 555 ban=key+'=' 556 for x in self.env.DEFINES: 557 if x.startswith(ban): 558 return True 559 return False 560@conf 561def get_define(self,key): 562 assert key and isinstance(key,str) 563 ban=key+'=' 564 for x in self.env.DEFINES: 565 if x.startswith(ban): 566 return x[len(ban):] 567 return None 568@conf 569def have_define(self,key): 570 return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key) 571@conf 572def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''): 573 if not configfile:configfile=WAF_CONFIG_H 574 waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile) 575 node=top and self.bldnode or self.path.get_bld() 576 node=node.make_node(configfile) 577 node.parent.mkdir() 578 lst=['/* WARNING! All changes made to this file will be lost! */\n'] 579 lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard)) 580 lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix)) 581 lst.append('\n#endif /* %s */\n'%waf_guard) 582 node.write('\n'.join(lst)) 583 self.env.append_unique(Build.CFG_FILES,[node.abspath()]) 584 if remove: 585 for key in self.env[DEFKEYS]: 586 self.undefine(key) 587 self.env[DEFKEYS]=[] 588@conf 589def get_config_header(self,defines=True,headers=False,define_prefix=''): 590 lst=[] 591 if self.env.WAF_CONFIG_H_PRELUDE: 592 lst.append(self.env.WAF_CONFIG_H_PRELUDE) 593 if headers: 594 for x in self.env[INCKEYS]: 595 lst.append('#include <%s>'%x) 596 if defines: 597 tbl={} 598 for k in self.env.DEFINES: 599 a,_,b=k.partition('=') 600 tbl[a]=b 601 for k in self.env[DEFKEYS]: 602 caption=self.get_define_comment(k) 603 if caption: 604 caption=' /* %s */'%caption 605 try: 606 txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption) 607 except KeyError: 608 txt='/* #undef %s%s */%s'%(define_prefix,k,caption) 609 lst.append(txt) 610 return"\n".join(lst) 611@conf 612def cc_add_flags(conf): 613 conf.add_os_flags('CPPFLAGS',dup=False) 614 conf.add_os_flags('CFLAGS',dup=False) 615@conf 616def cxx_add_flags(conf): 617 conf.add_os_flags('CPPFLAGS',dup=False) 618 conf.add_os_flags('CXXFLAGS',dup=False) 619@conf 620def link_add_flags(conf): 621 conf.add_os_flags('LINKFLAGS',dup=False) 622 conf.add_os_flags('LDFLAGS',dup=False) 623@conf 624def cc_load_tools(conf): 625 if not conf.env.DEST_OS: 626 conf.env.DEST_OS=Utils.unversioned_sys_platform() 627 conf.load('c') 628@conf 629def cxx_load_tools(conf): 630 if not conf.env.DEST_OS: 631 conf.env.DEST_OS=Utils.unversioned_sys_platform() 632 conf.load('cxx') 633@conf 634def get_cc_version(conf,cc,gcc=False,icc=False,clang=False): 635 cmd=cc+['-dM','-E','-'] 636 env=conf.env.env or None 637 try: 638 out,err=conf.cmd_and_log(cmd,output=0,input='\n'.encode(),env=env) 639 except Exception: 640 conf.fatal('Could not determine the compiler version %r'%cmd) 641 if gcc: 642 if out.find('__INTEL_COMPILER')>=0: 643 conf.fatal('The intel compiler pretends to be gcc') 644 if out.find('__GNUC__')<0 and out.find('__clang__')<0: 645 conf.fatal('Could not determine the compiler type') 646 if icc and out.find('__INTEL_COMPILER')<0: 647 conf.fatal('Not icc/icpc') 648 if clang and out.find('__clang__')<0: 649 conf.fatal('Not clang/clang++') 650 if not clang and out.find('__clang__')>=0: 651 conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') 652 k={} 653 if icc or gcc or clang: 654 out=out.splitlines() 655 for line in out: 656 lst=shlex.split(line) 657 if len(lst)>2: 658 key=lst[1] 659 val=lst[2] 660 k[key]=val 661 def isD(var): 662 return var in k 663 if not conf.env.DEST_OS: 664 conf.env.DEST_OS='' 665 for i in MACRO_TO_DESTOS: 666 if isD(i): 667 conf.env.DEST_OS=MACRO_TO_DESTOS[i] 668 break 669 else: 670 if isD('__APPLE__')and isD('__MACH__'): 671 conf.env.DEST_OS='darwin' 672 elif isD('__unix__'): 673 conf.env.DEST_OS='generic' 674 if isD('__ELF__'): 675 conf.env.DEST_BINFMT='elf' 676 elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'): 677 conf.env.DEST_BINFMT='pe' 678 conf.env.LIBDIR=conf.env.BINDIR 679 elif isD('__APPLE__'): 680 conf.env.DEST_BINFMT='mac-o' 681 if not conf.env.DEST_BINFMT: 682 conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS) 683 for i in MACRO_TO_DEST_CPU: 684 if isD(i): 685 conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i] 686 break 687 Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')])) 688 if icc: 689 ver=k['__INTEL_COMPILER'] 690 conf.env.CC_VERSION=(ver[:-2],ver[-2],ver[-1]) 691 else: 692 if isD('__clang__')and isD('__clang_major__'): 693 conf.env.CC_VERSION=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__']) 694 else: 695 conf.env.CC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0')) 696 return k 697@conf 698def get_xlc_version(conf,cc): 699 cmd=cc+['-qversion'] 700 try: 701 out,err=conf.cmd_and_log(cmd,output=0) 702 except Errors.WafError: 703 conf.fatal('Could not find xlc %r'%cmd) 704 for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",): 705 version_re=re.compile(v,re.I).search 706 match=version_re(out or err) 707 if match: 708 k=match.groupdict() 709 conf.env.CC_VERSION=(k['major'],k['minor']) 710 break 711 else: 712 conf.fatal('Could not determine the XLC version.') 713@conf 714def get_suncc_version(conf,cc): 715 cmd=cc+['-V'] 716 try: 717 out,err=conf.cmd_and_log(cmd,output=0) 718 except Errors.WafError as e: 719 if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')): 720 conf.fatal('Could not find suncc %r'%cmd) 721 out=e.stdout 722 err=e.stderr 723 version=(out or err) 724 version=version.splitlines()[0] 725 version_re=re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search 726 match=version_re(version) 727 if match: 728 k=match.groupdict() 729 conf.env.CC_VERSION=(k['major'],k['minor']) 730 else: 731 conf.fatal('Could not determine the suncc version.') 732@conf 733def add_as_needed(self): 734 if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME): 735 self.env.append_unique('LINKFLAGS','-Wl,--as-needed') 736class cfgtask(Task.TaskBase): 737 def display(self): 738 return'' 739 def runnable_status(self): 740 return Task.RUN_ME 741 def uid(self): 742 return Utils.SIG_NIL 743 def run(self): 744 conf=self.conf 745 bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath()) 746 bld.env=conf.env 747 bld.init_dirs() 748 bld.in_msg=1 749 bld.logger=self.logger 750 bld.multicheck_task=self 751 args=self.args 752 try: 753 if'func'in args: 754 bld.test(build_fun=args['func'],msg=args.get('msg',''),okmsg=args.get('okmsg',''),errmsg=args.get('errmsg',''),) 755 else: 756 args['multicheck_mandatory']=args.get('mandatory',True) 757 args['mandatory']=True 758 try: 759 bld.check(**args) 760 finally: 761 args['mandatory']=args['multicheck_mandatory'] 762 except Exception: 763 return 1 764@conf 765def multicheck(self,*k,**kw): 766 self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw) 767 for var in('DEFINES',DEFKEYS): 768 self.env.append_value(var,[]) 769 self.env.DEFINE_COMMENTS=self.env.DEFINE_COMMENTS or{} 770 class par(object): 771 def __init__(self): 772 self.keep=False 773 self.task_sigs={} 774 self.progress_bar=0 775 def total(self): 776 return len(tasks) 777 def to_log(self,*k,**kw): 778 return 779 bld=par() 780 bld.keep=kw.get('run_all_tests',True) 781 tasks=[] 782 for dct in k: 783 x=Task.classes['cfgtask'](bld=bld) 784 tasks.append(x) 785 x.args=dct 786 x.bld=bld 787 x.conf=self 788 x.args=dct 789 x.logger=Logs.make_mem_logger(str(id(x)),self.logger) 790 def it(): 791 yield tasks 792 while 1: 793 yield[] 794 bld.producer=p=Runner.Parallel(bld,Options.options.jobs) 795 p.biter=it() 796 p.start() 797 for x in tasks: 798 x.logger.memhandler.flush() 799 if p.error: 800 for x in p.error: 801 if getattr(x,'err_msg',None): 802 self.to_log(x.err_msg) 803 self.end_msg('fail',color='RED') 804 raise Errors.WafError('There is an error in the library, read config.log for more information') 805 failure_count=0 806 for x in tasks: 807 if x.hasrun not in(Task.SUCCESS,Task.NOT_RUN): 808 failure_count+=1 809 if failure_count: 810 self.end_msg(kw.get('errmsg','%s test failed'%failure_count),color='YELLOW',**kw) 811 else: 812 self.end_msg('all ok',**kw) 813 for x in tasks: 814 if'msg'in x.args: 815 self.start_msg(x.args['msg']) 816 if x.hasrun==Task.NOT_RUN: 817 self.end_msg('test cancelled','YELLOW') 818 elif x.hasrun!=Task.SUCCESS: 819 self.end_msg(x.args.get('errmsg','no'),'YELLOW') 820 else: 821 self.end_msg(x.args.get('okmsg','yes'),'GREEN') 822 for x in tasks: 823 if x.hasrun!=Task.SUCCESS: 824 if x.args.get('mandatory',True): 825 self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information') 826