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) = library_flags(conf, lib)
97 hdrs = hlist_to_string(conf, headers=h)
98 ret = conf.check(fragment='%s\nint main(void) { return 0; }' % hdrs,
102 msg="Checking for header %s" % h)
104 missing_headers.add(h)
108 if add_headers and not h in conf.env.hlist:
109 conf.env.hlist.append(h)
114 def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None):
115 '''check for a list of headers
117 when together==True, then the headers accumulate within this test.
118 This is useful for interdependent headers
121 if not add_headers and together:
122 saved_hlist = conf.env.hlist[:]
123 set_add_headers = True
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):
129 if not add_headers and together:
130 conf.env.hlist = saved_hlist
134 def header_list(conf, headers=None, lib=None):
135 '''form a list of headers which exist, as a string'''
137 if headers is not None:
138 for h in TO_LIST(headers):
139 if CHECK_HEADER(conf, h, add_headers=False, lib=lib):
141 return hlist_to_string(conf, headers=hlist)
145 def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None):
146 '''check for a single type'''
148 define = 'HAVE_' + t.upper().replace(' ', '_')
150 msg='Checking for %s' % t
151 ret = CHECK_CODE(conf, '%s _x' % t,
159 if not ret and alternate:
160 conf.DEFINE(t, alternate)
165 def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None):
166 '''check for a list of types'''
168 for t in TO_LIST(list):
169 if not CHECK_TYPE(conf, t, headers=headers,
170 define=define, alternate=alternate, lib=lib):
176 def 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)
182 def CHECK_VARIABLE(conf, v, define=None, always=False,
183 headers=None, msg=None, lib=None):
184 '''check for a variable declaration (or define)'''
186 define = 'HAVE_%s' % v.upper()
189 msg="Checking for variable %s" % v
191 return CHECK_CODE(conf,
192 # we need to make sure the compiler doesn't
196 void *_x; _x=(void *)&%s; return (int)_x;
211 def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False):
212 '''check a list of variable declarations, using the HAVE_DECL_xxx form
215 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
218 for v in TO_LIST(vars):
220 define='HAVE_DECL_%s' % v.upper()
222 define='HAVE_%s_DECL' % v.upper()
223 if not CHECK_VARIABLE(conf, v,
226 msg='Checking for declaration of %s' % v,
232 def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
233 '''check for a function'''
234 define='HAVE_%s' % f.upper()
238 conf.COMPOUND_START('Checking for %s' % f)
240 if link is None or link == True:
241 ret = CHECK_CODE(conf,
242 # this is based on the autoconf strategy
244 #define %s __fake__%s
251 #if defined __stub_%s || defined __stub___%s
252 #error "bad glibc stub"
255 int main() { return %s(); }
256 ''' % (f, f, f, f, f, f, f),
265 msg='Checking for %s' % f)
268 ret = CHECK_CODE(conf,
269 # it might be a macro
270 # we need to make sure the compiler doesn't
272 'void *__x = (void *)%s; return (int)__x' % f,
281 msg='Checking for macro %s' % f)
283 if not ret and (link is None or link == False):
284 ret = CHECK_VARIABLE(conf, f,
287 msg='Checking for declaration of %s' % f)
288 conf.COMPOUND_END(ret)
293 def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None):
294 '''check for a list of functions'''
296 for f in TO_LIST(list):
297 if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers):
303 def CHECK_SIZEOF(conf, vars, headers=None, define=None):
304 '''check the size of a type'''
306 for v in TO_LIST(vars):
309 v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
310 if not CHECK_CODE(conf,
311 'printf("%%u", (unsigned)sizeof(%s))' % v,
318 msg="Checking size of %s" % v):
325 def 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,
332 '''check if some code compiles and/or runs'''
334 if CONFIG_SET(conf, define):
337 if headers is not None:
338 CHECK_HEADERS(conf, headers=headers, lib=lib)
341 hdrs = header_list(conf, headers=headers, lib=lib)
349 defs = conf.get_config_header()
352 fragment='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs, hdrs, code)
354 fragment='%s\n%s\n%s\n' % (defs, hdrs, code)
357 msg="Checking for %s" % define
359 cflags = TO_LIST(cflags)
362 cflags.append('-I%s' % conf.curdir)
369 uselib = TO_LIST(lib)
371 (ccflags, ldflags) = library_flags(conf, uselib)
373 cflags.extend(ccflags)
376 exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
380 conf.COMPOUND_START(msg)
382 ret = conf.check(fragment=fragment,
384 define_name = define,
385 mandatory = mandatory,
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?
401 conf.DEFINE(define, 1)
402 conf.COMPOUND_END(True)
404 conf.COMPOUND_END(conf.env[define])
407 conf.DEFINE(define, 0)
408 conf.COMPOUND_END(False)
414 def CHECK_STRUCTURE_MEMBER(conf, structname, member,
415 always=False, define=None, headers=None):
416 '''check for a structure member'''
418 define = 'HAVE_%s' % member.upper()
419 return CHECK_CODE(conf,
420 '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
427 msg="Checking for member %s in %s" % (member, structname))
431 def CHECK_CFLAGS(conf, cflags):
432 '''check if the given cflags are accepted by the compiler
434 return conf.check(fragment='int main(void) { return 0; }\n',
438 msg="Checking compiler accepts %s" % cflags)
441 def CHECK_LDFLAGS(conf, ldflags):
442 '''check if the given ldflags are accepted by the linker
444 return conf.check(fragment='int main(void) { return 0; }\n',
447 msg="Checking linker accepts %s" % ldflags)
451 def CONFIG_GET(conf, option):
452 '''return True if a configuration option was found'''
453 if (option in conf.env):
454 return conf.env[option]
459 def CONFIG_SET(conf, option):
460 '''return True if a configuration option was found'''
461 return (option in conf.env) and (conf.env[option] != ())
462 Build.BuildContext.CONFIG_SET = CONFIG_SET
463 Build.BuildContext.CONFIG_GET = CONFIG_GET
466 def library_flags(self, libs):
467 '''work out flags from pkg_config'''
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 # note that we do not add the -L in here, as that is added by the waf
475 # core. Adding it here would just change the order that it is put on the link line
476 # which can cause system paths to be added before internal libraries
477 extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
478 extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
479 ccflags.extend(extra_ccflags)
480 ldflags.extend(extra_ldflags)
481 if 'EXTRA_LDFLAGS' in self.env:
482 ldflags.extend(self.env['EXTRA_LDFLAGS'])
484 ccflags = unique_list(ccflags)
485 ldflags = unique_list(ldflags)
486 return (ccflags, ldflags)
490 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
491 '''check if a set of libraries exist as system libraries
493 returns the sublist of libs that do exist as a syslib or []
504 liblist = TO_LIST(libs)
505 for lib in liblist[:]:
506 if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
510 (ccflags, ldflags) = library_flags(conf, lib)
512 res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags)
514 res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags)
518 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
521 # if it isn't a mandatory library, then remove it from dependency lists
523 SET_TARGET_TYPE(conf, lib, 'EMPTY')
525 conf.define('HAVE_LIB%s' % lib.upper().replace('-','_'), 1)
526 conf.env['LIB_' + lib.upper()] = lib
528 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
536 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
537 headers=None, link=True, empty_decl=True, set_target=True):
539 check that the functions in 'list' are available in 'library'
540 if they are, then make that library available as a dependency
542 if the library is not available and mandatory==True, then
545 If the library is not available and mandatory==False, then
546 add the library to the list of dependencies to remove from
549 optionally check for the functions first in libc
551 remaining = TO_LIST(list)
552 liblist = TO_LIST(library)
554 # check if some already found
555 for f in remaining[:]:
556 if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
559 # see if the functions are in libc
561 for f in remaining[:]:
562 if CHECK_FUNC(conf, f, link=True, headers=headers):
567 if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
568 SET_TARGET_TYPE(conf, lib, 'EMPTY')
571 checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
572 for lib in liblist[:]:
573 if not lib in checklist and mandatory:
574 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
579 if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
586 def IN_LAUNCH_DIR(conf):
587 '''return True if this rule is being run from the launch directory'''
588 return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
589 Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
593 def SAMBA_CONFIG_H(conf, path=None):
594 '''write out config.h in the right directory'''
595 # we don't want to produce a config.h in places like lib/replace
596 # when we are building projects that depend on lib/replace
597 if not IN_LAUNCH_DIR(conf):
600 if Options.options.developer:
601 # we add these here to ensure that -Wstrict-prototypes is not set during configure
602 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 -fno-common',
604 conf.ADD_CFLAGS('-Wcast-qual', testflags=True)
605 conf.env.DEVELOPER_MODE = True
607 if Options.options.picky_developer:
608 conf.ADD_CFLAGS('-Werror', testflags=True)
610 if Options.options.fatal_errors:
611 conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
613 if Options.options.pedantic:
614 conf.ADD_CFLAGS('-W', testflags=True)
617 conf.write_config_header('config.h', top=True)
619 conf.write_config_header(path)
620 conf.SAMBA_CROSS_CHECK_COMPLETE()
624 def CONFIG_PATH(conf, name, default):
625 '''setup a configurable path'''
626 if not name in conf.env:
627 if default[0] == '/':
628 conf.env[name] = default
630 conf.env[name] = conf.env['PREFIX'] + default
633 def ADD_CFLAGS(conf, flags, testflags=False):
634 '''add some CFLAGS to the command line
635 optionally set testflags to ensure all the flags work
639 for f in flags.split():
640 if CHECK_CFLAGS(conf, f):
643 if not 'EXTRA_CFLAGS' in conf.env:
644 conf.env['EXTRA_CFLAGS'] = []
645 conf.env['EXTRA_CFLAGS'].extend(TO_LIST(flags))
648 def ADD_LDFLAGS(conf, flags, testflags=False):
649 '''add some LDFLAGS to the command line
650 optionally set testflags to ensure all the flags work
652 this will return the flags that are added, if any
656 for f in flags.split():
657 if CHECK_LDFLAGS(conf, f):
660 if not 'EXTRA_LDFLAGS' in conf.env:
661 conf.env['EXTRA_LDFLAGS'] = []
662 conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
667 def ADD_EXTRA_INCLUDES(conf, includes):
668 '''add some extra include directories to all builds'''
669 if not 'EXTRA_INCLUDES' in conf.env:
670 conf.env['EXTRA_INCLUDES'] = []
671 conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
675 def CURRENT_CFLAGS(bld, target, cflags, hide_symbols=False):
676 '''work out the current flags. local flags are added first'''
677 if not 'EXTRA_CFLAGS' in bld.env:
680 list = bld.env['EXTRA_CFLAGS'];
681 ret = TO_LIST(cflags)
683 if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
684 ret.append('-fvisibility=hidden')
689 def CHECK_CC_ENV(conf):
690 """trim whitespaces from 'CC'.
691 The build farm sometimes puts a space at the start"""
692 if os.environ.get('CC'):
693 conf.env.CC = TO_LIST(os.environ.get('CC'))
694 if len(conf.env.CC) == 1:
695 # make for nicer logs if just a single command
696 conf.env.CC = conf.env.CC[0]
700 def SETUP_CONFIGURE_CACHE(conf, enable):
701 '''enable/disable cache of configure results'''
703 # when -C is chosen, we will use a private cache and will
704 # not look into system includes. This roughtly matches what
705 # autoconf does with -C
706 cache_path = os.path.join(conf.blddir, '.confcache')
708 Options.cache_global = os.environ['WAFCACHE'] = cache_path
710 # when -C is not chosen we will not cache configure checks
711 # We set the recursion limit low to prevent waf from spending
712 # a lot of time on the signatures of the files.
713 Options.cache_global = os.environ['WAFCACHE'] = ''
714 preproc.recursion_limit = 1
715 # in either case we don't need to scan system includes
716 preproc.go_absolute = False
720 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
721 # we don't want any libraries or modules to rely on runtime
722 # resolution of symbols
723 if sys.platform != "openbsd4":
724 conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
726 if sys.platform != "openbsd4" and conf.env.undefined_ignore_ldflags == []:
727 if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
728 conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']