e6d3b5d4d81a47de6dba471319900cc7973b391b
[aubio.git] / waflib / Tools / c_config.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5 import os,re,shlex,sys
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'
10 DEFKEYS='define_key'
11 INCKEYS='include_key'
12 cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
13 SNIP_FUNCTION='''
14 int main(int argc, char **argv) {
15         void *p;
16         (void)argc; (void)argv;
17         p=(void*)(%s);
18         return 0;
19 }
20 '''
21 SNIP_TYPE='''
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;
26         return 1;
27 }
28 '''
29 SNIP_EMPTY_PROGRAM='''
30 int main(int argc, char **argv) {
31         (void)argc; (void)argv;
32         return 0;
33 }
34 '''
35 SNIP_FIELD='''
36 int 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 '''
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',}
45 @conf
46 def parse_flags(self,line,uselib_store,env=None,force_static=False):
47         assert(isinstance(line,str))
48         env=env or self.env
49         app=env.append_value
50         appu=env.append_unique
51         lex=shlex.shlex(line,posix=False)
52         lex.whitespace_split=True
53         lex.commenters=''
54         lst=list(lex)
55         uselib=uselib_store
56         while lst:
57                 x=lst.pop(0)
58                 st=x[:2]
59                 ot=x[2:]
60                 if st=='-I'or st=='/I':
61                         if not ot:ot=lst.pop(0)
62                         appu('INCLUDES_'+uselib,[ot])
63                 elif st=='-include':
64                         tmp=[x,lst.pop(0)]
65                         app('CFLAGS',tmp)
66                         app('CXXFLAGS',tmp)
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])
70                 elif st=='-l':
71                         if not ot:ot=lst.pop(0)
72                         prefix=force_static and'STLIB_'or'LIB_'
73                         appu(prefix+uselib,[ot])
74                 elif st=='-L':
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])
83                 elif x=='-framework':
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'):
95                         arg=lst.pop(0)
96                         app('LINKFLAGS_'+uselib,[x,arg])
97                 elif x.startswith('-arch')or x.startswith('-isysroot'):
98                         tmp=[x,lst.pop(0)]
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])
104 @conf
105 def ret_msg(self,f,kw):
106         if isinstance(f,str):
107                 return f
108         return f(kw)
109 @conf
110 def validate_cfg(self,kw):
111         if not'path'in 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:
116                 if not'msg'in kw:
117                         kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
118                 return
119         if not'okmsg'in kw:
120                 kw['okmsg']='yes'
121         if not'errmsg'in kw:
122                 kw['errmsg']='not found'
123         if'modversion'in kw:
124                 if not'msg'in kw:
125                         kw['msg']='Checking for %r version'%kw['modversion']
126                 return
127         for x in cfg_ver.keys():
128                 y=x.replace('-','_')
129                 if y in kw:
130                         if not'package'in kw:
131                                 raise ValueError('%s requires a package'%x)
132                         if not'msg'in kw:
133                                 kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
134                         return
135         if not'msg'in kw:
136                 kw['msg']='Checking for %r'%(kw['package']or kw['path'])
137 @conf
138 def exec_cfg(self,kw):
139         def define_it():
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)
144                 if not'okmsg'in kw:
145                         kw['okmsg']='yes'
146                 return
147         for x in cfg_ver:
148                 y=x.replace('-','_')
149                 if y in kw:
150                         self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']])
151                         if not'okmsg'in kw:
152                                 kw['okmsg']='yes'
153                         define_it()
154                         break
155         if'modversion'in kw:
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)
158                 return version
159         lst=[kw['path']]
160         defi=kw.get('define_variable',None)
161         if not defi:
162                 defi=self.env.PKG_CONFIG_DEFINES or{}
163         for key,val in defi.items():
164                 lst.append('--define-variable=%s=%s'%(key,val))
165         if'variables'in kw:
166                 env=kw.get('env',self.env)
167                 uselib=kw.get('uselib_store',kw['package'].upper())
168                 vars=Utils.to_list(kw['variables'])
169                 for v in vars:
170                         val=self.cmd_and_log(lst+['--variable='+v]).strip()
171                         var='%s_%s'%(uselib,v)
172                         env[var]=val
173                 if not'okmsg'in kw:
174                         kw['okmsg']='yes'
175                 return
176         static=False
177         if'args'in kw:
178                 args=Utils.to_list(kw['args'])
179                 if'--static'in args or'--static-libs'in args:
180                         static=True
181                 lst+=args
182         lst.extend(Utils.to_list(kw['package']))
183         ret=self.cmd_and_log(lst)
184         if not'okmsg'in kw:
185                 kw['okmsg']='yes'
186         define_it()
187         self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
188         return ret
189 @conf
190 def check_cfg(self,*k,**kw):
191         if k:
192                 lst=k[0].split()
193                 kw['package']=lst[0]
194                 kw['args']=' '.join(lst[1:])
195         self.validate_cfg(kw)
196         if'msg'in kw:
197                 self.start_msg(kw['msg'])
198         ret=None
199         try:
200                 ret=self.exec_cfg(kw)
201         except self.errors.WafError:
202                 if'errmsg'in kw:
203                         self.end_msg(kw['errmsg'],'YELLOW')
204                 if Logs.verbose>1:
205                         raise
206                 else:
207                         self.fatal('The configuration failed')
208         else:
209                 kw['success']=ret
210                 if'okmsg'in kw:
211                         self.end_msg(self.ret_msg(kw['okmsg'],kw))
212         return ret
213 @conf
214 def validate_c(self,kw):
215         if not'env'in kw:
216                 kw['env']=self.env.derive()
217         env=kw['env']
218         if not'compiler'in kw and not'features'in kw:
219                 kw['compiler']='c'
220                 if env['CXX_NAME']and Task.classes.get('cxx',None):
221                         kw['compiler']='cxx'
222                         if not self.env['CXX']:
223                                 self.fatal('a c++ compiler is required')
224                 else:
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'
231         if not'type'in kw:
232                 kw['type']='cprogram'
233         if not'features'in kw:
234                 kw['features']=[kw['compile_mode'],kw['type']]
235         else:
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'')
239         def to_header(dct):
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])
243                 return''
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:
250                                 kw['header_name']=[]
251                         fwk='%s/%s.h'%(fwkname,fwkname)
252                         if kw.get('remove_dot_h',None):
253                                 fwk=fwk[:-2]
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']
259                 if not'msg'in kw:
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:
267                 tu=kw['type_name']
268                 if not'header_name'in kw:
269                         kw['header_name']='stdint.h'
270                 if'field_name'in kw:
271                         field=kw['field_name']
272                         kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
273                         if not'msg'in kw:
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())
277                 else:
278                         kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
279                         if not'msg'in kw:
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:
284                 if not'msg'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])
293         if'lib'in kw:
294                 if not'msg'in kw:
295                         kw['msg']='Checking for library %s'%kw['lib']
296                 if not'uselib_store'in kw:
297                         kw['uselib_store']=kw['lib'].upper()
298         if'stlib'in kw:
299                 if not'msg'in kw:
300                         kw['msg']='Checking for static library %s'%kw['stlib']
301                 if not'uselib_store'in kw:
302                         kw['uselib_store']=kw['stlib'].upper()
303         if'fragment'in kw:
304                 kw['code']=kw['fragment']
305                 if not'msg'in kw:
306                         kw['msg']='Checking for code snippet'
307                 if not'errmsg'in kw:
308                         kw['errmsg']='no'
309         for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
310                 if flagsname in kw:
311                         if not'msg'in kw:
312                                 kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
313                         if not'errmsg'in kw:
314                                 kw['errmsg']='no'
315         if not'execute'in kw:
316                 kw['execute']=False
317         if kw['execute']:
318                 kw['features'].append('test_exec')
319         if not'errmsg'in kw:
320                 kw['errmsg']='not found'
321         if not'okmsg'in kw:
322                 kw['okmsg']='yes'
323         if not'code'in kw:
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'
331 @conf
332 def post_check(self,*k,**kw):
333         is_success=0
334         if kw['execute']:
335                 if kw['success']is not None:
336                         if kw.get('define_ret',False):
337                                 is_success=kw['success']
338                         else:
339                                 is_success=(kw['success']==0)
340         else:
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))
346                         else:
347                                 self.define_cond(kw['define_name'],is_success)
348                 else:
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
355                 _vars=set([])
356                 for x in kw['features']:
357                         if x in ccroot.USELIB_VARS:
358                                 _vars|=ccroot.USELIB_VARS[x]
359                 for k in _vars:
360                         lk=k.lower()
361                         if k=='INCLUDES':lk='includes'
362                         if k=='DEFINES':lk='defines'
363                         if lk in kw:
364                                 val=kw[lk]
365                                 if isinstance(val,str):
366                                         val=val.rstrip(os.path.sep)
367                                 self.env.append_unique(k+'_'+kw['uselib_store'],val)
368         return is_success
369 @conf
370 def check(self,*k,**kw):
371         self.validate_c(kw)
372         self.start_msg(kw['msg'])
373         ret=None
374         try:
375                 ret=self.run_c_code(*k,**kw)
376         except self.errors.ConfigurationError:
377                 self.end_msg(kw['errmsg'],'YELLOW')
378                 if Logs.verbose>1:
379                         raise
380                 else:
381                         self.fatal('The configuration failed')
382         else:
383                 kw['success']=ret
384         ret=self.post_check(*k,**kw)
385         if not ret:
386                 self.end_msg(kw['errmsg'],'YELLOW')
387                 self.fatal('The configuration failed %r'%ret)
388         else:
389                 self.end_msg(self.ret_msg(kw['okmsg'],kw))
390         return ret
391 class test_exec(Task.Task):
392         color='PINK'
393         def run(self):
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()])
397                         else:
398                                 self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
399                 else:
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)
406                         else:
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])
412 CACHE_RESULTS=1
413 COMPILE_ERRORS=2
414 @conf
415 def run_c_code(self,*k,**kw):
416         lst=[str(v)for(p,v)in kw.items()if p!='env']
417         h=Utils.h_list(lst)
418         dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
419         try:
420                 os.makedirs(dir)
421         except OSError:
422                 pass
423         try:
424                 os.stat(dir)
425         except OSError:
426                 self.fatal('cannot use the configuration test folder %r'%dir)
427         cachemode=getattr(Options.options,'confcache',None)
428         if cachemode==CACHE_RESULTS:
429                 try:
430                         proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
431                 except OSError:
432                         pass
433                 else:
434                         ret=proj['cache_run_c_code']
435                         if isinstance(ret,str)and ret.startswith('Test does not build'):
436                                 self.fatal(ret)
437                         return ret
438         bdir=os.path.join(dir,'testbuild')
439         if not os.path.exists(bdir):
440                 os.makedirs(bdir)
441         self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
442         bld.init_dirs()
443         bld.progress_bar=0
444         bld.targets='*'
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)
450         bld.env=kw['env']
451         o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
452         for k,v in kw.items():
453                 setattr(o,k,v)
454         self.to_log("==>\n%s\n<=="%kw['code'])
455         bld.targets='*'
456         ret=-1
457         try:
458                 try:
459                         bld.compile()
460                 except Errors.WafError:
461                         ret='Test does not build: %s'%Utils.ex_stack()
462                         self.fatal(ret)
463                 else:
464                         ret=getattr(bld,'retval',0)
465         finally:
466                 proj=ConfigSet.ConfigSet()
467                 proj['cache_run_c_code']=ret
468                 proj.store(os.path.join(dir,'cache_run_c_code'))
469         return ret
470 @conf
471 def check_cxx(self,*k,**kw):
472         kw['compiler']='cxx'
473         return self.check(*k,**kw)
474 @conf
475 def check_cc(self,*k,**kw):
476         kw['compiler']='c'
477         return self.check(*k,**kw)
478 @conf
479 def define(self,key,val,quote=True):
480         assert key and isinstance(key,str)
481         if val is True:
482                 val=1
483         elif val in(False,None):
484                 val=0
485         if isinstance(val,int)or isinstance(val,float):
486                 s='%s=%s'
487         else:
488                 s=quote and'%s="%s"'or'%s=%s'
489         app=s%(key,str(val))
490         ban=key+'='
491         lst=self.env['DEFINES']
492         for x in lst:
493                 if x.startswith(ban):
494                         lst[lst.index(x)]=app
495                         break
496         else:
497                 self.env.append_value('DEFINES',app)
498         self.env.append_unique(DEFKEYS,key)
499 @conf
500 def undefine(self,key):
501         assert key and isinstance(key,str)
502         ban=key+'='
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)
506 @conf
507 def define_cond(self,key,val):
508         assert key and isinstance(key,str)
509         if val:
510                 self.define(key,1)
511         else:
512                 self.undefine(key)
513 @conf
514 def is_defined(self,key):
515         assert key and isinstance(key,str)
516         ban=key+'='
517         for x in self.env['DEFINES']:
518                 if x.startswith(ban):
519                         return True
520         return False
521 @conf
522 def get_define(self,key):
523         assert key and isinstance(key,str)
524         ban=key+'='
525         for x in self.env['DEFINES']:
526                 if x.startswith(ban):
527                         return x[len(ban):]
528         return None
529 @conf
530 def have_define(self,key):
531         return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
532 @conf
533 def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
534         if env:
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)
540         node.parent.mkdir()
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()])
547         if remove:
548                 for key in self.env[DEFKEYS]:
549                         self.undefine(key)
550                 self.env[DEFKEYS]=[]
551 @conf
552 def get_config_header(self,defines=True,headers=False,define_prefix=''):
553         lst=[]
554         if headers:
555                 for x in self.env[INCKEYS]:
556                         lst.append('#include <%s>'%x)
557         if defines:
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))
562                         else:
563                                 lst.append('/* #undef %s */'%(define_prefix+x))
564         return"\n".join(lst)
565 @conf
566 def cc_add_flags(conf):
567         conf.add_os_flags('CPPFLAGS','CFLAGS')
568         conf.add_os_flags('CFLAGS')
569 @conf
570 def cxx_add_flags(conf):
571         conf.add_os_flags('CPPFLAGS','CXXFLAGS')
572         conf.add_os_flags('CXXFLAGS')
573 @conf
574 def link_add_flags(conf):
575         conf.add_os_flags('LINKFLAGS')
576         conf.add_os_flags('LDFLAGS','LINKFLAGS')
577 @conf
578 def cc_load_tools(conf):
579         if not conf.env.DEST_OS:
580                 conf.env.DEST_OS=Utils.unversioned_sys_platform()
581         conf.load('c')
582 @conf
583 def cxx_load_tools(conf):
584         if not conf.env.DEST_OS:
585                 conf.env.DEST_OS=Utils.unversioned_sys_platform()
586         conf.load('cxx')
587 @conf
588 def get_cc_version(conf,cc,gcc=False,icc=False):
589         cmd=cc+['-dM','-E','-']
590         env=conf.env.env or None
591         try:
592                 p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
593                 p.stdin.write('\n')
594                 out=p.communicate()[0]
595         except Exception:
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')
599         if gcc:
600                 if out.find('__INTEL_COMPILER')>=0:
601                         conf.fatal('The intel compiler pretends to be gcc')
602                 if out.find('__GNUC__')<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')
606         k={}
607         if icc or gcc:
608                 out=out.splitlines()
609                 for line in out:
610                         lst=shlex.split(line)
611                         if len(lst)>2:
612                                 key=lst[1]
613                                 val=lst[2]
614                                 k[key]=val
615                 def isD(var):
616                         return var in k
617                 def isT(var):
618                         return var in k and k[var]!='0'
619                 if not conf.env.DEST_OS:
620                         conf.env.DEST_OS=''
621                 for i in MACRO_TO_DESTOS:
622                         if isD(i):
623                                 conf.env.DEST_OS=MACRO_TO_DESTOS[i]
624                                 break
625                 else:
626                         if isD('__APPLE__')and isD('__MACH__'):
627                                 conf.env.DEST_OS='darwin'
628                         elif isD('__unix__'):
629                                 conf.env.DEST_OS='generic'
630                 if isD('__ELF__'):
631                         conf.env.DEST_BINFMT='elf'
632                 elif isD('__WINNT__')or isD('__CYGWIN__'):
633                         conf.env.DEST_BINFMT='pe'
634                         conf.env.LIBDIR=conf.env['PREFIX']+'/bin'
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:
640                         if isD(i):
641                                 conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
642                                 break
643                 Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
644                 if icc:
645                         ver=k['__INTEL_COMPILER']
646                         conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
647                 else:
648                         if isD('__clang__'):
649                                 conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
650                         else:
651                                 conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
652         return k
653 @conf
654 def get_xlc_version(conf,cc):
655         cmd=cc+['-qversion']
656         try:
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)
663                 if match:
664                         k=match.groupdict()
665                         conf.env['CC_VERSION']=(k['major'],k['minor'])
666                         break
667         else:
668                 conf.fatal('Could not determine the XLC version.')
669 @conf
670 def add_as_needed(self):
671         if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
672                 self.env.append_unique('LINKFLAGS','--as-needed')
673 class cfgtask(Task.TaskBase):
674         def display(self):
675                 return''
676         def runnable_status(self):
677                 return Task.RUN_ME
678         def uid(self):
679                 return Utils.SIG_NIL
680         def run(self):
681                 conf=self.conf
682                 bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
683                 bld.env=conf.env
684                 bld.init_dirs()
685                 bld.in_msg=1
686                 bld.logger=self.logger
687                 try:
688                         bld.check(**self.args)
689                 except Exception:
690                         return 1
691 @conf
692 def multicheck(self,*k,**kw):
693         self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
694         class par(object):
695                 def __init__(self):
696                         self.keep=False
697                         self.cache_global=Options.cache_global
698                         self.nocache=Options.options.nocache
699                         self.returned_tasks=[]
700                         self.task_sigs={}
701                 def total(self):
702                         return len(tasks)
703                 def to_log(self,*k,**kw):
704                         return
705         bld=par()
706         tasks=[]
707         for dct in k:
708                 x=cfgtask(bld=bld)
709                 tasks.append(x)
710                 x.args=dct
711                 x.bld=bld
712                 x.conf=self
713                 x.args=dct
714                 x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
715         def it():
716                 yield tasks
717                 while 1:
718                         yield[]
719         p=Runner.Parallel(bld,Options.options.jobs)
720         p.biter=it()
721         p.start()
722         for x in tasks:
723                 x.logger.memhandler.flush()
724         for x in tasks:
725                 if x.hasrun!=Task.SUCCESS:
726                         self.end_msg(kw.get('errmsg','no'),color='YELLOW')
727                         self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
728         self.end_msg('ok')