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 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') |
---|
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__')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: |
---|
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 get_suncc_version(conf,cc): |
---|
671 | cmd=cc+['-V'] |
---|
672 | try: |
---|
673 | out,err=conf.cmd_and_log(cmd,output=0) |
---|
674 | except Errors.WafError: |
---|
675 | conf.fatal('Could not find suncc %r'%cmd) |
---|
676 | version=(out or err) |
---|
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) |
---|
680 | if match: |
---|
681 | k=match.groupdict() |
---|
682 | conf.env['CC_VERSION']=(k['major'],k['minor']) |
---|
683 | else: |
---|
684 | conf.fatal('Could not determine the suncc version.') |
---|
685 | @conf |
---|
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): |
---|
690 | def display(self): |
---|
691 | return'' |
---|
692 | def runnable_status(self): |
---|
693 | return Task.RUN_ME |
---|
694 | def uid(self): |
---|
695 | return Utils.SIG_NIL |
---|
696 | def run(self): |
---|
697 | conf=self.conf |
---|
698 | bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath()) |
---|
699 | bld.env=conf.env |
---|
700 | bld.init_dirs() |
---|
701 | bld.in_msg=1 |
---|
702 | bld.logger=self.logger |
---|
703 | try: |
---|
704 | bld.check(**self.args) |
---|
705 | except Exception: |
---|
706 | return 1 |
---|
707 | @conf |
---|
708 | def multicheck(self,*k,**kw): |
---|
709 | self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k))) |
---|
710 | class par(object): |
---|
711 | def __init__(self): |
---|
712 | self.keep=False |
---|
713 | self.cache_global=Options.cache_global |
---|
714 | self.nocache=Options.options.nocache |
---|
715 | self.returned_tasks=[] |
---|
716 | self.task_sigs={} |
---|
717 | def total(self): |
---|
718 | return len(tasks) |
---|
719 | def to_log(self,*k,**kw): |
---|
720 | return |
---|
721 | bld=par() |
---|
722 | tasks=[] |
---|
723 | for dct in k: |
---|
724 | x=cfgtask(bld=bld) |
---|
725 | tasks.append(x) |
---|
726 | x.args=dct |
---|
727 | x.bld=bld |
---|
728 | x.conf=self |
---|
729 | x.args=dct |
---|
730 | x.logger=Logs.make_mem_logger(str(id(x)),self.logger) |
---|
731 | def it(): |
---|
732 | yield tasks |
---|
733 | while 1: |
---|
734 | yield[] |
---|
735 | p=Runner.Parallel(bld,Options.options.jobs) |
---|
736 | p.biter=it() |
---|
737 | p.start() |
---|
738 | for x in tasks: |
---|
739 | x.logger.memhandler.flush() |
---|
740 | for x in tasks: |
---|
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') |
---|
744 | self.end_msg('ok') |
---|