source: trunk/server/buildtools/wafsamba/samba_autoconf.py

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 22.8 KB
Line 
1# a waf tool to add autoconf-like macros to the configure section
2
3import Build, os, sys, Options, preproc, Logs
4import string
5from Configure import conf
6from samba_utils import *
7import samba_cross
8
9missing_headers = set()
10
11####################################################
12# some autoconf like helpers, to make the transition
13# to waf a bit easier for those used to autoconf
14# m4 files
15
16@runonce
17@conf
18def DEFINE(conf, d, v, add_to_cflags=False, quote=False):
19 '''define a config option'''
20 conf.define(d, v, quote=quote)
21 if add_to_cflags:
22 conf.env.append_value('CCDEFINES', d + '=' + str(v))
23
24def hlist_to_string(conf, headers=None):
25 '''convert a headers list to a set of #include lines'''
26 hdrs=''
27 hlist = conf.env.hlist
28 if headers:
29 hlist = hlist[:]
30 hlist.extend(TO_LIST(headers))
31 for h in hlist:
32 hdrs += '#include <%s>\n' % h
33 return hdrs
34
35
36@conf
37def COMPOUND_START(conf, msg):
38 '''start a compound test'''
39 def null_check_message_1(self,*k,**kw):
40 return
41 def null_check_message_2(self,*k,**kw):
42 return
43
44 v = getattr(conf.env, 'in_compound', [])
45 if v != [] and v != 0:
46 conf.env.in_compound = v + 1
47 return
48 conf.check_message_1(msg)
49 conf.saved_check_message_1 = conf.check_message_1
50 conf.check_message_1 = null_check_message_1
51 conf.saved_check_message_2 = conf.check_message_2
52 conf.check_message_2 = null_check_message_2
53 conf.env.in_compound = 1
54
55
56@conf
57def COMPOUND_END(conf, result):
58 '''start a compound test'''
59 conf.env.in_compound -= 1
60 if conf.env.in_compound != 0:
61 return
62 conf.check_message_1 = conf.saved_check_message_1
63 conf.check_message_2 = conf.saved_check_message_2
64 p = conf.check_message_2
65 if result == True:
66 p('ok ')
67 elif result == False:
68 p('not found', 'YELLOW')
69 else:
70 p(result)
71
72
73@feature('nolink')
74def nolink(self):
75 '''using the nolink type in conf.check() allows us to avoid
76 the link stage of a test, thus speeding it up for tests
77 that where linking is not needed'''
78 pass
79
80
81def CHECK_HEADER(conf, h, add_headers=False, lib=None):
82 '''check for a header'''
83 if h in missing_headers and lib is None:
84 return False
85 d = h.upper().replace('/', '_')
86 d = d.replace('.', '_')
87 d = d.replace('-', '_')
88 d = 'HAVE_%s' % d
89 if CONFIG_SET(conf, d):
90 if add_headers:
91 if not h in conf.env.hlist:
92 conf.env.hlist.append(h)
93 return True
94
95 (ccflags, ldflags) = library_flags(conf, lib)
96
97 hdrs = hlist_to_string(conf, headers=h)
98 ret = conf.check(fragment='%s\nint main(void) { return 0; }' % hdrs,
99 type='nolink',
100 execute=0,
101 ccflags=ccflags,
102 msg="Checking for header %s" % h)
103 if not ret:
104 missing_headers.add(h)
105 return False
106
107 conf.DEFINE(d, 1)
108 if add_headers and not h in conf.env.hlist:
109 conf.env.hlist.append(h)
110 return ret
111
112
113@conf
114def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None):
115 '''check for a list of headers
116
117 when together==True, then the headers accumulate within this test.
118 This is useful for interdependent headers
119 '''
120 ret = True
121 if not add_headers and together:
122 saved_hlist = conf.env.hlist[:]
123 set_add_headers = True
124 else:
125 set_add_headers = add_headers
126 for hdr in TO_LIST(headers):
127 if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib):
128 ret = False
129 if not add_headers and together:
130 conf.env.hlist = saved_hlist
131 return ret
132
133
134def header_list(conf, headers=None, lib=None):
135 '''form a list of headers which exist, as a string'''
136 hlist=[]
137 if headers is not None:
138 for h in TO_LIST(headers):
139 if CHECK_HEADER(conf, h, add_headers=False, lib=lib):
140 hlist.append(h)
141 return hlist_to_string(conf, headers=hlist)
142
143
144@conf
145def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None):
146 '''check for a single type'''
147 if define is None:
148 define = 'HAVE_' + t.upper().replace(' ', '_')
149 if msg is None:
150 msg='Checking for %s' % t
151 ret = CHECK_CODE(conf, '%s _x' % t,
152 define,
153 execute=False,
154 headers=headers,
155 local_include=False,
156 msg=msg,
157 lib=lib,
158 link=False)
159 if not ret and alternate:
160 conf.DEFINE(t, alternate)
161 return ret
162
163
164@conf
165def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None):
166 '''check for a list of types'''
167 ret = True
168 for t in TO_LIST(list):
169 if not CHECK_TYPE(conf, t, headers=headers,
170 define=define, alternate=alternate, lib=lib):
171 ret = False
172 return ret
173
174
175@conf
176def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None):
177 '''check for a single type with a header'''
178 return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define)
179
180
181@conf
182def CHECK_VARIABLE(conf, v, define=None, always=False,
183 headers=None, msg=None, lib=None):
184 '''check for a variable declaration (or define)'''
185 if define is None:
186 define = 'HAVE_%s' % v.upper()
187
188 if msg is None:
189 msg="Checking for variable %s" % v
190
191 return CHECK_CODE(conf,
192 # we need to make sure the compiler doesn't
193 # optimize it out...
194 '''
195 #ifndef %s
196 void *_x; _x=(void *)&%s; return (int)_x;
197 #endif
198 return 0
199 ''' % (v, v),
200 execute=False,
201 link=False,
202 msg=msg,
203 local_include=False,
204 lib=lib,
205 headers=headers,
206 define=define,
207 always=always)
208
209
210@conf
211def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False):
212 '''check a list of variable declarations, using the HAVE_DECL_xxx form
213 of define
214
215 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
216 '''
217 ret = True
218 for v in TO_LIST(vars):
219 if not reverse:
220 define='HAVE_DECL_%s' % v.upper()
221 else:
222 define='HAVE_%s_DECL' % v.upper()
223 if not CHECK_VARIABLE(conf, v,
224 define=define,
225 headers=headers,
226 msg='Checking for declaration of %s' % v,
227 always=always):
228 ret = False
229 return ret
230
231
232def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
233 '''check for a function'''
234 define='HAVE_%s' % f.upper()
235
236 ret = False
237
238 conf.COMPOUND_START('Checking for %s' % f)
239
240 if link is None or link == True:
241 ret = CHECK_CODE(conf,
242 # this is based on the autoconf strategy
243 '''
244 #define %s __fake__%s
245 #ifdef HAVE_LIMITS_H
246 # include <limits.h>
247 #else
248 # include <assert.h>
249 #endif
250 #undef %s
251 #if defined __stub_%s || defined __stub___%s
252 #error "bad glibc stub"
253 #endif
254 extern char %s();
255 int main() { return %s(); }
256 ''' % (f, f, f, f, f, f, f),
257 execute=False,
258 link=True,
259 addmain=False,
260 add_headers=False,
261 define=define,
262 local_include=False,
263 lib=lib,
264 headers=headers,
265 msg='Checking for %s' % f)
266
267 if not ret:
268 ret = CHECK_CODE(conf,
269 # it might be a macro
270 # we need to make sure the compiler doesn't
271 # optimize it out...
272 'void *__x = (void *)%s; return (int)__x' % f,
273 execute=False,
274 link=True,
275 addmain=True,
276 add_headers=True,
277 define=define,
278 local_include=False,
279 lib=lib,
280 headers=headers,
281 msg='Checking for macro %s' % f)
282
283 if not ret and (link is None or link == False):
284 ret = CHECK_VARIABLE(conf, f,
285 define=define,
286 headers=headers,
287 msg='Checking for declaration of %s' % f)
288 conf.COMPOUND_END(ret)
289 return ret
290
291
292@conf
293def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None):
294 '''check for a list of functions'''
295 ret = True
296 for f in TO_LIST(list):
297 if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers):
298 ret = False
299 return ret
300
301
302@conf
303def CHECK_SIZEOF(conf, vars, headers=None, define=None):
304 '''check the size of a type'''
305 ret = True
306 for v in TO_LIST(vars):
307 v_define = define
308 if v_define is None:
309 v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
310 if not CHECK_CODE(conf,
311 'printf("%%u", (unsigned)sizeof(%s))' % v,
312 define=v_define,
313 execute=True,
314 define_ret=True,
315 quote=False,
316 headers=headers,
317 local_include=False,
318 msg="Checking size of %s" % v):
319 ret = False
320 return ret
321
322
323
324@conf
325def CHECK_CODE(conf, code, define,
326 always=False, execute=False, addmain=True,
327 add_headers=True, mandatory=False,
328 headers=None, msg=None, cflags='', includes='# .',
329 local_include=True, lib=None, link=True,
330 define_ret=False, quote=False,
331 on_target=True):
332 '''check if some code compiles and/or runs'''
333
334 if CONFIG_SET(conf, define):
335 return True
336
337 if headers is not None:
338 CHECK_HEADERS(conf, headers=headers, lib=lib)
339
340 if add_headers:
341 hdrs = header_list(conf, headers=headers, lib=lib)
342 else:
343 hdrs = ''
344 if execute:
345 execute = 1
346 else:
347 execute = 0
348
349 defs = conf.get_config_header()
350
351 if addmain:
352 fragment='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs, hdrs, code)
353 else:
354 fragment='%s\n%s\n%s\n' % (defs, hdrs, code)
355
356 if msg is None:
357 msg="Checking for %s" % define
358
359 cflags = TO_LIST(cflags)
360
361 if local_include:
362 cflags.append('-I%s' % conf.curdir)
363
364 if not link:
365 type='nolink'
366 else:
367 type='cprogram'
368
369 uselib = TO_LIST(lib)
370
371 (ccflags, ldflags) = library_flags(conf, uselib)
372
373 cflags.extend(ccflags)
374
375 if on_target:
376 exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
377 else:
378 exec_args = []
379
380 conf.COMPOUND_START(msg)
381
382 ret = conf.check(fragment=fragment,
383 execute=execute,
384 define_name = define,
385 mandatory = mandatory,
386 ccflags=cflags,
387 ldflags=ldflags,
388 includes=includes,
389 uselib=uselib,
390 type=type,
391 msg=msg,
392 quote=quote,
393 exec_args=exec_args,
394 define_ret=define_ret)
395 if not ret and CONFIG_SET(conf, define):
396 # sometimes conf.check() returns false, but it
397 # sets the define. Maybe a waf bug?
398 ret = True
399 if ret:
400 if not define_ret:
401 conf.DEFINE(define, 1)
402 conf.COMPOUND_END(True)
403 else:
404 conf.COMPOUND_END(conf.env[define])
405 return True
406 if always:
407 conf.DEFINE(define, 0)
408 conf.COMPOUND_END(False)
409 return False
410
411
412
413@conf
414def CHECK_STRUCTURE_MEMBER(conf, structname, member,
415 always=False, define=None, headers=None):
416 '''check for a structure member'''
417 if define is None:
418 define = 'HAVE_%s' % member.upper()
419 return CHECK_CODE(conf,
420 '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
421 define,
422 execute=False,
423 link=False,
424 always=always,
425 headers=headers,
426 local_include=False,
427 msg="Checking for member %s in %s" % (member, structname))
428
429
430@conf
431def CHECK_CFLAGS(conf, cflags):
432 '''check if the given cflags are accepted by the compiler
433 '''
434 return conf.check(fragment='int main(void) { return 0; }\n',
435 execute=0,
436 type='nolink',
437 ccflags=cflags,
438 msg="Checking compiler accepts %s" % cflags)
439
440@conf
441def CHECK_LDFLAGS(conf, ldflags):
442 '''check if the given ldflags are accepted by the linker
443 '''
444 return conf.check(fragment='int main(void) { return 0; }\n',
445 execute=0,
446 ldflags=ldflags,
447 msg="Checking linker accepts %s" % ldflags)
448
449
450@conf
451def CONFIG_GET(conf, option):
452 '''return True if a configuration option was found'''
453 if (option in conf.env):
454 return conf.env[option]
455 else:
456 return None
457
458@conf
459def CONFIG_SET(conf, option):
460 '''return True if a configuration option was found'''
461 return (option in conf.env) and (conf.env[option] != ())
462Build.BuildContext.CONFIG_SET = CONFIG_SET
463Build.BuildContext.CONFIG_GET = CONFIG_GET
464
465
466def library_flags(self, libs):
467 '''work out flags from pkg_config'''
468 ccflags = []
469 ldflags = []
470 for lib in TO_LIST(libs):
471 inc_path = getattr(self.env, 'CPPPATH_%s' % lib.upper(), [])
472 lib_path = getattr(self.env, 'LIBPATH_%s' % lib.upper(), [])
473 ccflags.extend(['-I%s' % i for i in inc_path])
474 ldflags.extend(['-L%s' % l for l in lib_path])
475 extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
476 extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
477 ccflags.extend(extra_ccflags)
478 ldflags.extend(extra_ldflags)
479 if 'EXTRA_LDFLAGS' in self.env:
480 ldflags.extend(self.env['EXTRA_LDFLAGS'])
481
482 ccflags = unique_list(ccflags)
483 ldflags = unique_list(ldflags)
484 return (ccflags, ldflags)
485
486
487@conf
488def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
489 '''check if a set of libraries exist as system libraries
490
491 returns the sublist of libs that do exist as a syslib or []
492 '''
493
494 fragment= '''
495int foo()
496{
497 int v = 2;
498 return v*2;
499}
500'''
501 ret = []
502 liblist = TO_LIST(libs)
503 for lib in liblist[:]:
504 if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
505 ret.append(lib)
506 continue
507
508 (ccflags, ldflags) = library_flags(conf, lib)
509 if shlib:
510 res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags)
511 else:
512 res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags)
513
514 if not res:
515 if mandatory:
516 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
517 sys.exit(1)
518 if empty_decl:
519 # if it isn't a mandatory library, then remove it from dependency lists
520 if set_target:
521 SET_TARGET_TYPE(conf, lib, 'EMPTY')
522 else:
523 conf.define('HAVE_LIB%s' % lib.upper().replace('-','_'), 1)
524 conf.env['LIB_' + lib.upper()] = lib
525 if set_target:
526 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
527 ret.append(lib)
528
529 return ret
530
531
532
533@conf
534def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
535 headers=None, link=True, empty_decl=True, set_target=True):
536 """
537 check that the functions in 'list' are available in 'library'
538 if they are, then make that library available as a dependency
539
540 if the library is not available and mandatory==True, then
541 raise an error.
542
543 If the library is not available and mandatory==False, then
544 add the library to the list of dependencies to remove from
545 build rules
546
547 optionally check for the functions first in libc
548 """
549 remaining = TO_LIST(list)
550 liblist = TO_LIST(library)
551
552 # check if some already found
553 for f in remaining[:]:
554 if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
555 remaining.remove(f)
556
557 # see if the functions are in libc
558 if checklibc:
559 for f in remaining[:]:
560 if CHECK_FUNC(conf, f, link=True, headers=headers):
561 remaining.remove(f)
562
563 if remaining == []:
564 for lib in liblist:
565 if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
566 SET_TARGET_TYPE(conf, lib, 'EMPTY')
567 return True
568
569 checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
570 for lib in liblist[:]:
571 if not lib in checklist and mandatory:
572 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
573 sys.exit(1)
574
575 ret = True
576 for f in remaining:
577 if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
578 ret = False
579
580 return ret
581
582
583@conf
584def IN_LAUNCH_DIR(conf):
585 '''return True if this rule is being run from the launch directory'''
586 return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
587Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
588
589
590@conf
591def SAMBA_CONFIG_H(conf, path=None):
592 '''write out config.h in the right directory'''
593 # we don't want to produce a config.h in places like lib/replace
594 # when we are building projects that depend on lib/replace
595 if not IN_LAUNCH_DIR(conf):
596 return
597
598 if Options.options.developer:
599 # we add these here to ensure that -Wstrict-prototypes is not set during configure
600 conf.ADD_CFLAGS('-Wall -g -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Werror-implicit-function-declaration -Wformat=2 -Wno-format-y2k -Wmissing-prototypes',
601 testflags=True)
602 if os.getenv('TOPLEVEL_BUILD'):
603 conf.ADD_CFLAGS('-Wcast-qual', testflags=True)
604 conf.env.DEVELOPER_MODE = True
605
606 if Options.options.picky_developer:
607 conf.ADD_CFLAGS('-Werror', testflags=True)
608
609 if Options.options.fatal_errors:
610 conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
611
612 if Options.options.pedantic:
613 conf.ADD_CFLAGS('-W', testflags=True)
614
615 if path is None:
616 conf.write_config_header('config.h', top=True)
617 else:
618 conf.write_config_header(path)
619 conf.SAMBA_CROSS_CHECK_COMPLETE()
620
621
622@conf
623def CONFIG_PATH(conf, name, default):
624 '''setup a configurable path'''
625 if not name in conf.env:
626 if default[0] == '/':
627 conf.env[name] = default
628 else:
629 conf.env[name] = conf.env['PREFIX'] + default
630
631@conf
632def ADD_CFLAGS(conf, flags, testflags=False):
633 '''add some CFLAGS to the command line
634 optionally set testflags to ensure all the flags work
635 '''
636 if testflags:
637 ok_flags=[]
638 for f in flags.split():
639 if CHECK_CFLAGS(conf, f):
640 ok_flags.append(f)
641 flags = ok_flags
642 if not 'EXTRA_CFLAGS' in conf.env:
643 conf.env['EXTRA_CFLAGS'] = []
644 conf.env['EXTRA_CFLAGS'].extend(TO_LIST(flags))
645
646@conf
647def ADD_LDFLAGS(conf, flags, testflags=False):
648 '''add some LDFLAGS to the command line
649 optionally set testflags to ensure all the flags work
650
651 this will return the flags that are added, if any
652 '''
653 if testflags:
654 ok_flags=[]
655 for f in flags.split():
656 if CHECK_LDFLAGS(conf, f):
657 ok_flags.append(f)
658 flags = ok_flags
659 if not 'EXTRA_LDFLAGS' in conf.env:
660 conf.env['EXTRA_LDFLAGS'] = []
661 conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
662 return flags
663
664
665@conf
666def ADD_EXTRA_INCLUDES(conf, includes):
667 '''add some extra include directories to all builds'''
668 if not 'EXTRA_INCLUDES' in conf.env:
669 conf.env['EXTRA_INCLUDES'] = []
670 conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
671
672
673
674def CURRENT_CFLAGS(bld, target, cflags, hide_symbols=False):
675 '''work out the current flags. local flags are added first'''
676 if not 'EXTRA_CFLAGS' in bld.env:
677 list = []
678 else:
679 list = bld.env['EXTRA_CFLAGS'];
680 ret = TO_LIST(cflags)
681 ret.extend(list)
682 if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
683 ret.append('-fvisibility=hidden')
684 return ret
685
686
687@conf
688def CHECK_CC_ENV(conf):
689 """trim whitespaces from 'CC'.
690 The build farm sometimes puts a space at the start"""
691 if os.environ.get('CC'):
692 conf.env.CC = TO_LIST(os.environ.get('CC'))
693 if len(conf.env.CC) == 1:
694 # make for nicer logs if just a single command
695 conf.env.CC = conf.env.CC[0]
696
697
698@conf
699def SETUP_CONFIGURE_CACHE(conf, enable):
700 '''enable/disable cache of configure results'''
701 if enable:
702 # when -C is chosen, we will use a private cache and will
703 # not look into system includes. This roughtly matches what
704 # autoconf does with -C
705 cache_path = os.path.join(conf.blddir, '.confcache')
706 mkdir_p(cache_path)
707 Options.cache_global = os.environ['WAFCACHE'] = cache_path
708 else:
709 # when -C is not chosen we will not cache configure checks
710 # We set the recursion limit low to prevent waf from spending
711 # a lot of time on the signatures of the files.
712 Options.cache_global = os.environ['WAFCACHE'] = ''
713 preproc.recursion_limit = 1
714 # in either case we don't need to scan system includes
715 preproc.go_absolute = False
Note: See TracBrowser for help on using the repository browser.