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):
47 assert(isinstance(line,str))
50 appu=env.append_unique
51 lex=shlex.shlex(line,posix=False)
52 lex.whitespace_split=True
60 if st=='-I'or st=='/I':
61 if not ot:ot=lst.pop(0)
62 appu('INCLUDES_'+uselib,[ot])
67 elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
68 if not ot:ot=lst.pop(0)
69 app('DEFINES_'+uselib,[ot])
71 if not ot:ot=lst.pop(0)
72 prefix=force_static and'STLIB_'or'LIB_'
73 appu(prefix+uselib,[ot])
75 if not ot:ot=lst.pop(0)
76 appu('LIBPATH_'+uselib,[ot])
77 elif x.startswith('/LIBPATH:'):
78 appu('LIBPATH_'+uselib,[x.replace('/LIBPATH:','')])
79 elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
80 app('CFLAGS_'+uselib,[x])
81 app('CXXFLAGS_'+uselib,[x])
82 app('LINKFLAGS_'+uselib,[x])
84 appu('FRAMEWORK_'+uselib,[lst.pop(0)])
85 elif x.startswith('-F'):
86 appu('FRAMEWORKPATH_'+uselib,[x[2:]])
87 elif x.startswith('-Wl'):
88 app('LINKFLAGS_'+uselib,[x])
89 elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
90 app('CFLAGS_'+uselib,[x])
91 app('CXXFLAGS_'+uselib,[x])
92 elif x.startswith('-bundle'):
93 app('LINKFLAGS_'+uselib,[x])
94 elif x.startswith('-undefined'):
96 app('LINKFLAGS_'+uselib,[x,arg])
97 elif x.startswith('-arch')or x.startswith('-isysroot'):
99 app('CFLAGS_'+uselib,tmp)
100 app('CXXFLAGS_'+uselib,tmp)
101 app('LINKFLAGS_'+uselib,tmp)
102 elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
103 appu('LINKFLAGS_'+uselib,[x])
105 def ret_msg(self,f,kw):
106 if isinstance(f,str):
110 def validate_cfg(self,kw):
112 if not self.env.PKGCONFIG:
113 self.find_program('pkg-config',var='PKGCONFIG')
114 kw['path']=self.env.PKGCONFIG
115 if'atleast_pkgconfig_version'in kw:
117 kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
122 kw['errmsg']='not found'
125 kw['msg']='Checking for %r version'%kw['modversion']
127 for x in cfg_ver.keys():
130 if not'package'in kw:
131 raise ValueError('%s requires a package'%x)
133 kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
136 kw['msg']='Checking for %r'%(kw['package']or kw['path'])
138 def exec_cfg(self,kw):
140 self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
141 if'atleast_pkgconfig_version'in kw:
142 cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
143 self.cmd_and_log(cmd)
150 self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']])
156 version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']]).strip()
157 self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
160 defi=kw.get('define_variable',None)
162 defi=self.env.PKG_CONFIG_DEFINES or{}
163 for key,val in defi.items():
164 lst.append('--define-variable=%s=%s'%(key,val))
166 env=kw.get('env',self.env)
167 uselib=kw.get('uselib_store',kw['package'].upper())
168 vars=Utils.to_list(kw['variables'])
170 val=self.cmd_and_log(lst+['--variable='+v]).strip()
171 var='%s_%s'%(uselib,v)
178 args=Utils.to_list(kw['args'])
179 if'--static'in args or'--static-libs'in args:
182 lst.extend(Utils.to_list(kw['package']))
183 ret=self.cmd_and_log(lst)
187 self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
190 def check_cfg(self,*k,**kw):
194 kw['args']=' '.join(lst[1:])
195 self.validate_cfg(kw)
197 self.start_msg(kw['msg'])
200 ret=self.exec_cfg(kw)
201 except self.errors.WafError:
203 self.end_msg(kw['errmsg'],'YELLOW')
207 self.fatal('The configuration failed')
211 self.end_msg(self.ret_msg(kw['okmsg'],kw))
214 def validate_c(self,kw):
216 kw['env']=self.env.derive()
218 if not'compiler'in kw and not'features'in kw:
220 if env['CXX_NAME']and Task.classes.get('cxx',None):
222 if not self.env['CXX']:
223 self.fatal('a c++ compiler is required')
225 if not self.env['CC']:
226 self.fatal('a c compiler is required')
227 if not'compile_mode'in kw:
228 kw['compile_mode']='c'
229 if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
230 kw['compile_mode']='cxx'
232 kw['type']='cprogram'
233 if not'features'in kw:
234 kw['features']=[kw['compile_mode'],kw['type']]
236 kw['features']=Utils.to_list(kw['features'])
237 if not'compile_filename'in kw:
238 kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
240 if'header_name'in dct:
241 dct=Utils.to_list(dct['header_name'])
242 return''.join(['#include <%s>\n'%x for x in dct])
244 if'framework_name'in kw:
245 fwkname=kw['framework_name']
246 if not'uselib_store'in kw:
247 kw['uselib_store']=fwkname.upper()
248 if not kw.get('no_header',False):
249 if not'header_name'in kw:
251 fwk='%s/%s.h'%(fwkname,fwkname)
252 if kw.get('remove_dot_h',None):
254 kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
255 kw['msg']='Checking for framework %s'%fwkname
256 kw['framework']=fwkname
257 if'function_name'in kw:
258 fu=kw['function_name']
260 kw['msg']='Checking for function %s'%fu
261 kw['code']=to_header(kw)+SNIP_FUNCTION%fu
262 if not'uselib_store'in kw:
263 kw['uselib_store']=fu.upper()
264 if not'define_name'in kw:
265 kw['define_name']=self.have_define(fu)
266 elif'type_name'in kw:
268 if not'header_name'in kw:
269 kw['header_name']='stdint.h'
271 field=kw['field_name']
272 kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
274 kw['msg']='Checking for field %s in %s'%(field,tu)
275 if not'define_name'in kw:
276 kw['define_name']=self.have_define((tu+'_'+field).upper())
278 kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
280 kw['msg']='Checking for type %s'%tu
281 if not'define_name'in kw:
282 kw['define_name']=self.have_define(tu.upper())
283 elif'header_name'in kw:
285 kw['msg']='Checking for header %s'%kw['header_name']
286 l=Utils.to_list(kw['header_name'])
287 assert len(l)>0,'list of headers in header_name is empty'
288 kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
289 if not'uselib_store'in kw:
290 kw['uselib_store']=l[0].upper()
291 if not'define_name'in kw:
292 kw['define_name']=self.have_define(l[0])
295 kw['msg']='Checking for library %s'%kw['lib']
296 if not'uselib_store'in kw:
297 kw['uselib_store']=kw['lib'].upper()
300 kw['msg']='Checking for static library %s'%kw['stlib']
301 if not'uselib_store'in kw:
302 kw['uselib_store']=kw['stlib'].upper()
304 kw['code']=kw['fragment']
306 kw['msg']='Checking for code snippet'
309 for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
312 kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
315 if not'execute'in kw:
318 kw['features'].append('test_exec')
320 kw['errmsg']='not found'
324 kw['code']=SNIP_EMPTY_PROGRAM
325 if self.env[INCKEYS]:
326 kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
327 if not kw.get('success'):kw['success']=None
328 if'define_name'in kw:
329 self.undefine(kw['define_name'])
330 assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
332 def post_check(self,*k,**kw):
335 if kw['success']is not None:
336 if kw.get('define_ret',False):
337 is_success=kw['success']
339 is_success=(kw['success']==0)
341 is_success=(kw['success']==0)
342 if'define_name'in kw:
343 if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
344 if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
345 self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
347 self.define_cond(kw['define_name'],is_success)
349 self.define_cond(kw['define_name'],is_success)
350 if'header_name'in kw:
351 if kw.get('auto_add_header_name',False):
352 self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
353 if is_success and'uselib_store'in kw:
354 from waflib.Tools import ccroot
356 for x in kw['features']:
357 if x in ccroot.USELIB_VARS:
358 _vars|=ccroot.USELIB_VARS[x]
361 if k=='INCLUDES':lk='includes'
362 if k=='DEFINES':lk='defines'
365 if isinstance(val,str):
366 val=val.rstrip(os.path.sep)
367 self.env.append_unique(k+'_'+kw['uselib_store'],val)
370 def check(self,*k,**kw):
372 self.start_msg(kw['msg'])
375 ret=self.run_c_code(*k,**kw)
376 except self.errors.ConfigurationError:
377 self.end_msg(kw['errmsg'],'YELLOW')
381 self.fatal('The configuration failed')
384 ret=self.post_check(*k,**kw)
386 self.end_msg(kw['errmsg'],'YELLOW')
387 self.fatal('The configuration failed %r'%ret)
389 self.end_msg(self.ret_msg(kw['okmsg'],kw))
391 class test_exec(Task.Task):
394 if getattr(self.generator,'rpath',None):
395 if getattr(self.generator,'define_ret',False):
396 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
398 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
400 env=self.env.env or{}
401 env.update(dict(os.environ))
402 for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
403 env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
404 if getattr(self.generator,'define_ret',False):
405 self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
407 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
408 @feature('test_exec')
409 @after_method('apply_link')
410 def test_exec_fun(self):
411 self.create_task('test_exec',self.link_task.outputs[0])
415 def run_c_code(self,*k,**kw):
416 lst=[str(v)for(p,v)in kw.items()if p!='env']
418 dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
426 self.fatal('cannot use the configuration test folder %r'%dir)
427 cachemode=getattr(Options.options,'confcache',None)
428 if cachemode==CACHE_RESULTS:
430 proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
434 ret=proj['cache_run_c_code']
435 if isinstance(ret,str)and ret.startswith('Test does not build'):
438 bdir=os.path.join(dir,'testbuild')
439 if not os.path.exists(bdir):
441 self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
445 if kw['compile_filename']:
446 node=bld.srcnode.make_node(kw['compile_filename'])
447 node.write(kw['code'])
448 bld.logger=self.logger
449 bld.all_envs.update(self.all_envs)
451 o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
452 for k,v in kw.items():
454 self.to_log("==>\n%s\n<=="%kw['code'])
460 except Errors.WafError:
461 ret='Test does not build: %s'%Utils.ex_stack()
464 ret=getattr(bld,'retval',0)
466 proj=ConfigSet.ConfigSet()
467 proj['cache_run_c_code']=ret
468 proj.store(os.path.join(dir,'cache_run_c_code'))
471 def check_cxx(self,*k,**kw):
473 return self.check(*k,**kw)
475 def check_cc(self,*k,**kw):
477 return self.check(*k,**kw)
479 def define(self,key,val,quote=True):
480 assert key and isinstance(key,str)
483 elif val in(False,None):
485 if isinstance(val,int)or isinstance(val,float):
488 s=quote and'%s="%s"'or'%s=%s'
491 lst=self.env['DEFINES']
493 if x.startswith(ban):
494 lst[lst.index(x)]=app
497 self.env.append_value('DEFINES',app)
498 self.env.append_unique(DEFKEYS,key)
500 def undefine(self,key):
501 assert key and isinstance(key,str)
503 lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
504 self.env['DEFINES']=lst
505 self.env.append_unique(DEFKEYS,key)
507 def define_cond(self,key,val):
508 assert key and isinstance(key,str)
514 def is_defined(self,key):
515 assert key and isinstance(key,str)
517 for x in self.env['DEFINES']:
518 if x.startswith(ban):
522 def get_define(self,key):
523 assert key and isinstance(key,str)
525 for x in self.env['DEFINES']:
526 if x.startswith(ban):
530 def have_define(self,key):
531 return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
533 def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
535 Logs.warn('Cannot pass env to write_config_header')
536 if not configfile:configfile=WAF_CONFIG_H
537 waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
538 node=top and self.bldnode or self.path.get_bld()
539 node=node.make_node(configfile)
541 lst=['/* WARNING! All changes made to this file will be lost! */\n']
542 lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
543 lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
544 lst.append('\n#endif /* %s */\n'%waf_guard)
545 node.write('\n'.join(lst))
546 self.env.append_unique(Build.CFG_FILES,[node.abspath()])
548 for key in self.env[DEFKEYS]:
552 def get_config_header(self,defines=True,headers=False,define_prefix=''):
555 for x in self.env[INCKEYS]:
556 lst.append('#include <%s>'%x)
558 for x in self.env[DEFKEYS]:
559 if self.is_defined(x):
560 val=self.get_define(x)
561 lst.append('#define %s %s'%(define_prefix+x,val))
563 lst.append('/* #undef %s */'%(define_prefix+x))
566 def cc_add_flags(conf):
567 conf.add_os_flags('CPPFLAGS','CFLAGS')
568 conf.add_os_flags('CFLAGS')
570 def cxx_add_flags(conf):
571 conf.add_os_flags('CPPFLAGS','CXXFLAGS')
572 conf.add_os_flags('CXXFLAGS')
574 def link_add_flags(conf):
575 conf.add_os_flags('LINKFLAGS')
576 conf.add_os_flags('LDFLAGS','LINKFLAGS')
578 def cc_load_tools(conf):
579 if not conf.env.DEST_OS:
580 conf.env.DEST_OS=Utils.unversioned_sys_platform()
583 def cxx_load_tools(conf):
584 if not conf.env.DEST_OS:
585 conf.env.DEST_OS=Utils.unversioned_sys_platform()
588 def get_cc_version(conf,cc,gcc=False,icc=False):
589 cmd=cc+['-dM','-E','-']
590 env=conf.env.env or None
592 p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
594 out=p.communicate()[0]
596 conf.fatal('Could not determine the compiler version %r'%cmd)
597 if not isinstance(out,str):
598 out=out.decode(sys.stdout.encoding or'iso8859-1')
600 if out.find('__INTEL_COMPILER')>=0:
601 conf.fatal('The intel compiler pretends to be gcc')
602 if out.find('__GNUC__')<0 and out.find('__clang__')<0:
603 conf.fatal('Could not determine the compiler type')
604 if icc and out.find('__INTEL_COMPILER')<0:
605 conf.fatal('Not icc/icpc')
610 lst=shlex.split(line)
618 return var in k and k[var]!='0'
619 if not conf.env.DEST_OS:
621 for i in MACRO_TO_DESTOS:
623 conf.env.DEST_OS=MACRO_TO_DESTOS[i]
626 if isD('__APPLE__')and isD('__MACH__'):
627 conf.env.DEST_OS='darwin'
628 elif isD('__unix__'):
629 conf.env.DEST_OS='generic'
631 conf.env.DEST_BINFMT='elf'
632 elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
633 conf.env.DEST_BINFMT='pe'
634 conf.env.LIBDIR=conf.env.BINDIR
635 elif isD('__APPLE__'):
636 conf.env.DEST_BINFMT='mac-o'
637 if not conf.env.DEST_BINFMT:
638 conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
639 for i in MACRO_TO_DEST_CPU:
641 conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
643 Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
645 ver=k['__INTEL_COMPILER']
646 conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
649 conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
651 conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
654 def get_xlc_version(conf,cc):
657 out,err=conf.cmd_and_log(cmd,output=0)
658 except Errors.WafError:
659 conf.fatal('Could not find xlc %r'%cmd)
660 for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
661 version_re=re.compile(v,re.I).search
662 match=version_re(out or err)
665 conf.env['CC_VERSION']=(k['major'],k['minor'])
668 conf.fatal('Could not determine the XLC version.')
670 def get_suncc_version(conf,cc):
673 out,err=conf.cmd_and_log(cmd,output=0)
674 except Errors.WafError:
675 conf.fatal('Could not find suncc %r'%cmd)
677 version=version.split('\n')[0]
678 version_re=re.compile(r'cc:\s+sun\s+(c\+\+|c)\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
679 match=version_re(version)
682 conf.env['CC_VERSION']=(k['major'],k['minor'])
684 conf.fatal('Could not determine the suncc version.')
686 def add_as_needed(self):
687 if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
688 self.env.append_unique('LINKFLAGS','--as-needed')
689 class cfgtask(Task.TaskBase):
692 def runnable_status(self):
698 bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
702 bld.logger=self.logger
704 bld.check(**self.args)
708 def multicheck(self,*k,**kw):
709 self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
713 self.cache_global=Options.cache_global
714 self.nocache=Options.options.nocache
715 self.returned_tasks=[]
719 def to_log(self,*k,**kw):
730 x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
735 p=Runner.Parallel(bld,Options.options.jobs)
739 x.logger.memhandler.flush()
741 if x.hasrun!=Task.SUCCESS:
742 self.end_msg(kw.get('errmsg','no'),color='YELLOW')
743 self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')