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