1 # a waf tool to add autoconf-like macros to the configure section
3 import Build, os, sys, Options, preproc, Logs
5 from Configure import conf
6 from samba_utils import *
9 missing_headers = set()
11 ####################################################
12 # some autoconf like helpers, to make the transition
13 # to waf a bit easier for those used to autoconf
18 def DEFINE(conf, d, v, add_to_cflags=False, quote=False):
19 '''define a config option'''
20 conf.define(d, v, quote=quote)
22 conf.env.append_value('CCDEFINES', d + '=' + str(v))
24 def hlist_to_string(conf, headers=None):
25 '''convert a headers list to a set of #include lines'''
27 hlist = conf.env.hlist
30 hlist.extend(TO_LIST(headers))
32 hdrs += '#include <%s>\n' % h
37 def COMPOUND_START(conf, msg):
38 '''start a compound test'''
39 def null_check_message_1(self,*k,**kw):
41 def null_check_message_2(self,*k,**kw):
44 v = getattr(conf.env, 'in_compound', [])
45 if v != [] and v != 0:
46 conf.env.in_compound = v + 1
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
57 def COMPOUND_END(conf, result):
58 '''start a compound test'''
59 conf.env.in_compound -= 1
60 if conf.env.in_compound != 0:
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
68 p('not found', 'YELLOW')
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'''
81 def CHECK_HEADER(conf, h, add_headers=False, lib=None):
82 '''check for a header'''
83 if h in missing_headers and lib is None:
85 d = h.upper().replace('/', '_')
86 d = d.replace('.', '_')
87 d = d.replace('-', '_')
89 if CONFIG_SET(conf, d):
91 if not h in conf.env.hlist:
92 conf.env.hlist.append(h)
95 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
97 hdrs = hlist_to_string(conf, headers=h)
100 ret = conf.check(fragment='%s\nint main(void) { return 0; }' % hdrs,
106 msg="Checking for header %s" % h)
108 missing_headers.add(h)
112 if add_headers and not h in conf.env.hlist:
113 conf.env.hlist.append(h)
118 def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None):
119 '''check for a list of headers
121 when together==True, then the headers accumulate within this test.
122 This is useful for interdependent headers
125 if not add_headers and together:
126 saved_hlist = conf.env.hlist[:]
127 set_add_headers = True
129 set_add_headers = add_headers
130 for hdr in TO_LIST(headers):
131 if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib):
133 if not add_headers and together:
134 conf.env.hlist = saved_hlist
138 def header_list(conf, headers=None, lib=None):
139 '''form a list of headers which exist, as a string'''
141 if headers is not None:
142 for h in TO_LIST(headers):
143 if CHECK_HEADER(conf, h, add_headers=False, lib=lib):
145 return hlist_to_string(conf, headers=hlist)
149 def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None):
150 '''check for a single type'''
152 define = 'HAVE_' + t.upper().replace(' ', '_')
154 msg='Checking for %s' % t
155 ret = CHECK_CODE(conf, '%s _x' % t,
163 if not ret and alternate:
164 conf.DEFINE(t, alternate)
169 def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None):
170 '''check for a list of types'''
172 for t in TO_LIST(list):
173 if not CHECK_TYPE(conf, t, headers=headers,
174 define=define, alternate=alternate, lib=lib):
180 def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None):
181 '''check for a single type with a header'''
182 return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define)
186 def CHECK_VARIABLE(conf, v, define=None, always=False,
187 headers=None, msg=None, lib=None):
188 '''check for a variable declaration (or define)'''
190 define = 'HAVE_%s' % v.upper()
193 msg="Checking for variable %s" % v
195 return CHECK_CODE(conf,
196 # we need to make sure the compiler doesn't
200 void *_x; _x=(void *)&%s; return (int)_x;
215 def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False):
216 '''check a list of variable declarations, using the HAVE_DECL_xxx form
219 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
222 for v in TO_LIST(vars):
224 define='HAVE_DECL_%s' % v.upper()
226 define='HAVE_%s_DECL' % v.upper()
227 if not CHECK_VARIABLE(conf, v,
230 msg='Checking for declaration of %s' % v,
236 def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
237 '''check for a function'''
238 define='HAVE_%s' % f.upper()
242 conf.COMPOUND_START('Checking for %s' % f)
244 if link is None or link:
245 ret = CHECK_CODE(conf,
246 # this is based on the autoconf strategy
248 #define %s __fake__%s
255 #if defined __stub_%s || defined __stub___%s
256 #error "bad glibc stub"
259 int main() { return %s(); }
260 ''' % (f, f, f, f, f, f, f),
269 msg='Checking for %s' % f)
272 ret = CHECK_CODE(conf,
273 # it might be a macro
274 # we need to make sure the compiler doesn't
276 'void *__x = (void *)%s; return (int)__x' % f,
285 msg='Checking for macro %s' % f)
287 if not ret and (link is None or not link):
288 ret = CHECK_VARIABLE(conf, f,
291 msg='Checking for declaration of %s' % f)
292 conf.COMPOUND_END(ret)
297 def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None):
298 '''check for a list of functions'''
300 for f in TO_LIST(list):
301 if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers):
307 def CHECK_SIZEOF(conf, vars, headers=None, define=None):
308 '''check the size of a type'''
310 for v in TO_LIST(vars):
313 v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
314 if not CHECK_CODE(conf,
315 'printf("%%u", (unsigned)sizeof(%s))' % v,
322 msg="Checking size of %s" % v):
327 def CHECK_VALUEOF(conf, v, headers=None, define=None):
328 '''check the value of a variable/define'''
332 v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_')
334 'printf("%%u", (unsigned)(%s))' % v,
341 msg="Checking value of %s" % v):
342 return int(conf.env[v_define])
347 def CHECK_CODE(conf, code, define,
348 always=False, execute=False, addmain=True,
349 add_headers=True, mandatory=False,
350 headers=None, msg=None, cflags='', includes='# .',
351 local_include=True, lib=None, link=True,
352 define_ret=False, quote=False,
354 '''check if some code compiles and/or runs'''
356 if CONFIG_SET(conf, define):
359 if headers is not None:
360 CHECK_HEADERS(conf, headers=headers, lib=lib)
363 hdrs = header_list(conf, headers=headers, lib=lib)
371 defs = conf.get_config_header()
374 fragment='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs, hdrs, code)
376 fragment='%s\n%s\n%s\n' % (defs, hdrs, code)
379 msg="Checking for %s" % define
381 cflags = TO_LIST(cflags)
384 cflags.append('-I%s' % conf.curdir)
391 uselib = TO_LIST(lib)
393 (ccflags, ldflags, cpppath) = library_flags(conf, uselib)
395 includes = TO_LIST(includes)
396 includes.extend(cpppath)
398 uselib = [l.upper() for l in uselib]
400 cflags.extend(ccflags)
403 exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
407 conf.COMPOUND_START(msg)
409 ret = conf.check(fragment=fragment,
411 define_name = define,
412 mandatory = mandatory,
421 define_ret=define_ret)
422 if not ret and CONFIG_SET(conf, define):
423 # sometimes conf.check() returns false, but it
424 # sets the define. Maybe a waf bug?
428 conf.DEFINE(define, 1)
429 conf.COMPOUND_END(True)
431 conf.COMPOUND_END(conf.env[define])
434 conf.DEFINE(define, 0)
435 conf.COMPOUND_END(False)
441 def CHECK_STRUCTURE_MEMBER(conf, structname, member,
442 always=False, define=None, headers=None):
443 '''check for a structure member'''
445 define = 'HAVE_%s' % member.upper()
446 return CHECK_CODE(conf,
447 '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
454 msg="Checking for member %s in %s" % (member, structname))
458 def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'):
459 '''check if the given cflags are accepted by the compiler
461 return conf.check(fragment=fragment,
465 msg="Checking compiler accepts %s" % cflags)
468 def CHECK_LDFLAGS(conf, ldflags):
469 '''check if the given ldflags are accepted by the linker
471 return conf.check(fragment='int main(void) { return 0; }\n',
474 msg="Checking linker accepts %s" % ldflags)
478 def CONFIG_GET(conf, option):
479 '''return True if a configuration option was found'''
480 if (option in conf.env):
481 return conf.env[option]
486 def CONFIG_SET(conf, option):
487 '''return True if a configuration option was found'''
488 if option not in conf.env:
500 def CONFIG_RESET(conf, option):
501 if option not in conf.env:
505 Build.BuildContext.CONFIG_RESET = CONFIG_RESET
506 Build.BuildContext.CONFIG_SET = CONFIG_SET
507 Build.BuildContext.CONFIG_GET = CONFIG_GET
510 def library_flags(self, libs):
511 '''work out flags from pkg_config'''
515 for lib in TO_LIST(libs):
516 # note that we do not add the -I and -L in here, as that is added by the waf
517 # core. Adding it here would just change the order that it is put on the link line
518 # which can cause system paths to be added before internal libraries
519 extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
520 extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
521 extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), []))
522 ccflags.extend(extra_ccflags)
523 ldflags.extend(extra_ldflags)
524 cpppath.extend(extra_cpppath)
525 if 'EXTRA_LDFLAGS' in self.env:
526 ldflags.extend(self.env['EXTRA_LDFLAGS'])
528 ccflags = unique_list(ccflags)
529 ldflags = unique_list(ldflags)
530 cpppath = unique_list(cpppath)
531 return (ccflags, ldflags, cpppath)
535 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
536 '''check if a set of libraries exist as system libraries
538 returns the sublist of libs that do exist as a syslib or []
549 liblist = TO_LIST(libs)
550 for lib in liblist[:]:
551 if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
555 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
557 res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
559 res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
563 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
566 # if it isn't a mandatory library, then remove it from dependency lists
568 SET_TARGET_TYPE(conf, lib, 'EMPTY')
570 conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1)
571 conf.env['LIB_' + lib.upper()] = lib
573 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
581 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
582 headers=None, link=True, empty_decl=True, set_target=True):
584 check that the functions in 'list' are available in 'library'
585 if they are, then make that library available as a dependency
587 if the library is not available and mandatory==True, then
590 If the library is not available and mandatory==False, then
591 add the library to the list of dependencies to remove from
594 optionally check for the functions first in libc
596 remaining = TO_LIST(list)
597 liblist = TO_LIST(library)
599 # check if some already found
600 for f in remaining[:]:
601 if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
604 # see if the functions are in libc
606 for f in remaining[:]:
607 if CHECK_FUNC(conf, f, link=True, headers=headers):
612 if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
613 SET_TARGET_TYPE(conf, lib, 'EMPTY')
616 checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
617 for lib in liblist[:]:
618 if not lib in checklist and mandatory:
619 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
624 if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
631 def IN_LAUNCH_DIR(conf):
632 '''return True if this rule is being run from the launch directory'''
633 return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
634 Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
638 def SAMBA_CONFIG_H(conf, path=None):
639 '''write out config.h in the right directory'''
640 # we don't want to produce a config.h in places like lib/replace
641 # when we are building projects that depend on lib/replace
642 if not IN_LAUNCH_DIR(conf):
645 if Options.options.debug:
646 conf.ADD_CFLAGS('-g', testflags=True)
648 if Options.options.developer:
649 conf.env.DEVELOPER_MODE = True
651 conf.ADD_CFLAGS('-g', testflags=True)
652 conf.ADD_CFLAGS('-Wall', testflags=True)
653 conf.ADD_CFLAGS('-Wshadow', testflags=True)
654 conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True)
655 conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True)
656 conf.ADD_CFLAGS('-fno-common', testflags=True)
658 conf.ADD_CFLAGS('-Werror=address', testflags=True)
659 # we add these here to ensure that -Wstrict-prototypes is not set during configure
660 conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
662 conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
664 conf.ADD_CFLAGS('-Werror-implicit-function-declaration',
666 conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
668 conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
671 conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
672 # This check is because for ldb_search(), a NULL format string
673 # is not an error, but some compilers complain about that.
674 if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], '''
675 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
683 if not 'EXTRA_CFLAGS' in conf.env:
684 conf.env['EXTRA_CFLAGS'] = []
685 conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
687 if Options.options.picky_developer:
688 conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror', testflags=True)
690 if Options.options.fatal_errors:
691 conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
693 if Options.options.pedantic:
694 conf.ADD_CFLAGS('-W', testflags=True)
697 conf.write_config_header('config.h', top=True)
699 conf.write_config_header(path)
700 conf.SAMBA_CROSS_CHECK_COMPLETE()
704 def CONFIG_PATH(conf, name, default):
705 '''setup a configurable path'''
706 if not name in conf.env:
707 if default[0] == '/':
708 conf.env[name] = default
710 conf.env[name] = conf.env['PREFIX'] + default
713 def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False):
714 '''add some CFLAGS to the command line
715 optionally set testflags to ensure all the flags work
719 for f in flags.split():
720 if CHECK_CFLAGS(conf, f):
723 if not name in conf.env:
725 conf.env[name].extend(TO_LIST(flags))
728 def ADD_CFLAGS(conf, flags, testflags=False):
729 '''add some CFLAGS to the command line
730 optionally set testflags to ensure all the flags work
732 ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags)
735 def ADD_LDFLAGS(conf, flags, testflags=False):
736 '''add some LDFLAGS to the command line
737 optionally set testflags to ensure all the flags work
739 this will return the flags that are added, if any
743 for f in flags.split():
744 if CHECK_LDFLAGS(conf, f):
747 if not 'EXTRA_LDFLAGS' in conf.env:
748 conf.env['EXTRA_LDFLAGS'] = []
749 conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
754 def ADD_EXTRA_INCLUDES(conf, includes):
755 '''add some extra include directories to all builds'''
756 if not 'EXTRA_INCLUDES' in conf.env:
757 conf.env['EXTRA_INCLUDES'] = []
758 conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
762 def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=True, hide_symbols=False):
763 '''work out the current flags. local flags are added first'''
764 ret = TO_LIST(cflags)
765 if not 'EXTRA_CFLAGS' in bld.env:
768 list = bld.env['EXTRA_CFLAGS'];
770 if not allow_warnings and 'PICKY_CFLAGS' in bld.env:
771 list = bld.env['PICKY_CFLAGS'];
773 if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
774 ret.append('-fvisibility=hidden')
779 def CHECK_CC_ENV(conf):
780 """trim whitespaces from 'CC'.
781 The build farm sometimes puts a space at the start"""
782 if os.environ.get('CC'):
783 conf.env.CC = TO_LIST(os.environ.get('CC'))
784 if len(conf.env.CC) == 1:
785 # make for nicer logs if just a single command
786 conf.env.CC = conf.env.CC[0]
790 def SETUP_CONFIGURE_CACHE(conf, enable):
791 '''enable/disable cache of configure results'''
793 # when -C is chosen, we will use a private cache and will
794 # not look into system includes. This roughtly matches what
795 # autoconf does with -C
796 cache_path = os.path.join(conf.blddir, '.confcache')
798 Options.cache_global = os.environ['WAFCACHE'] = cache_path
800 # when -C is not chosen we will not cache configure checks
801 # We set the recursion limit low to prevent waf from spending
802 # a lot of time on the signatures of the files.
803 Options.cache_global = os.environ['WAFCACHE'] = ''
804 preproc.recursion_limit = 1
805 # in either case we don't need to scan system includes
806 preproc.go_absolute = False
810 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
811 # we don't want any libraries or modules to rely on runtime
812 # resolution of symbols
813 if not sys.platform.startswith("openbsd"):
814 conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
816 if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
817 if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
818 conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']