3 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
6 from waflib import Build,Utils,Task,Options,Logs,Errors,ConfigSet,Runner
7 from waflib.TaskGen import after_method,feature
8 from waflib.Configure import conf
9 WAF_CONFIG_H='config.h'
12 cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
14 int main(int argc, char **argv) {
16 (void)argc; (void)argv;
22 int 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;
29 SNIP_EMPTY_PROGRAM='''
30 int main(int argc, char **argv) {
31 (void)argc; (void)argv;
36 int main(int argc, char **argv) {
38 (void)argc; (void)argv;
39 off = (char*) &((%(type_name)s*)0)->%(field_name)s;
40 return (size_t) off < sizeof(%(type_name)s);
43 MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'msys','_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'}
44 MACRO_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',}
46 def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None):
47 assert(isinstance(line,str))
52 posix=('\\ 'in line)or('\\\\'in line)
53 lex=shlex.shlex(line,posix=posix)
54 lex.whitespace_split=True
58 appu=env.append_unique
64 if st=='-I'or st=='/I':
65 if not ot:ot=lst.pop(0)
66 appu('INCLUDES_'+uselib,[ot])
71 elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
72 if not ot:ot=lst.pop(0)
73 app('DEFINES_'+uselib,[ot])
75 if not ot:ot=lst.pop(0)
76 prefix=force_static and'STLIB_'or'LIB_'
77 appu(prefix+uselib,[ot])
79 if not ot:ot=lst.pop(0)
80 appu('LIBPATH_'+uselib,[ot])
81 elif x.startswith('/LIBPATH:'):
82 appu('LIBPATH_'+uselib,[x.replace('/LIBPATH:','')])
83 elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
84 app('CFLAGS_'+uselib,[x])
85 app('CXXFLAGS_'+uselib,[x])
86 app('LINKFLAGS_'+uselib,[x])
88 appu('FRAMEWORK_'+uselib,[lst.pop(0)])
89 elif x.startswith('-F'):
90 appu('FRAMEWORKPATH_'+uselib,[x[2:]])
92 app('RPATH_'+uselib,lst.pop(0))
93 elif x.startswith('-Wl,-R'):
94 app('RPATH_'+uselib,x[6:])
95 elif x.startswith('-Wl,-rpath,'):
96 app('RPATH_'+uselib,x[11:])
97 elif x.startswith('-Wl'):
98 app('LINKFLAGS_'+uselib,[x])
99 elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
100 app('CFLAGS_'+uselib,[x])
101 app('CXXFLAGS_'+uselib,[x])
102 elif x.startswith('-bundle'):
103 app('LINKFLAGS_'+uselib,[x])
104 elif x.startswith('-undefined')or x.startswith('-Xlinker'):
106 app('LINKFLAGS_'+uselib,[x,arg])
107 elif x.startswith('-arch')or x.startswith('-isysroot'):
109 app('CFLAGS_'+uselib,tmp)
110 app('CXXFLAGS_'+uselib,tmp)
111 app('LINKFLAGS_'+uselib,tmp)
112 elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
113 appu('LINKFLAGS_'+uselib,[x])
115 def validate_cfg(self,kw):
117 if not self.env.PKGCONFIG:
118 self.find_program('pkg-config',var='PKGCONFIG')
119 kw['path']=self.env.PKGCONFIG
120 if'atleast_pkgconfig_version'in kw:
122 kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
127 kw['errmsg']='not found'
130 kw['msg']='Checking for %r version'%kw['modversion']
132 for x in cfg_ver.keys():
135 if not'package'in kw:
136 raise ValueError('%s requires a package'%x)
138 kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
140 if not'define_name'in kw:
141 pkgname=kw.get('uselib_store',kw['package'].upper())
142 kw['define_name']=self.have_define(pkgname)
143 if not'uselib_store'in kw:
144 self.undefine(kw['define_name'])
146 kw['msg']='Checking for %r'%(kw['package']or kw['path'])
148 def exec_cfg(self,kw):
149 path=Utils.to_list(kw['path'])
151 pkgname=kw.get('uselib_store',kw['package'].upper())
152 if kw.get('global_define'):
153 self.define(self.have_define(kw['package']),1,False)
155 self.env.append_unique('DEFINES_%s'%pkgname,"%s=1"%self.have_define(pkgname))
156 self.env[self.have_define(pkgname)]=1
157 if'atleast_pkgconfig_version'in kw:
158 cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
159 self.cmd_and_log(cmd)
166 self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']])
172 version=self.cmd_and_log(path+['--modversion',kw['modversion']]).strip()
173 self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
176 defi=kw.get('define_variable',None)
178 defi=self.env.PKG_CONFIG_DEFINES or{}
179 for key,val in defi.items():
180 lst.append('--define-variable=%s=%s'%(key,val))
181 static=kw.get('force_static',False)
183 args=Utils.to_list(kw['args'])
184 if'--static'in args or'--static-libs'in args:
187 lst.extend(Utils.to_list(kw['package']))
189 env=kw.get('env',self.env)
190 uselib=kw.get('uselib_store',kw['package'].upper())
191 vars=Utils.to_list(kw['variables'])
193 val=self.cmd_and_log(lst+['--variable='+v]).strip()
194 var='%s_%s'%(uselib,v)
199 ret=self.cmd_and_log(lst)
203 self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static,posix=kw.get('posix',None))
206 def check_cfg(self,*k,**kw):
210 kw['args']=' '.join(lst[1:])
211 self.validate_cfg(kw)
213 self.start_msg(kw['msg'],**kw)
216 ret=self.exec_cfg(kw)
217 except self.errors.WafError:
219 self.end_msg(kw['errmsg'],'YELLOW',**kw)
223 self.fatal('The configuration failed')
229 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
232 if bld.kw['compile_filename']:
233 node=bld.srcnode.make_node(bld.kw['compile_filename'])
234 node.write(bld.kw['code'])
235 o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog')
236 for k,v in bld.kw.items():
238 if not bld.kw.get('quiet',None):
239 bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
241 def validate_c(self,kw):
242 if not'build_fun'in kw:
243 kw['build_fun']=build_fun
245 kw['env']=self.env.derive()
247 if not'compiler'in kw and not'features'in kw:
249 if env['CXX_NAME']and Task.classes.get('cxx',None):
251 if not self.env['CXX']:
252 self.fatal('a c++ compiler is required')
254 if not self.env['CC']:
255 self.fatal('a c compiler is required')
256 if not'compile_mode'in kw:
257 kw['compile_mode']='c'
258 if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
259 kw['compile_mode']='cxx'
261 kw['type']='cprogram'
262 if not'features'in kw:
263 kw['features']=[kw['compile_mode'],kw['type']]
265 kw['features']=Utils.to_list(kw['features'])
266 if not'compile_filename'in kw:
267 kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
269 if'header_name'in dct:
270 dct=Utils.to_list(dct['header_name'])
271 return''.join(['#include <%s>\n'%x for x in dct])
273 if'framework_name'in kw:
274 fwkname=kw['framework_name']
275 if not'uselib_store'in kw:
276 kw['uselib_store']=fwkname.upper()
277 if not kw.get('no_header',False):
278 if not'header_name'in kw:
280 fwk='%s/%s.h'%(fwkname,fwkname)
281 if kw.get('remove_dot_h',None):
283 kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
284 kw['msg']='Checking for framework %s'%fwkname
285 kw['framework']=fwkname
286 if'function_name'in kw:
287 fu=kw['function_name']
289 kw['msg']='Checking for function %s'%fu
290 kw['code']=to_header(kw)+SNIP_FUNCTION%fu
291 if not'uselib_store'in kw:
292 kw['uselib_store']=fu.upper()
293 if not'define_name'in kw:
294 kw['define_name']=self.have_define(fu)
295 elif'type_name'in kw:
297 if not'header_name'in kw:
298 kw['header_name']='stdint.h'
300 field=kw['field_name']
301 kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
303 kw['msg']='Checking for field %s in %s'%(field,tu)
304 if not'define_name'in kw:
305 kw['define_name']=self.have_define((tu+'_'+field).upper())
307 kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
309 kw['msg']='Checking for type %s'%tu
310 if not'define_name'in kw:
311 kw['define_name']=self.have_define(tu.upper())
312 elif'header_name'in kw:
314 kw['msg']='Checking for header %s'%kw['header_name']
315 l=Utils.to_list(kw['header_name'])
316 assert len(l)>0,'list of headers in header_name is empty'
317 kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
318 if not'uselib_store'in kw:
319 kw['uselib_store']=l[0].upper()
320 if not'define_name'in kw:
321 kw['define_name']=self.have_define(l[0])
324 kw['msg']='Checking for library %s'%kw['lib']
325 if not'uselib_store'in kw:
326 kw['uselib_store']=kw['lib'].upper()
329 kw['msg']='Checking for static library %s'%kw['stlib']
330 if not'uselib_store'in kw:
331 kw['uselib_store']=kw['stlib'].upper()
333 kw['code']=kw['fragment']
335 kw['msg']='Checking for code snippet'
338 for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')):
341 kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
344 if not'execute'in kw:
347 kw['features'].append('test_exec')
349 kw['errmsg']='not found'
353 kw['code']=SNIP_EMPTY_PROGRAM
354 if self.env[INCKEYS]:
355 kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
356 if not kw.get('success'):kw['success']=None
357 if'define_name'in kw:
358 self.undefine(kw['define_name'])
360 self.fatal('missing "msg" in conf.check(...)')
362 def post_check(self,*k,**kw):
365 if kw['success']is not None:
366 if kw.get('define_ret',False):
367 is_success=kw['success']
369 is_success=(kw['success']==0)
371 is_success=(kw['success']==0)
372 if'define_name'in kw:
373 if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
374 if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
375 self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
377 self.define_cond(kw['define_name'],is_success)
379 self.define_cond(kw['define_name'],is_success)
380 if'header_name'in kw:
381 if kw.get('auto_add_header_name',False):
382 self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
383 if is_success and'uselib_store'in kw:
384 from waflib.Tools import ccroot
386 for x in kw['features']:
387 if x in ccroot.USELIB_VARS:
388 _vars|=ccroot.USELIB_VARS[x]
393 if isinstance(val,str):
394 val=val.rstrip(os.path.sep)
395 self.env.append_unique(k+'_'+kw['uselib_store'],Utils.to_list(val))
398 def check(self,*k,**kw):
400 self.start_msg(kw['msg'],**kw)
403 ret=self.run_build(*k,**kw)
404 except self.errors.ConfigurationError:
405 self.end_msg(kw['errmsg'],'YELLOW',**kw)
409 self.fatal('The configuration failed')
412 ret=self.post_check(*k,**kw)
414 self.end_msg(kw['errmsg'],'YELLOW',**kw)
415 self.fatal('The configuration failed %r'%ret)
417 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
419 class test_exec(Task.Task):
422 if getattr(self.generator,'rpath',None):
423 if getattr(self.generator,'define_ret',False):
424 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
426 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
428 env=self.env.env or{}
429 env.update(dict(os.environ))
430 for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
431 env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
432 if getattr(self.generator,'define_ret',False):
433 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
435 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
436 @feature('test_exec')
437 @after_method('apply_link')
438 def test_exec_fun(self):
439 self.create_task('test_exec',self.link_task.outputs[0])
441 def check_cxx(self,*k,**kw):
443 return self.check(*k,**kw)
445 def check_cc(self,*k,**kw):
447 return self.check(*k,**kw)
449 def define(self,key,val,quote=True):
450 assert key and isinstance(key,str)
453 elif val in(False,None):
455 if isinstance(val,int)or isinstance(val,float):
458 s=quote and'%s="%s"'or'%s=%s'
461 lst=self.env['DEFINES']
463 if x.startswith(ban):
464 lst[lst.index(x)]=app
467 self.env.append_value('DEFINES',app)
468 self.env.append_unique(DEFKEYS,key)
470 def undefine(self,key):
471 assert key and isinstance(key,str)
473 lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
474 self.env['DEFINES']=lst
475 self.env.append_unique(DEFKEYS,key)
477 def define_cond(self,key,val):
478 assert key and isinstance(key,str)
484 def is_defined(self,key):
485 assert key and isinstance(key,str)
487 for x in self.env['DEFINES']:
488 if x.startswith(ban):
492 def get_define(self,key):
493 assert key and isinstance(key,str)
495 for x in self.env['DEFINES']:
496 if x.startswith(ban):
500 def have_define(self,key):
501 return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
503 def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''):
504 if not configfile:configfile=WAF_CONFIG_H
505 waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
506 node=top and self.bldnode or self.path.get_bld()
507 node=node.make_node(configfile)
509 lst=['/* WARNING! All changes made to this file will be lost! */\n']
510 lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
511 lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
512 lst.append('\n#endif /* %s */\n'%waf_guard)
513 node.write('\n'.join(lst))
514 self.env.append_unique(Build.CFG_FILES,[node.abspath()])
516 for key in self.env[DEFKEYS]:
520 def get_config_header(self,defines=True,headers=False,define_prefix=''):
523 for x in self.env[INCKEYS]:
524 lst.append('#include <%s>'%x)
527 for k in self.env['DEFINES']:
528 a,_,b=k.partition('=')
530 for k in self.env[DEFKEYS]:
532 txt='#define %s%s %s'%(define_prefix,k,tbl[k])
534 txt='/* #undef %s%s */'%(define_prefix,k)
538 def cc_add_flags(conf):
539 conf.add_os_flags('CPPFLAGS','CFLAGS')
540 conf.add_os_flags('CFLAGS')
542 def cxx_add_flags(conf):
543 conf.add_os_flags('CPPFLAGS','CXXFLAGS')
544 conf.add_os_flags('CXXFLAGS')
546 def link_add_flags(conf):
547 conf.add_os_flags('LINKFLAGS')
548 conf.add_os_flags('LDFLAGS','LINKFLAGS')
550 def cc_load_tools(conf):
551 if not conf.env.DEST_OS:
552 conf.env.DEST_OS=Utils.unversioned_sys_platform()
555 def cxx_load_tools(conf):
556 if not conf.env.DEST_OS:
557 conf.env.DEST_OS=Utils.unversioned_sys_platform()
560 def get_cc_version(conf,cc,gcc=False,icc=False,clang=False):
561 cmd=cc+['-dM','-E','-']
562 env=conf.env.env or None
564 p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
566 out=p.communicate()[0]
568 conf.fatal('Could not determine the compiler version %r'%cmd)
569 if not isinstance(out,str):
570 out=out.decode(sys.stdout.encoding or'iso8859-1')
572 if out.find('__INTEL_COMPILER')>=0:
573 conf.fatal('The intel compiler pretends to be gcc')
574 if out.find('__GNUC__')<0 and out.find('__clang__')<0:
575 conf.fatal('Could not determine the compiler type')
576 if icc and out.find('__INTEL_COMPILER')<0:
577 conf.fatal('Not icc/icpc')
578 if clang and out.find('__clang__')<0:
579 conf.fatal('Not clang/clang++')
580 if not clang and out.find('__clang__')>=0:
581 conf.fatal('Could not find g++, if renamed try eg: CXX=g++48 waf configure')
583 if icc or gcc or clang:
586 lst=shlex.split(line)
594 return var in k and k[var]!='0'
595 if not conf.env.DEST_OS:
597 for i in MACRO_TO_DESTOS:
599 conf.env.DEST_OS=MACRO_TO_DESTOS[i]
602 if isD('__APPLE__')and isD('__MACH__'):
603 conf.env.DEST_OS='darwin'
604 elif isD('__unix__'):
605 conf.env.DEST_OS='generic'
607 conf.env.DEST_BINFMT='elf'
608 elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
609 conf.env.DEST_BINFMT='pe'
610 conf.env.LIBDIR=conf.env.BINDIR
611 elif isD('__APPLE__'):
612 conf.env.DEST_BINFMT='mac-o'
613 if not conf.env.DEST_BINFMT:
614 conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
615 for i in MACRO_TO_DEST_CPU:
617 conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
619 Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
621 ver=k['__INTEL_COMPILER']
622 conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
626 conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
628 conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
631 conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
633 conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],0)
636 def get_xlc_version(conf,cc):
639 out,err=conf.cmd_and_log(cmd,output=0)
640 except Errors.WafError:
641 conf.fatal('Could not find xlc %r'%cmd)
642 for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
643 version_re=re.compile(v,re.I).search
644 match=version_re(out or err)
647 conf.env['CC_VERSION']=(k['major'],k['minor'])
650 conf.fatal('Could not determine the XLC version.')
652 def get_suncc_version(conf,cc):
655 out,err=conf.cmd_and_log(cmd,output=0)
656 except Errors.WafError ,e:
657 if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')):
658 conf.fatal('Could not find suncc %r'%cmd)
662 version=version.split('\n')[0]
663 version_re=re.compile(r'cc:\s+sun\s+(c\+\+|c)\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
664 match=version_re(version)
667 conf.env['CC_VERSION']=(k['major'],k['minor'])
669 conf.fatal('Could not determine the suncc version.')
671 def add_as_needed(self):
672 if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
673 self.env.append_unique('LINKFLAGS','-Wl,--as-needed')
674 class cfgtask(Task.TaskBase):
677 def runnable_status(self):
683 bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
687 bld.logger=self.logger
689 bld.check(**self.args)
693 def multicheck(self,*k,**kw):
694 self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw)
698 self.returned_tasks=[]
702 def to_log(self,*k,**kw):
713 x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
718 p=Runner.Parallel(bld,Options.options.jobs)
722 x.logger.memhandler.flush()
724 if x.hasrun!=Task.SUCCESS:
725 self.end_msg(kw.get('errmsg','no'),color='YELLOW',**kw)
726 self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
727 self.end_msg('ok',**kw)