~ubuntu-branches/ubuntu/utopic/fomp/utopic

« back to all changes in this revision

Viewing changes to waflib/Tools/c_config.py

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2012-11-05 10:49:59 UTC
  • Revision ID: package-import@ubuntu.com-20121105104959-2q6sje2d5fhjevfv
Tags: upstream-1.0.0~dfsg0
ImportĀ upstreamĀ versionĀ 1.0.0~dfsg0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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() {
 
15
        void *p;
 
16
        p=(void*)(%s);
 
17
        return 0;
 
18
}
 
19
'''
 
20
SNIP_TYPE='''
 
21
int main() {
 
22
        if ((%(type_name)s *) 0) return 0;
 
23
        if (sizeof (%(type_name)s)) return 0;
 
24
}
 
25
'''
 
26
SNIP_EMPTY_PROGRAM='''
 
27
int main() {
 
28
        return 0;
 
29
}
 
30
'''
 
31
SNIP_FIELD='''
 
32
int main() {
 
33
        char *off;
 
34
        off = (char*) &((%(type_name)s*)0)->%(field_name)s;
 
35
        return (size_t) off < sizeof(%(type_name)s);
 
36
}
 
37
'''
 
38
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'}
 
39
MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc',}
 
40
@conf
 
41
def parse_flags(self,line,uselib_store,env=None,force_static=False):
 
42
        assert(isinstance(line,str))
 
43
        env=env or self.env
 
44
        app=env.append_value
 
45
        appu=env.append_unique
 
46
        lex=shlex.shlex(line,posix=False)
 
47
        lex.whitespace_split=True
 
48
        lex.commenters=''
 
49
        lst=list(lex)
 
50
        uselib=uselib_store
 
51
        while lst:
 
52
                x=lst.pop(0)
 
53
                st=x[:2]
 
54
                ot=x[2:]
 
55
                if st=='-I'or st=='/I':
 
56
                        if not ot:ot=lst.pop(0)
 
57
                        appu('INCLUDES_'+uselib,[ot])
 
58
                elif st=='-include':
 
59
                        tmp=[x,lst.pop(0)]
 
60
                        app('CFLAGS',tmp)
 
61
                        app('CXXFLAGS',tmp)
 
62
                elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
 
63
                        if not ot:ot=lst.pop(0)
 
64
                        app('DEFINES_'+uselib,[ot])
 
65
                elif st=='-l':
 
66
                        if not ot:ot=lst.pop(0)
 
67
                        prefix=force_static and'STLIB_'or'LIB_'
 
68
                        appu(prefix+uselib,[ot])
 
69
                elif st=='-L':
 
70
                        if not ot:ot=lst.pop(0)
 
71
                        appu('LIBPATH_'+uselib,[ot])
 
72
                elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
 
73
                        app('CFLAGS_'+uselib,[x])
 
74
                        app('CXXFLAGS_'+uselib,[x])
 
75
                        app('LINKFLAGS_'+uselib,[x])
 
76
                elif x=='-framework':
 
77
                        appu('FRAMEWORK_'+uselib,[lst.pop(0)])
 
78
                elif x.startswith('-F'):
 
79
                        appu('FRAMEWORKPATH_'+uselib,[x[2:]])
 
80
                elif x.startswith('-Wl'):
 
81
                        app('LINKFLAGS_'+uselib,[x])
 
82
                elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
 
83
                        app('CFLAGS_'+uselib,[x])
 
84
                        app('CXXFLAGS_'+uselib,[x])
 
85
                elif x.startswith('-bundle'):
 
86
                        app('LINKFLAGS_'+uselib,[x])
 
87
                elif x.startswith('-undefined'):
 
88
                        arg=lst.pop(0)
 
89
                        app('LINKFLAGS_'+uselib,[x,arg])
 
90
                elif x.startswith('-arch')or x.startswith('-isysroot'):
 
91
                        tmp=[x,lst.pop(0)]
 
92
                        app('CFLAGS_'+uselib,tmp)
 
93
                        app('CXXFLAGS_'+uselib,tmp)
 
94
                        app('LINKFLAGS_'+uselib,tmp)
 
95
                elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib'):
 
96
                        appu('LINKFLAGS_'+uselib,[x])
 
97
@conf
 
98
def ret_msg(self,f,kw):
 
99
        if isinstance(f,str):
 
100
                return f
 
101
        return f(kw)
 
102
@conf
 
103
def validate_cfg(self,kw):
 
104
        if not'path'in kw:
 
105
                if not self.env.PKGCONFIG:
 
106
                        self.find_program('pkg-config',var='PKGCONFIG')
 
107
                kw['path']=self.env.PKGCONFIG
 
108
        if'atleast_pkgconfig_version'in kw:
 
109
                if not'msg'in kw:
 
110
                        kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
 
111
                return
 
112
        if not'okmsg'in kw:
 
113
                kw['okmsg']='yes'
 
114
        if not'errmsg'in kw:
 
115
                kw['errmsg']='not found'
 
116
        if'modversion'in kw:
 
117
                if not'msg'in kw:
 
118
                        kw['msg']='Checking for %r version'%kw['modversion']
 
119
                return
 
120
        for x in cfg_ver.keys():
 
121
                y=x.replace('-','_')
 
122
                if y in kw:
 
123
                        if not'package'in kw:
 
124
                                raise ValueError('%s requires a package'%x)
 
125
                        if not'msg'in kw:
 
126
                                kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
 
127
                        return
 
128
        if not'msg'in kw:
 
129
                kw['msg']='Checking for %r'%(kw['package']or kw['path'])
 
130
@conf
 
131
def exec_cfg(self,kw):
 
132
        if'atleast_pkgconfig_version'in kw:
 
133
                cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
 
134
                self.cmd_and_log(cmd)
 
135
                if not'okmsg'in kw:
 
136
                        kw['okmsg']='yes'
 
137
                return
 
138
        for x in cfg_ver:
 
139
                y=x.replace('-','_')
 
140
                if y in kw:
 
141
                        self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']])
 
142
                        if not'okmsg'in kw:
 
143
                                kw['okmsg']='yes'
 
144
                        self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
 
145
                        break
 
146
        if'modversion'in kw:
 
147
                version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']]).strip()
 
148
                self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
 
149
                return version
 
150
        lst=[kw['path']]
 
151
        defi=kw.get('define_variable',None)
 
152
        if not defi:
 
153
                defi=self.env.PKG_CONFIG_DEFINES or{}
 
154
        for key,val in defi.items():
 
155
                lst.append('--define-variable=%s=%s'%(key,val))
 
156
        if'variables'in kw:
 
157
                env=kw.get('env',self.env)
 
158
                uselib=kw.get('uselib_store',kw['package'].upper())
 
159
                vars=Utils.to_list(kw['variables'])
 
160
                for v in vars:
 
161
                        val=self.cmd_and_log(lst+['--variable='+v]).strip()
 
162
                        var='%s_%s'%(uselib,v)
 
163
                        env[var]=val
 
164
                if not'okmsg'in kw:
 
165
                        kw['okmsg']='yes'
 
166
                return
 
167
        static=False
 
168
        if'args'in kw:
 
169
                args=Utils.to_list(kw['args'])
 
170
                if'--static'in args or'--static-libs'in args:
 
171
                        static=True
 
172
                lst+=args
 
173
        lst.extend(Utils.to_list(kw['package']))
 
174
        ret=self.cmd_and_log(lst)
 
175
        if not'okmsg'in kw:
 
176
                kw['okmsg']='yes'
 
177
        self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
 
178
        self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
 
179
        return ret
 
180
@conf
 
181
def check_cfg(self,*k,**kw):
 
182
        if k:
 
183
                lst=k[0].split()
 
184
                kw['package']=lst[0]
 
185
                kw['args']=' '.join(lst[1:])
 
186
        self.validate_cfg(kw)
 
187
        if'msg'in kw:
 
188
                self.start_msg(kw['msg'])
 
189
        ret=None
 
190
        try:
 
191
                ret=self.exec_cfg(kw)
 
192
        except self.errors.WafError:
 
193
                if'errmsg'in kw:
 
194
                        self.end_msg(kw['errmsg'],'YELLOW')
 
195
                if Logs.verbose>1:
 
196
                        raise
 
197
                else:
 
198
                        self.fatal('The configuration failed')
 
199
        else:
 
200
                kw['success']=ret
 
201
                if'okmsg'in kw:
 
202
                        self.end_msg(self.ret_msg(kw['okmsg'],kw))
 
203
        return ret
 
204
@conf
 
205
def validate_c(self,kw):
 
206
        if not'env'in kw:
 
207
                kw['env']=self.env.derive()
 
208
        env=kw['env']
 
209
        if not'compiler'in kw and not'features'in kw:
 
210
                kw['compiler']='c'
 
211
                if env['CXX_NAME']and Task.classes.get('cxx',None):
 
212
                        kw['compiler']='cxx'
 
213
                        if not self.env['CXX']:
 
214
                                self.fatal('a c++ compiler is required')
 
215
                else:
 
216
                        if not self.env['CC']:
 
217
                                self.fatal('a c compiler is required')
 
218
        if not'compile_mode'in kw:
 
219
                kw['compile_mode']='c'
 
220
                if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
 
221
                        kw['compile_mode']='cxx'
 
222
        if not'type'in kw:
 
223
                kw['type']='cprogram'
 
224
        if not'features'in kw:
 
225
                kw['features']=[kw['compile_mode'],kw['type']]
 
226
        else:
 
227
                kw['features']=Utils.to_list(kw['features'])
 
228
        if not'compile_filename'in kw:
 
229
                kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
 
230
        def to_header(dct):
 
231
                if'header_name'in dct:
 
232
                        dct=Utils.to_list(dct['header_name'])
 
233
                        return''.join(['#include <%s>\n'%x for x in dct])
 
234
                return''
 
235
        if'framework_name'in kw:
 
236
                fwkname=kw['framework_name']
 
237
                if not'uselib_store'in kw:
 
238
                        kw['uselib_store']=fwkname.upper()
 
239
                if not kw.get('no_header',False):
 
240
                        if not'header_name'in kw:
 
241
                                kw['header_name']=[]
 
242
                        fwk='%s/%s.h'%(fwkname,fwkname)
 
243
                        if kw.get('remove_dot_h',None):
 
244
                                fwk=fwk[:-2]
 
245
                        kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
 
246
                kw['msg']='Checking for framework %s'%fwkname
 
247
                kw['framework']=fwkname
 
248
        if'function_name'in kw:
 
249
                fu=kw['function_name']
 
250
                if not'msg'in kw:
 
251
                        kw['msg']='Checking for function %s'%fu
 
252
                kw['code']=to_header(kw)+SNIP_FUNCTION%fu
 
253
                if not'uselib_store'in kw:
 
254
                        kw['uselib_store']=fu.upper()
 
255
                if not'define_name'in kw:
 
256
                        kw['define_name']=self.have_define(fu)
 
257
        elif'type_name'in kw:
 
258
                tu=kw['type_name']
 
259
                if not'header_name'in kw:
 
260
                        kw['header_name']='stdint.h'
 
261
                if'field_name'in kw:
 
262
                        field=kw['field_name']
 
263
                        kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
 
264
                        if not'msg'in kw:
 
265
                                kw['msg']='Checking for field %s in %s'%(field,tu)
 
266
                        if not'define_name'in kw:
 
267
                                kw['define_name']=self.have_define((tu+'_'+field).upper())
 
268
                else:
 
269
                        kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
 
270
                        if not'msg'in kw:
 
271
                                kw['msg']='Checking for type %s'%tu
 
272
                        if not'define_name'in kw:
 
273
                                kw['define_name']=self.have_define(tu.upper())
 
274
        elif'header_name'in kw:
 
275
                if not'msg'in kw:
 
276
                        kw['msg']='Checking for header %s'%kw['header_name']
 
277
                l=Utils.to_list(kw['header_name'])
 
278
                assert len(l)>0,'list of headers in header_name is empty'
 
279
                kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
 
280
                if not'uselib_store'in kw:
 
281
                        kw['uselib_store']=l[0].upper()
 
282
                if not'define_name'in kw:
 
283
                        kw['define_name']=self.have_define(l[0])
 
284
        if'lib'in kw:
 
285
                if not'msg'in kw:
 
286
                        kw['msg']='Checking for library %s'%kw['lib']
 
287
                if not'uselib_store'in kw:
 
288
                        kw['uselib_store']=kw['lib'].upper()
 
289
        if'stlib'in kw:
 
290
                if not'msg'in kw:
 
291
                        kw['msg']='Checking for static library %s'%kw['stlib']
 
292
                if not'uselib_store'in kw:
 
293
                        kw['uselib_store']=kw['stlib'].upper()
 
294
        if'fragment'in kw:
 
295
                kw['code']=kw['fragment']
 
296
                if not'msg'in kw:
 
297
                        kw['msg']='Checking for code snippet'
 
298
                if not'errmsg'in kw:
 
299
                        kw['errmsg']='no'
 
300
        for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
 
301
                if flagsname in kw:
 
302
                        if not'msg'in kw:
 
303
                                kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
 
304
                        if not'errmsg'in kw:
 
305
                                kw['errmsg']='no'
 
306
        if not'execute'in kw:
 
307
                kw['execute']=False
 
308
        if kw['execute']:
 
309
                kw['features'].append('test_exec')
 
310
        if not'errmsg'in kw:
 
311
                kw['errmsg']='not found'
 
312
        if not'okmsg'in kw:
 
313
                kw['okmsg']='yes'
 
314
        if not'code'in kw:
 
315
                kw['code']=SNIP_EMPTY_PROGRAM
 
316
        if self.env[INCKEYS]:
 
317
                kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
 
318
        if not kw.get('success'):kw['success']=None
 
319
        if'define_name'in kw:
 
320
                self.undefine(kw['define_name'])
 
321
        assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
 
322
@conf
 
323
def post_check(self,*k,**kw):
 
324
        is_success=0
 
325
        if kw['execute']:
 
326
                if kw['success']is not None:
 
327
                        if kw.get('define_ret',False):
 
328
                                is_success=kw['success']
 
329
                        else:
 
330
                                is_success=(kw['success']==0)
 
331
        else:
 
332
                is_success=(kw['success']==0)
 
333
        if'define_name'in kw:
 
334
                if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
 
335
                        if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
 
336
                                self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
 
337
                        else:
 
338
                                self.define_cond(kw['define_name'],is_success)
 
339
                else:
 
340
                        self.define_cond(kw['define_name'],is_success)
 
341
        if'header_name'in kw:
 
342
                if kw.get('auto_add_header_name',False):
 
343
                        self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
 
344
        if is_success and'uselib_store'in kw:
 
345
                from waflib.Tools import ccroot
 
346
                _vars=set([])
 
347
                for x in kw['features']:
 
348
                        if x in ccroot.USELIB_VARS:
 
349
                                _vars|=ccroot.USELIB_VARS[x]
 
350
                for k in _vars:
 
351
                        lk=k.lower()
 
352
                        if k=='INCLUDES':lk='includes'
 
353
                        if k=='DEFINES':lk='defines'
 
354
                        if lk in kw:
 
355
                                val=kw[lk]
 
356
                                if isinstance(val,str):
 
357
                                        val=val.rstrip(os.path.sep)
 
358
                                self.env.append_unique(k+'_'+kw['uselib_store'],val)
 
359
        return is_success
 
360
@conf
 
361
def check(self,*k,**kw):
 
362
        self.validate_c(kw)
 
363
        self.start_msg(kw['msg'])
 
364
        ret=None
 
365
        try:
 
366
                ret=self.run_c_code(*k,**kw)
 
367
        except self.errors.ConfigurationError:
 
368
                self.end_msg(kw['errmsg'],'YELLOW')
 
369
                if Logs.verbose>1:
 
370
                        raise
 
371
                else:
 
372
                        self.fatal('The configuration failed')
 
373
        else:
 
374
                kw['success']=ret
 
375
        ret=self.post_check(*k,**kw)
 
376
        if not ret:
 
377
                self.end_msg(kw['errmsg'],'YELLOW')
 
378
                self.fatal('The configuration failed %r'%ret)
 
379
        else:
 
380
                self.end_msg(self.ret_msg(kw['okmsg'],kw))
 
381
        return ret
 
382
class test_exec(Task.Task):
 
383
        color='PINK'
 
384
        def run(self):
 
385
                if getattr(self.generator,'rpath',None):
 
386
                        if getattr(self.generator,'define_ret',False):
 
387
                                self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
 
388
                        else:
 
389
                                self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
 
390
                else:
 
391
                        env=self.env.env or{}
 
392
                        env.update(dict(os.environ))
 
393
                        for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
 
394
                                env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
 
395
                        if getattr(self.generator,'define_ret',False):
 
396
                                self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
 
397
                        else:
 
398
                                self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
 
399
@feature('test_exec')
 
400
@after_method('apply_link')
 
401
def test_exec_fun(self):
 
402
        self.create_task('test_exec',self.link_task.outputs[0])
 
403
CACHE_RESULTS=1
 
404
COMPILE_ERRORS=2
 
405
@conf
 
406
def run_c_code(self,*k,**kw):
 
407
        lst=[str(v)for(p,v)in kw.items()if p!='env']
 
408
        h=Utils.h_list(lst)
 
409
        dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
 
410
        try:
 
411
                os.makedirs(dir)
 
412
        except OSError:
 
413
                pass
 
414
        try:
 
415
                os.stat(dir)
 
416
        except OSError:
 
417
                self.fatal('cannot use the configuration test folder %r'%dir)
 
418
        cachemode=getattr(Options.options,'confcache',None)
 
419
        if cachemode==CACHE_RESULTS:
 
420
                try:
 
421
                        proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
 
422
                except OSError:
 
423
                        pass
 
424
                else:
 
425
                        ret=proj['cache_run_c_code']
 
426
                        if isinstance(ret,str)and ret.startswith('Test does not build'):
 
427
                                self.fatal(ret)
 
428
                        return ret
 
429
        bdir=os.path.join(dir,'testbuild')
 
430
        if not os.path.exists(bdir):
 
431
                os.makedirs(bdir)
 
432
        self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
 
433
        bld.init_dirs()
 
434
        bld.progress_bar=0
 
435
        bld.targets='*'
 
436
        if kw['compile_filename']:
 
437
                node=bld.srcnode.make_node(kw['compile_filename'])
 
438
                node.write(kw['code'])
 
439
        bld.logger=self.logger
 
440
        bld.all_envs.update(self.all_envs)
 
441
        bld.env=kw['env']
 
442
        o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
 
443
        for k,v in kw.items():
 
444
                setattr(o,k,v)
 
445
        self.to_log("==>\n%s\n<=="%kw['code'])
 
446
        bld.targets='*'
 
447
        ret=-1
 
448
        try:
 
449
                try:
 
450
                        bld.compile()
 
451
                except Errors.WafError:
 
452
                        ret='Test does not build: %s'%Utils.ex_stack()
 
453
                        self.fatal(ret)
 
454
                else:
 
455
                        ret=getattr(bld,'retval',0)
 
456
        finally:
 
457
                proj=ConfigSet.ConfigSet()
 
458
                proj['cache_run_c_code']=ret
 
459
                proj.store(os.path.join(dir,'cache_run_c_code'))
 
460
        return ret
 
461
@conf
 
462
def check_cxx(self,*k,**kw):
 
463
        kw['compiler']='cxx'
 
464
        return self.check(*k,**kw)
 
465
@conf
 
466
def check_cc(self,*k,**kw):
 
467
        kw['compiler']='c'
 
468
        return self.check(*k,**kw)
 
469
@conf
 
470
def define(self,key,val,quote=True):
 
471
        assert key and isinstance(key,str)
 
472
        if val is True:
 
473
                val=1
 
474
        elif val in(False,None):
 
475
                val=0
 
476
        if isinstance(val,int)or isinstance(val,float):
 
477
                s='%s=%s'
 
478
        else:
 
479
                s=quote and'%s="%s"'or'%s=%s'
 
480
        app=s%(key,str(val))
 
481
        ban=key+'='
 
482
        lst=self.env['DEFINES']
 
483
        for x in lst:
 
484
                if x.startswith(ban):
 
485
                        lst[lst.index(x)]=app
 
486
                        break
 
487
        else:
 
488
                self.env.append_value('DEFINES',app)
 
489
        self.env.append_unique(DEFKEYS,key)
 
490
@conf
 
491
def undefine(self,key):
 
492
        assert key and isinstance(key,str)
 
493
        ban=key+'='
 
494
        lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
 
495
        self.env['DEFINES']=lst
 
496
        self.env.append_unique(DEFKEYS,key)
 
497
@conf
 
498
def define_cond(self,key,val):
 
499
        assert key and isinstance(key,str)
 
500
        if val:
 
501
                self.define(key,1)
 
502
        else:
 
503
                self.undefine(key)
 
504
@conf
 
505
def is_defined(self,key):
 
506
        assert key and isinstance(key,str)
 
507
        ban=key+'='
 
508
        for x in self.env['DEFINES']:
 
509
                if x.startswith(ban):
 
510
                        return True
 
511
        return False
 
512
@conf
 
513
def get_define(self,key):
 
514
        assert key and isinstance(key,str)
 
515
        ban=key+'='
 
516
        for x in self.env['DEFINES']:
 
517
                if x.startswith(ban):
 
518
                        return x[len(ban):]
 
519
        return None
 
520
@conf
 
521
def have_define(self,key):
 
522
        return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
 
523
@conf
 
524
def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
 
525
        if env:
 
526
                Logs.warn('Cannot pass env to write_config_header')
 
527
        if not configfile:configfile=WAF_CONFIG_H
 
528
        waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
 
529
        node=top and self.bldnode or self.path.get_bld()
 
530
        node=node.make_node(configfile)
 
531
        node.parent.mkdir()
 
532
        lst=['/* WARNING! All changes made to this file will be lost! */\n']
 
533
        lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
 
534
        lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
 
535
        lst.append('\n#endif /* %s */\n'%waf_guard)
 
536
        node.write('\n'.join(lst))
 
537
        self.env.append_unique(Build.CFG_FILES,[node.abspath()])
 
538
        if remove:
 
539
                for key in self.env[DEFKEYS]:
 
540
                        self.undefine(key)
 
541
                self.env[DEFKEYS]=[]
 
542
@conf
 
543
def get_config_header(self,defines=True,headers=False,define_prefix=''):
 
544
        lst=[]
 
545
        if headers:
 
546
                for x in self.env[INCKEYS]:
 
547
                        lst.append('#include <%s>'%x)
 
548
        if defines:
 
549
                for x in self.env[DEFKEYS]:
 
550
                        if self.is_defined(x):
 
551
                                val=self.get_define(x)
 
552
                                lst.append('#define %s %s'%(define_prefix+x,val))
 
553
                        else:
 
554
                                lst.append('/* #undef %s */'%(define_prefix+x))
 
555
        return"\n".join(lst)
 
556
@conf
 
557
def cc_add_flags(conf):
 
558
        conf.add_os_flags('CPPFLAGS','CFLAGS')
 
559
        conf.add_os_flags('CFLAGS')
 
560
@conf
 
561
def cxx_add_flags(conf):
 
562
        conf.add_os_flags('CPPFLAGS','CXXFLAGS')
 
563
        conf.add_os_flags('CXXFLAGS')
 
564
@conf
 
565
def link_add_flags(conf):
 
566
        conf.add_os_flags('LINKFLAGS')
 
567
        conf.add_os_flags('LDFLAGS','LINKFLAGS')
 
568
@conf
 
569
def cc_load_tools(conf):
 
570
        if not conf.env.DEST_OS:
 
571
                conf.env.DEST_OS=Utils.unversioned_sys_platform()
 
572
        conf.load('c')
 
573
@conf
 
574
def cxx_load_tools(conf):
 
575
        if not conf.env.DEST_OS:
 
576
                conf.env.DEST_OS=Utils.unversioned_sys_platform()
 
577
        conf.load('cxx')
 
578
@conf
 
579
def get_cc_version(conf,cc,gcc=False,icc=False):
 
580
        cmd=cc+['-dM','-E','-']
 
581
        env=conf.env.env or None
 
582
        try:
 
583
                p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
 
584
                p.stdin.write('\n')
 
585
                out=p.communicate()[0]
 
586
        except Exception:
 
587
                conf.fatal('Could not determine the compiler version %r'%cmd)
 
588
        if not isinstance(out,str):
 
589
                out=out.decode(sys.stdout.encoding or'iso8859-1')
 
590
        if gcc:
 
591
                if out.find('__INTEL_COMPILER')>=0:
 
592
                        conf.fatal('The intel compiler pretends to be gcc')
 
593
                if out.find('__GNUC__')<0:
 
594
                        conf.fatal('Could not determine the compiler type')
 
595
        if icc and out.find('__INTEL_COMPILER')<0:
 
596
                conf.fatal('Not icc/icpc')
 
597
        k={}
 
598
        if icc or gcc:
 
599
                out=out.splitlines()
 
600
                for line in out:
 
601
                        lst=shlex.split(line)
 
602
                        if len(lst)>2:
 
603
                                key=lst[1]
 
604
                                val=lst[2]
 
605
                                k[key]=val
 
606
                def isD(var):
 
607
                        return var in k
 
608
                def isT(var):
 
609
                        return var in k and k[var]!='0'
 
610
                if not conf.env.DEST_OS:
 
611
                        conf.env.DEST_OS=''
 
612
                for i in MACRO_TO_DESTOS:
 
613
                        if isD(i):
 
614
                                conf.env.DEST_OS=MACRO_TO_DESTOS[i]
 
615
                                break
 
616
                else:
 
617
                        if isD('__APPLE__')and isD('__MACH__'):
 
618
                                conf.env.DEST_OS='darwin'
 
619
                        elif isD('__unix__'):
 
620
                                conf.env.DEST_OS='generic'
 
621
                if isD('__ELF__'):
 
622
                        conf.env.DEST_BINFMT='elf'
 
623
                elif isD('__WINNT__')or isD('__CYGWIN__'):
 
624
                        conf.env.DEST_BINFMT='pe'
 
625
                        conf.env.LIBDIR=conf.env['PREFIX']+'/bin'
 
626
                elif isD('__APPLE__'):
 
627
                        conf.env.DEST_BINFMT='mac-o'
 
628
                if not conf.env.DEST_BINFMT:
 
629
                        conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
 
630
                for i in MACRO_TO_DEST_CPU:
 
631
                        if isD(i):
 
632
                                conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
 
633
                                break
 
634
                Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
 
635
                if icc:
 
636
                        ver=k['__INTEL_COMPILER']
 
637
                        conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
 
638
                else:
 
639
                        conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
 
640
        return k
 
641
@conf
 
642
def get_xlc_version(conf,cc):
 
643
        cmd=cc+['-qversion']
 
644
        try:
 
645
                out,err=conf.cmd_and_log(cmd,output=0)
 
646
        except Errors.WafError:
 
647
                conf.fatal('Could not find xlc %r'%cmd)
 
648
        for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)"):
 
649
                version_re=re.compile(v,re.I).search
 
650
                match=version_re(out or err)
 
651
                if match:
 
652
                        k=match.groupdict()
 
653
                        conf.env['CC_VERSION']=(k['major'],k['minor'])
 
654
                        break
 
655
        else:
 
656
                conf.fatal('Could not determine the XLC version.')
 
657
@conf
 
658
def add_as_needed(self):
 
659
        if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
 
660
                self.env.append_unique('LINKFLAGS','--as-needed')
 
661
class cfgtask(Task.TaskBase):
 
662
        def display(self):
 
663
                return''
 
664
        def runnable_status(self):
 
665
                return Task.RUN_ME
 
666
        def uid(self):
 
667
                return Utils.SIG_NIL
 
668
        def run(self):
 
669
                conf=self.conf
 
670
                bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
 
671
                bld.env=conf.env
 
672
                bld.init_dirs()
 
673
                bld.in_msg=1
 
674
                bld.logger=self.logger
 
675
                try:
 
676
                        bld.check(**self.args)
 
677
                except Exception:
 
678
                        return 1
 
679
@conf
 
680
def multicheck(self,*k,**kw):
 
681
        self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
 
682
        class par(object):
 
683
                def __init__(self):
 
684
                        self.keep=False
 
685
                        self.cache_global=Options.cache_global
 
686
                        self.nocache=Options.options.nocache
 
687
                        self.returned_tasks=[]
 
688
                        self.task_sigs={}
 
689
                def total(self):
 
690
                        return len(tasks)
 
691
                def to_log(self,*k,**kw):
 
692
                        return
 
693
        bld=par()
 
694
        tasks=[]
 
695
        for dct in k:
 
696
                x=cfgtask(bld=bld)
 
697
                tasks.append(x)
 
698
                x.args=dct
 
699
                x.bld=bld
 
700
                x.conf=self
 
701
                x.args=dct
 
702
                x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
 
703
        def it():
 
704
                yield tasks
 
705
                while 1:
 
706
                        yield[]
 
707
        p=Runner.Parallel(bld,Options.options.jobs)
 
708
        p.biter=it()
 
709
        p.start()
 
710
        for x in tasks:
 
711
                x.logger.memhandler.flush()
 
712
        for x in tasks:
 
713
                if x.hasrun!=Task.SUCCESS:
 
714
                        self.end_msg(kw.get('errmsg','no'),color='YELLOW')
 
715
                        self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
 
716
        self.end_msg('ok')