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, critical
=True):
308 '''check the size of a type'''
309 for v
in TO_LIST(vars):
313 v_define
= 'SIZEOF_%s' % v
.upper().replace(' ', '_')
314 for size
in list((1, 2, 4, 8, 16, 32)):
316 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v
, size
),
321 msg
="Checking if size of %s == %d" % (v
, size
)):
322 conf
.DEFINE(v_define
, size
)
325 if not ret
and critical
:
326 Logs
.error("Couldn't determine size of '%s'" % v
)
331 def CHECK_VALUEOF(conf
, v
, headers
=None, define
=None):
332 '''check the value of a variable/define'''
336 v_define
= 'VALUEOF_%s' % v
.upper().replace(' ', '_')
338 'printf("%%u", (unsigned)(%s))' % v
,
345 msg
="Checking value of %s" % v
):
346 return int(conf
.env
[v_define
])
351 def CHECK_CODE(conf
, code
, define
,
352 always
=False, execute
=False, addmain
=True,
353 add_headers
=True, mandatory
=False,
354 headers
=None, msg
=None, cflags
='', includes
='# .',
355 local_include
=True, lib
=None, link
=True,
356 define_ret
=False, quote
=False,
358 '''check if some code compiles and/or runs'''
360 if CONFIG_SET(conf
, define
):
363 if headers
is not None:
364 CHECK_HEADERS(conf
, headers
=headers
, lib
=lib
)
367 hdrs
= header_list(conf
, headers
=headers
, lib
=lib
)
375 defs
= conf
.get_config_header()
378 fragment
='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs
, hdrs
, code
)
380 fragment
='%s\n%s\n%s\n' % (defs
, hdrs
, code
)
383 msg
="Checking for %s" % define
385 cflags
= TO_LIST(cflags
)
388 cflags
.append('-I%s' % conf
.curdir
)
395 uselib
= TO_LIST(lib
)
397 (ccflags
, ldflags
, cpppath
) = library_flags(conf
, uselib
)
399 includes
= TO_LIST(includes
)
400 includes
.extend(cpppath
)
402 uselib
= [l
.upper() for l
in uselib
]
404 cflags
.extend(ccflags
)
407 exec_args
= conf
.SAMBA_CROSS_ARGS(msg
=msg
)
411 conf
.COMPOUND_START(msg
)
413 ret
= conf
.check(fragment
=fragment
,
415 define_name
= define
,
416 mandatory
= mandatory
,
425 define_ret
=define_ret
)
426 if not ret
and CONFIG_SET(conf
, define
):
427 # sometimes conf.check() returns false, but it
428 # sets the define. Maybe a waf bug?
432 conf
.DEFINE(define
, 1)
433 conf
.COMPOUND_END(True)
435 conf
.COMPOUND_END(conf
.env
[define
])
438 conf
.DEFINE(define
, 0)
439 conf
.COMPOUND_END(False)
445 def CHECK_STRUCTURE_MEMBER(conf
, structname
, member
,
446 always
=False, define
=None, headers
=None):
447 '''check for a structure member'''
449 define
= 'HAVE_%s' % member
.upper()
450 return CHECK_CODE(conf
,
451 '%s s; void *_x; _x=(void *)&s.%s' % (structname
, member
),
458 msg
="Checking for member %s in %s" % (member
, structname
))
462 def CHECK_CFLAGS(conf
, cflags
, fragment
='int main(void) { return 0; }\n'):
463 '''check if the given cflags are accepted by the compiler
465 return conf
.check(fragment
=fragment
,
469 msg
="Checking compiler accepts %s" % cflags
)
472 def CHECK_LDFLAGS(conf
, ldflags
):
473 '''check if the given ldflags are accepted by the linker
475 return conf
.check(fragment
='int main(void) { return 0; }\n',
478 msg
="Checking linker accepts %s" % ldflags
)
482 def CONFIG_GET(conf
, option
):
483 '''return True if a configuration option was found'''
484 if (option
in conf
.env
):
485 return conf
.env
[option
]
490 def CONFIG_SET(conf
, option
):
491 '''return True if a configuration option was found'''
492 if option
not in conf
.env
:
504 def CONFIG_RESET(conf
, option
):
505 if option
not in conf
.env
:
509 Build
.BuildContext
.CONFIG_RESET
= CONFIG_RESET
510 Build
.BuildContext
.CONFIG_SET
= CONFIG_SET
511 Build
.BuildContext
.CONFIG_GET
= CONFIG_GET
514 def library_flags(self
, libs
):
515 '''work out flags from pkg_config'''
519 for lib
in TO_LIST(libs
):
520 # note that we do not add the -I and -L in here, as that is added by the waf
521 # core. Adding it here would just change the order that it is put on the link line
522 # which can cause system paths to be added before internal libraries
523 extra_ccflags
= TO_LIST(getattr(self
.env
, 'CCFLAGS_%s' % lib
.upper(), []))
524 extra_ldflags
= TO_LIST(getattr(self
.env
, 'LDFLAGS_%s' % lib
.upper(), []))
525 extra_cpppath
= TO_LIST(getattr(self
.env
, 'CPPPATH_%s' % lib
.upper(), []))
526 ccflags
.extend(extra_ccflags
)
527 ldflags
.extend(extra_ldflags
)
528 cpppath
.extend(extra_cpppath
)
529 if 'EXTRA_LDFLAGS' in self
.env
:
530 ldflags
.extend(self
.env
['EXTRA_LDFLAGS'])
532 ccflags
= unique_list(ccflags
)
533 ldflags
= unique_list(ldflags
)
534 cpppath
= unique_list(cpppath
)
535 return (ccflags
, ldflags
, cpppath
)
539 def CHECK_LIB(conf
, libs
, mandatory
=False, empty_decl
=True, set_target
=True, shlib
=False):
540 '''check if a set of libraries exist as system libraries
542 returns the sublist of libs that do exist as a syslib or []
553 liblist
= TO_LIST(libs
)
554 for lib
in liblist
[:]:
555 if GET_TARGET_TYPE(conf
, lib
) == 'SYSLIB':
559 (ccflags
, ldflags
, cpppath
) = library_flags(conf
, lib
)
561 res
= conf
.check(features
='cc cshlib', fragment
=fragment
, lib
=lib
, uselib_store
=lib
, ccflags
=ccflags
, ldflags
=ldflags
, uselib
=lib
.upper())
563 res
= conf
.check(lib
=lib
, uselib_store
=lib
, ccflags
=ccflags
, ldflags
=ldflags
, uselib
=lib
.upper())
567 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
570 # if it isn't a mandatory library, then remove it from dependency lists
572 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
574 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_').replace('.','_'), 1)
575 conf
.env
['LIB_' + lib
.upper()] = lib
577 conf
.SET_TARGET_TYPE(lib
, 'SYSLIB')
585 def CHECK_FUNCS_IN(conf
, list, library
, mandatory
=False, checklibc
=False,
586 headers
=None, link
=True, empty_decl
=True, set_target
=True):
588 check that the functions in 'list' are available in 'library'
589 if they are, then make that library available as a dependency
591 if the library is not available and mandatory==True, then
594 If the library is not available and mandatory==False, then
595 add the library to the list of dependencies to remove from
598 optionally check for the functions first in libc
600 remaining
= TO_LIST(list)
601 liblist
= TO_LIST(library
)
603 # check if some already found
604 for f
in remaining
[:]:
605 if CONFIG_SET(conf
, 'HAVE_%s' % f
.upper()):
608 # see if the functions are in libc
610 for f
in remaining
[:]:
611 if CHECK_FUNC(conf
, f
, link
=True, headers
=headers
):
616 if GET_TARGET_TYPE(conf
, lib
) != 'SYSLIB' and empty_decl
:
617 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
620 checklist
= conf
.CHECK_LIB(liblist
, empty_decl
=empty_decl
, set_target
=set_target
)
621 for lib
in liblist
[:]:
622 if not lib
in checklist
and mandatory
:
623 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
628 if not CHECK_FUNC(conf
, f
, lib
=' '.join(checklist
), headers
=headers
, link
=link
):
635 def IN_LAUNCH_DIR(conf
):
636 '''return True if this rule is being run from the launch directory'''
637 return os
.path
.realpath(conf
.curdir
) == os
.path
.realpath(Options
.launch_dir
)
638 Options
.Handler
.IN_LAUNCH_DIR
= IN_LAUNCH_DIR
642 def SAMBA_CONFIG_H(conf
, path
=None):
643 '''write out config.h in the right directory'''
644 # we don't want to produce a config.h in places like lib/replace
645 # when we are building projects that depend on lib/replace
646 if not IN_LAUNCH_DIR(conf
):
649 if Options
.options
.debug
:
650 conf
.ADD_CFLAGS('-g', testflags
=True)
652 if Options
.options
.developer
:
653 conf
.env
.DEVELOPER_MODE
= True
655 conf
.ADD_CFLAGS('-g', testflags
=True)
656 conf
.ADD_CFLAGS('-Wall', testflags
=True)
657 conf
.ADD_CFLAGS('-Wshadow', testflags
=True)
658 conf
.ADD_CFLAGS('-Wmissing-prototypes', testflags
=True)
659 conf
.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags
=True)
660 conf
.ADD_CFLAGS('-fno-common', testflags
=True)
662 conf
.ADD_CFLAGS('-Werror=address', testflags
=True)
663 # we add these here to ensure that -Wstrict-prototypes is not set during configure
664 conf
.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
666 conf
.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
668 conf
.ADD_CFLAGS('-Werror-implicit-function-declaration',
670 conf
.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
672 conf
.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
675 conf
.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags
=True)
676 # This check is because for ldb_search(), a NULL format string
677 # is not an error, but some compilers complain about that.
678 if CHECK_CFLAGS(conf
, ["-Werror=format", "-Wformat=2"], '''
679 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
687 if not 'EXTRA_CFLAGS' in conf
.env
:
688 conf
.env
['EXTRA_CFLAGS'] = []
689 conf
.env
['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
691 if Options
.options
.picky_developer
:
692 conf
.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror', testflags
=True)
694 if Options
.options
.fatal_errors
:
695 conf
.ADD_CFLAGS('-Wfatal-errors', testflags
=True)
697 if Options
.options
.pedantic
:
698 conf
.ADD_CFLAGS('-W', testflags
=True)
701 conf
.write_config_header('config.h', top
=True)
703 conf
.write_config_header(path
)
704 conf
.SAMBA_CROSS_CHECK_COMPLETE()
708 def CONFIG_PATH(conf
, name
, default
):
709 '''setup a configurable path'''
710 if not name
in conf
.env
:
711 if default
[0] == '/':
712 conf
.env
[name
] = default
714 conf
.env
[name
] = conf
.env
['PREFIX'] + default
717 def ADD_NAMED_CFLAGS(conf
, name
, flags
, testflags
=False):
718 '''add some CFLAGS to the command line
719 optionally set testflags to ensure all the flags work
723 for f
in flags
.split():
724 if CHECK_CFLAGS(conf
, f
):
727 if not name
in conf
.env
:
729 conf
.env
[name
].extend(TO_LIST(flags
))
732 def ADD_CFLAGS(conf
, flags
, testflags
=False):
733 '''add some CFLAGS to the command line
734 optionally set testflags to ensure all the flags work
736 ADD_NAMED_CFLAGS(conf
, 'EXTRA_CFLAGS', flags
, testflags
=testflags
)
739 def ADD_LDFLAGS(conf
, flags
, testflags
=False):
740 '''add some LDFLAGS to the command line
741 optionally set testflags to ensure all the flags work
743 this will return the flags that are added, if any
747 for f
in flags
.split():
748 if CHECK_LDFLAGS(conf
, f
):
751 if not 'EXTRA_LDFLAGS' in conf
.env
:
752 conf
.env
['EXTRA_LDFLAGS'] = []
753 conf
.env
['EXTRA_LDFLAGS'].extend(TO_LIST(flags
))
758 def ADD_EXTRA_INCLUDES(conf
, includes
):
759 '''add some extra include directories to all builds'''
760 if not 'EXTRA_INCLUDES' in conf
.env
:
761 conf
.env
['EXTRA_INCLUDES'] = []
762 conf
.env
['EXTRA_INCLUDES'].extend(TO_LIST(includes
))
766 def CURRENT_CFLAGS(bld
, target
, cflags
, allow_warnings
=True, hide_symbols
=False):
767 '''work out the current flags. local flags are added first'''
768 ret
= TO_LIST(cflags
)
769 if not 'EXTRA_CFLAGS' in bld
.env
:
772 list = bld
.env
['EXTRA_CFLAGS'];
774 if not allow_warnings
and 'PICKY_CFLAGS' in bld
.env
:
775 list = bld
.env
['PICKY_CFLAGS'];
777 if hide_symbols
and bld
.env
.HAVE_VISIBILITY_ATTR
:
778 ret
.append('-fvisibility=hidden')
783 def CHECK_CC_ENV(conf
):
784 """trim whitespaces from 'CC'.
785 The build farm sometimes puts a space at the start"""
786 if os
.environ
.get('CC'):
787 conf
.env
.CC
= TO_LIST(os
.environ
.get('CC'))
788 if len(conf
.env
.CC
) == 1:
789 # make for nicer logs if just a single command
790 conf
.env
.CC
= conf
.env
.CC
[0]
794 def SETUP_CONFIGURE_CACHE(conf
, enable
):
795 '''enable/disable cache of configure results'''
797 # when -C is chosen, we will use a private cache and will
798 # not look into system includes. This roughtly matches what
799 # autoconf does with -C
800 cache_path
= os
.path
.join(conf
.blddir
, '.confcache')
802 Options
.cache_global
= os
.environ
['WAFCACHE'] = cache_path
804 # when -C is not chosen we will not cache configure checks
805 # We set the recursion limit low to prevent waf from spending
806 # a lot of time on the signatures of the files.
807 Options
.cache_global
= os
.environ
['WAFCACHE'] = ''
808 preproc
.recursion_limit
= 1
809 # in either case we don't need to scan system includes
810 preproc
.go_absolute
= False
814 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf
):
815 # we don't want any libraries or modules to rely on runtime
816 # resolution of symbols
817 if not sys
.platform
.startswith("openbsd"):
818 conf
.env
.undefined_ldflags
= conf
.ADD_LDFLAGS('-Wl,-no-undefined', testflags
=True)
820 if not sys
.platform
.startswith("openbsd") and conf
.env
.undefined_ignore_ldflags
== []:
821 if conf
.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
822 conf
.env
.undefined_ignore_ldflags
= ['-undefined', 'dynamic_lookup']