4
if sys.hexversion < 0x020400f0: from sets import Set as set
5
import os,imp,sys,shlex,shutil
7
import Build,Utils,Configure,Task,Options,Logs,TaskGen
9
from Configure import conf,conftest
10
cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
20
if ((%(type_name)s *) 0) return 0;
21
if (sizeof (%(type_name)s)) return 0;
29
def parse_flags(line,uselib,env):
35
if st=='-I'or st=='/I':
36
if not ot:ot=lst.pop(0)
37
env.append_unique('CPPPATH_'+uselib,ot)
39
if not ot:ot=lst.pop(0)
40
env.append_unique('CXXDEFINES_'+uselib,ot)
41
env.append_unique('CCDEFINES_'+uselib,ot)
43
if not ot:ot=lst.pop(0)
44
env.append_unique('LIB_'+uselib,ot)
46
if not ot:ot=lst.pop(0)
47
env.append_unique('LIBPATH_'+uselib,ot)
48
elif x=='-pthread'or x.startswith('+'):
49
env.append_unique('CCFLAGS_'+uselib,x)
50
env.append_unique('CXXFLAGS_'+uselib,x)
51
env.append_unique('LINKFLAGS_'+uselib,x)
53
env.append_unique('FRAMEWORK_'+uselib,lst.pop(0))
54
elif x.startswith('-F'):
55
env.append_unique('FRAMEWORKPATH_'+uselib,x[2:])
56
elif x.startswith('-std'):
57
env.append_unique('CCFLAGS_'+uselib,x)
58
env.append_unique('LINKFLAGS_'+uselib,x)
59
elif x.startswith('-Wl'):
60
env.append_unique('LINKFLAGS_'+uselib,x)
61
elif x.startswith('-m')or x.startswith('-f'):
62
env.append_unique('CCFLAGS_'+uselib,x)
63
env.append_unique('CXXFLAGS_'+uselib,x)
64
def ret_msg(self,f,kw):
68
def validate_cfg(self,kw):
70
kw['path']='pkg-config --errors-to-stdout --print-errors'
71
if'atleast_pkgconfig_version'in kw:
73
kw['msg']='Checking for pkg-config version >= %s'%kw['atleast_pkgconfig_version']
79
kw['msg']='Checking for %s variables'%kw['package']
81
for x in cfg_ver.keys():
85
raise ValueError('%s requires a package'%x)
87
kw['msg']='Checking for %s %s %s'%(kw['package'],cfg_ver[x],kw[y])
90
kw['msg']='Checking for %s'%(kw['package']or kw['path'])
94
kw['errmsg']='not found'
95
def cmd_and_log(self,cmd,kw):
96
Logs.debug('runner: %s\n'%cmd)
98
self.log.write('%s\n'%cmd)
100
p=Utils.pproc.Popen(cmd,stdout=Utils.pproc.PIPE,stderr=Utils.pproc.PIPE,shell=True)
101
(out,err)=p.communicate()
103
self.log.write('error %r'%e)
111
if not kw.get('errmsg',''):
112
if kw.get('mandatory',False):
113
kw['errmsg']=out.strip()
118
def exec_cfg(self,kw):
119
if'atleast_pkgconfig_version'in kw:
120
cmd='%s --atleast-pkgconfig-version=%s'%(kw['path'],kw['atleast_pkgconfig_version'])
121
self.cmd_and_log(cmd,kw)
128
self.cmd_and_log('%s --%s=%s %s'%(kw['path'],x,kw[y],kw['package']),kw)
131
self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
134
version=self.cmd_and_log('%s --modversion %s'%(kw['path'],kw['modversion']),kw).strip()
135
self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
138
env=kw.get('env',self.env)
139
uselib=kw.get('uselib_store',kw['package'].upper())
140
vars=Utils.to_list(kw['variables'])
142
val=self.cmd_and_log('%s --variable=%s %s'%(kw['path'],v,kw['package']),kw).strip()
143
var='%s_%s'%(uselib,v)
149
for key,val in kw.get('define_variable',{}).iteritems():
150
lst.append('--define-variable=%s=%s'%(key,val))
151
lst.append(kw.get('args',''))
152
lst.append(kw['package'])
154
ret=self.cmd_and_log(cmd,kw)
157
self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
158
parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env))
160
def check_cfg(self,*k,**kw):
161
self.validate_cfg(kw)
163
self.check_message_1(kw['msg'])
166
ret=self.exec_cfg(kw)
167
except Configure.ConfigurationError,e:
169
self.check_message_2(kw['errmsg'],'YELLOW')
170
if'mandatory'in kw and kw['mandatory']:
174
self.fatal('the configuration failed (see %r)'%self.log.name)
178
self.check_message_2(self.ret_msg(kw['okmsg'],kw))
180
def validate_c(self,kw):
182
kw['env']=self.env.copy()
184
if not'compiler'in kw:
186
if env['CXX_NAME']and Task.TaskBase.classes.get('cxx',None):
188
if not self.env['CXX']:
189
self.fatal('a c++ compiler is required')
191
if not self.env['CC']:
192
self.fatal('a c compiler is required')
194
kw['type']='cprogram'
195
assert not(kw['type']!='cprogram'and kw.get('execute',0)),'can only execute programs'
197
if'header_name'in dct:
198
dct=Utils.to_list(dct['header_name'])
199
return''.join(['#include <%s>\n'%x for x in dct])
201
if not'compile_mode'in kw:
202
kw['compile_mode']=(kw['compiler']=='cxx')and'cxx'or'cc'
203
if not'compile_filename'in kw:
204
kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
205
if'framework_name'in kw:
206
try:TaskGen.task_gen.create_task_macapp
207
except AttributeError:self.fatal('frameworks require the osx tool')
208
fwkname=kw['framework_name']
209
if not'uselib_store'in kw:
210
kw['uselib_store']=fwkname.upper()
211
if not kw.get('no_header',False):
212
if not'header_name'in kw:
214
fwk='%s/%s.h'%(fwkname,fwkname)
215
if kw.get('remove_dot_h',None):
217
kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
218
kw['msg']='Checking for framework %s'%fwkname
219
kw['framework']=fwkname
220
if'function_name'in kw:
221
fu=kw['function_name']
223
kw['msg']='Checking for function %s'%fu
224
kw['code']=to_header(kw)+SNIP1%fu
225
if not'uselib_store'in kw:
226
kw['uselib_store']=fu.upper()
227
if not'define_name'in kw:
228
kw['define_name']=self.have_define(fu)
229
elif'type_name'in kw:
232
kw['msg']='Checking for type %s'%tu
233
if not'header_name'in kw:
234
kw['header_name']='stdint.h'
235
kw['code']=to_header(kw)+SNIP2%{'type_name':tu}
236
if not'define_name'in kw:
237
kw['define_name']=self.have_define(tu.upper())
238
elif'header_name'in kw:
240
kw['msg']='Checking for header %s'%kw['header_name']
241
l=Utils.to_list(kw['header_name'])
242
assert len(l)>0,'list of headers in header_name is empty'
243
kw['code']=to_header(kw)+SNIP3
244
if not'uselib_store'in kw:
245
kw['uselib_store']=l[0].upper()
246
if not'define_name'in kw:
247
kw['define_name']=self.have_define(l[0])
250
kw['msg']='Checking for library %s'%kw['lib']
251
if not'uselib_store'in kw:
252
kw['uselib_store']=kw['lib'].upper()
255
kw['msg']='Checking for static library %s'%kw['staticlib']
256
if not'uselib_store'in kw:
257
kw['uselib_store']=kw['staticlib'].upper()
259
kw['code']=kw['fragment']
261
kw['msg']='Checking for custom code'
264
for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
267
kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
270
if not'execute'in kw:
273
kw['errmsg']='not found'
278
if not kw.get('success'):kw['success']=None
279
assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
280
def post_check(self,*k,**kw):
286
is_success=(kw['success']==0)
287
if'define_name'in kw:
288
if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
291
if isinstance(key,str):
293
self.define(kw['define_name'],key,quote=kw.get('quote',1))
295
self.define_cond(kw['define_name'],True)
297
self.define_cond(kw['define_name'],False)
299
self.define_cond(kw['define_name'],is_success)
300
if is_success and'uselib_store'in kw:
302
for k in set(cc.g_cc_flag_vars).union(cxx.g_cxx_flag_vars):
304
if k=='CPPPATH':lk='includes'
305
if k=='CXXDEFINES':lk='defines'
306
if k=='CCDEFINES':lk='defines'
309
if isinstance(val,str):
310
val=val.rstrip(os.path.sep)
311
self.env.append_unique(k+'_'+kw['uselib_store'],val)
312
def check(self,*k,**kw):
314
self.check_message_1(kw['msg'])
317
ret=self.run_c_code(*k,**kw)
318
except Configure.ConfigurationError,e:
319
self.check_message_2(kw['errmsg'],'YELLOW')
320
if'mandatory'in kw and kw['mandatory']:
324
self.fatal('the configuration failed (see %r)'%self.log.name)
327
self.check_message_2(self.ret_msg(kw['okmsg'],kw))
328
self.post_check(*k,**kw)
329
if not kw.get('execute',False):
332
def run_c_code(self,*k,**kw):
333
test_f_name=kw['compile_filename']
336
dir=os.path.join(self.blddir,'.conf_check_%d'%k)
349
self.fatal('cannot create a configuration test folder %r'%dir)
353
self.fatal('cannot use the configuration test folder %r'%dir)
354
bdir=os.path.join(dir,'testbuild')
355
if not os.path.exists(bdir):
358
dest=open(os.path.join(dir,test_f_name),'w')
359
dest.write(kw['code'])
361
back=os.path.abspath('.')
362
bld=Build.BuildContext()
364
bld.all_envs.update(self.all_envs)
365
bld.all_envs['default']=env
366
bld.lst_variants=bld.all_envs.keys()
367
bld.load_dirs(dir,bdir)
369
bld.rescan(bld.srcnode)
370
o=bld(features=[kw['compile_mode'],kw['type']],source=test_f_name,target='testprog')
371
for k,v in kw.iteritems():
373
self.log.write("==>\n%s\n<==\n"%kw['code'])
376
except Utils.WafError:
382
self.log.write('command returned %r'%ret)
385
lastprog=o.link_task.outputs[0].abspath(env)
387
args=Utils.to_list(kw.get('exec_args',[]))
388
proc=Utils.pproc.Popen([lastprog]+args,stdout=Utils.pproc.PIPE,stderr=Utils.pproc.PIPE)
389
(out,err)=proc.communicate()
395
w('returncode %r'%proc.returncode)
398
self.fatal(Utils.ex_stack())
401
def check_cxx(self,*k,**kw):
403
return self.check(*k,**kw)
404
def check_cc(self,*k,**kw):
406
return self.check(*k,**kw)
407
def define(self,define,value,quote=1):
408
assert define and isinstance(define,str)
409
tbl=self.env[DEFINES]or Utils.ordered_dict()
410
if isinstance(value,str):
412
tbl[define]='"%s"'%repr('"'+value)[2:-1].replace('"','\\"')
415
elif isinstance(value,int):
418
raise TypeError('define %r -> %r must be a string or an int'%(define,value))
419
self.env[DEFINES]=tbl
420
self.env[define]=value
421
def undefine(self,define):
422
assert define and isinstance(define,str)
423
tbl=self.env[DEFINES]or Utils.ordered_dict()
426
self.env[DEFINES]=tbl
427
self.env[define]=value
428
def define_cond(self,name,value):
433
def is_defined(self,key):
434
defines=self.env[DEFINES]
442
return value!=UNDEFINED
443
def get_define(self,define):
444
try:return self.env[DEFINES][define]
445
except KeyError:return None
446
def have_define(self,name):
447
return self.__dict__.get('HAVE_PAT','HAVE_%s')%Utils.quote_define_name(name)
448
def write_config_header(self,configfile='',env='',guard='',top=False):
449
if not configfile:configfile=WAF_CONFIG_H
450
waf_guard=guard or'_%s_WAF'%Utils.quote_define_name(configfile)
451
if not env:env=self.env
455
diff=Utils.diff_path(self.srcdir,self.curdir)
456
full=os.sep.join([self.blddir,env.variant(),diff,configfile])
457
full=os.path.normpath(full)
458
(dir,base)=os.path.split(full)
462
dest.write('/* Configuration header created by Waf - do not edit */\n')
463
dest.write('#ifndef %s\n#define %s\n\n'%(waf_guard,waf_guard))
464
dest.write(self.get_config_header())
465
env.append_value(CFG_FILES,os.path.join(diff,configfile))
466
dest.write('\n#endif /* %s */\n'%waf_guard)
468
def get_config_header(self):
470
tbl=self.env[DEFINES]or Utils.ordered_dict()
471
for key in tbl.allkeys:
474
config_header.append('#define %s'%key)
475
elif value is UNDEFINED:
476
config_header.append('/* #undef %s */'%key)
478
config_header.append('#define %s %s'%(key,value))
479
return"\n".join(config_header)
483
if v['CPP']:cpp=v['CPP']
484
elif'CPP'in conf.environ:cpp=conf.environ['CPP']
485
if not cpp:cpp=conf.find_program('cpp',var='CPP')
486
if not cpp:cpp=v['CC']
487
if not cpp:cpp=v['CXX']
489
def cc_add_flags(conf):
490
conf.add_os_flags('CFLAGS','CCFLAGS')
491
conf.add_os_flags('CPPFLAGS')
492
def cxx_add_flags(conf):
493
conf.add_os_flags('CXXFLAGS')
494
conf.add_os_flags('CPPFLAGS')
495
def link_add_flags(conf):
496
conf.add_os_flags('LINKFLAGS')
497
conf.add_os_flags('LDFLAGS','LINKFLAGS')
498
def cc_load_tools(conf):
499
conf.check_tool('cc')
500
def cxx_load_tools(conf):
501
conf.check_tool('cxx')
520
conf(write_config_header)
521
conf(get_config_header)
523
conftest(cc_add_flags)
524
conftest(cxx_add_flags)
525
conftest(link_add_flags)
526
conftest(cc_load_tools)
527
conftest(cxx_load_tools)