1 # a waf tool to add autoconf-like macros to the configure section
3 import Build
, os
, 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
:
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
360 cflags
+= ' -I%s' % conf
.curdir
367 uselib
= TO_LIST(lib
)
369 (ccflags
, ldflags
) = library_flags(conf
, uselib
)
371 cflags
= TO_LIST(cflags
)
372 cflags
.extend(ccflags
)
375 exec_args
= conf
.SAMBA_CROSS_ARGS(msg
=msg
)
379 conf
.COMPOUND_START(msg
)
381 ret
= conf
.check(fragment
=fragment
,
383 define_name
= define
,
384 mandatory
= mandatory
,
393 define_ret
=define_ret
)
394 if not ret
and CONFIG_SET(conf
, define
):
395 # sometimes conf.check() returns false, but it
396 # sets the define. Maybe a waf bug?
400 conf
.DEFINE(define
, 1)
401 conf
.COMPOUND_END(True)
403 conf
.COMPOUND_END(conf
.env
[define
])
406 conf
.DEFINE(define
, 0)
407 conf
.COMPOUND_END(False)
413 def CHECK_STRUCTURE_MEMBER(conf
, structname
, member
,
414 always
=False, define
=None, headers
=None):
415 '''check for a structure member'''
417 define
= 'HAVE_%s' % member
.upper()
418 return CHECK_CODE(conf
,
419 '%s s; void *_x; _x=(void *)&s.%s' % (structname
, member
),
426 msg
="Checking for member %s in %s" % (member
, structname
))
430 def CHECK_CFLAGS(conf
, cflags
):
431 '''check if the given cflags are accepted by the compiler
433 return conf
.check(fragment
='int main(void) { return 0; }\n',
437 msg
="Checking compiler accepts %s" % cflags
)
441 def CONFIG_SET(conf
, option
):
442 '''return True if a configuration option was found'''
443 return (option
in conf
.env
) and (conf
.env
[option
] != ())
444 Build
.BuildContext
.CONFIG_SET
= CONFIG_SET
447 def library_flags(conf
, libs
):
448 '''work out flags from pkg_config'''
451 for lib
in TO_LIST(libs
):
452 inc_path
= getattr(conf
.env
, 'CPPPATH_%s' % lib
.upper(), [])
453 lib_path
= getattr(conf
.env
, 'LIBPATH_%s' % lib
.upper(), [])
454 ccflags
.extend(['-I%s' % i
for i
in inc_path
])
455 ldflags
.extend(['-L%s' % l
for l
in lib_path
])
456 extra_ccflags
= TO_LIST(getattr(conf
.env
, 'CCFLAGS_%s' % lib
.upper(), []))
457 extra_ldflags
= TO_LIST(getattr(conf
.env
, 'LDFLAGS_%s' % lib
.upper(), []))
458 ccflags
.extend(extra_ccflags
)
459 ldflags
.extend(extra_ldflags
)
460 return (ccflags
, ldflags
)
464 def CHECK_LIB(conf
, libs
, mandatory
=False, empty_decl
=True, set_target
=True):
465 '''check if a set of libraries exist as system libraries
467 returns the sublist of libs that do exist as a syslib or []
471 liblist
= TO_LIST(libs
)
472 for lib
in liblist
[:]:
473 if GET_TARGET_TYPE(conf
, lib
) == 'SYSLIB':
477 (ccflags
, ldflags
) = library_flags(conf
, lib
)
479 if not conf
.check(lib
=lib
, uselib_store
=lib
, ccflags
=ccflags
, ldflags
=ldflags
):
481 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
484 # if it isn't a mandatory library, then remove it from dependency lists
486 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
488 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_'), 1)
489 conf
.env
['LIB_' + lib
.upper()] = lib
491 conf
.SET_TARGET_TYPE(lib
, 'SYSLIB')
499 def CHECK_FUNCS_IN(conf
, list, library
, mandatory
=False, checklibc
=False,
500 headers
=None, link
=True, empty_decl
=True, set_target
=True):
502 check that the functions in 'list' are available in 'library'
503 if they are, then make that library available as a dependency
505 if the library is not available and mandatory==True, then
508 If the library is not available and mandatory==False, then
509 add the library to the list of dependencies to remove from
512 optionally check for the functions first in libc
514 remaining
= TO_LIST(list)
515 liblist
= TO_LIST(library
)
517 # check if some already found
518 for f
in remaining
[:]:
519 if CONFIG_SET(conf
, 'HAVE_%s' % f
.upper()):
522 # see if the functions are in libc
524 for f
in remaining
[:]:
525 if CHECK_FUNC(conf
, f
, link
=True, headers
=headers
):
530 if GET_TARGET_TYPE(conf
, lib
) != 'SYSLIB' and empty_decl
:
531 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
534 checklist
= conf
.CHECK_LIB(liblist
, empty_decl
=empty_decl
, set_target
=set_target
)
535 for lib
in liblist
[:]:
536 if not lib
in checklist
and mandatory
:
537 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
542 if not CHECK_FUNC(conf
, f
, lib
=' '.join(checklist
), headers
=headers
, link
=link
):
549 def IN_LAUNCH_DIR(conf
):
550 '''return True if this rule is being run from the launch directory'''
551 return os
.path
.realpath(conf
.curdir
) == os
.path
.realpath(Options
.launch_dir
)
552 Options
.Handler
.IN_LAUNCH_DIR
= IN_LAUNCH_DIR
556 def SAMBA_CONFIG_H(conf
, path
=None):
557 '''write out config.h in the right directory'''
558 # we don't want to produce a config.h in places like lib/replace
559 # when we are building projects that depend on lib/replace
560 if not IN_LAUNCH_DIR(conf
):
563 if Options
.options
.developer
:
564 # we add these here to ensure that -Wstrict-prototypes is not set during configure
565 conf
.ADD_CFLAGS('-Wall -g -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Werror-implicit-function-declaration -Wformat=2 -Wno-format-y2k -Wl,-no-undefined',
568 if Options
.options
.picky_developer
:
569 conf
.ADD_CFLAGS('-Werror', testflags
=True)
571 if Options
.options
.fatal_errors
:
572 conf
.ADD_CFLAGS('-Wfatal-errors', testflags
=True)
574 if Options
.options
.pedantic
:
575 conf
.ADD_CFLAGS('-W', testflags
=True)
578 conf
.write_config_header('config.h', top
=True)
580 conf
.write_config_header(path
)
581 conf
.SAMBA_CROSS_CHECK_COMPLETE()
585 def CONFIG_PATH(conf
, name
, default
):
586 '''setup a configurable path'''
587 if not name
in conf
.env
:
588 if default
[0] == '/':
589 conf
.env
[name
] = default
591 conf
.env
[name
] = conf
.env
['PREFIX'] + default
594 def ADD_CFLAGS(conf
, flags
, testflags
=False):
595 '''add some CFLAGS to the command line
596 optionally set testflags to ensure all the flags work
600 for f
in flags
.split():
601 if CHECK_CFLAGS(conf
, f
):
604 if not 'EXTRA_CFLAGS' in conf
.env
:
605 conf
.env
['EXTRA_CFLAGS'] = []
606 conf
.env
['EXTRA_CFLAGS'].extend(TO_LIST(flags
))
611 def ADD_EXTRA_INCLUDES(conf
, includes
):
612 '''add some extra include directories to all builds'''
613 if not 'EXTRA_INCLUDES' in conf
.env
:
614 conf
.env
['EXTRA_INCLUDES'] = []
615 conf
.env
['EXTRA_INCLUDES'].extend(TO_LIST(includes
))
619 def CURRENT_CFLAGS(bld
, target
, cflags
, hide_symbols
=False):
620 '''work out the current flags. local flags are added first'''
621 if not 'EXTRA_CFLAGS' in bld
.env
:
624 list = bld
.env
['EXTRA_CFLAGS'];
625 ret
= TO_LIST(cflags
)
627 if hide_symbols
and bld
.env
.HAVE_VISIBILITY_ATTR
:
628 ret
.append('-fvisibility=hidden')
633 def CHECK_CC_ENV(conf
):
634 """trim whitespaces from 'CC'.
635 The build farm sometimes puts a space at the start"""
636 if os
.environ
.get('CC'):
637 conf
.env
.CC
= TO_LIST(os
.environ
.get('CC'))
638 if len(conf
.env
.CC
) == 1:
639 # make for nicer logs if just a single command
640 conf
.env
.CC
= conf
.env
.CC
[0]
644 def SETUP_CONFIGURE_CACHE(conf
, enable
):
645 '''enable/disable cache of configure results'''
647 # when -C is chosen, we will use a private cache and will
648 # not look into system includes. This roughtly matches what
649 # autoconf does with -C
650 cache_path
= os
.path
.join(conf
.blddir
, '.confcache')
652 Options
.cache_global
= os
.environ
['WAFCACHE'] = cache_path
654 # when -C is not chosen we will not cache configure checks
655 # We set the recursion limit low to prevent waf from spending
656 # a lot of time on the signatures of the files.
657 Options
.cache_global
= os
.environ
['WAFCACHE'] = ''
658 preproc
.recursion_limit
= 1
659 # in either case we don't need to scan system includes
660 preproc
.go_absolute
= False