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 *
8 missing_headers
= set()
10 ####################################################
11 # some autoconf like helpers, to make the transition
12 # to waf a bit easier for those used to autoconf
17 def DEFINE(conf
, d
, v
, add_to_cflags
=False, quote
=False):
18 '''define a config option'''
19 conf
.define(d
, v
, quote
=quote
)
21 conf
.env
.append_value('CCDEFINES', d
+ '=' + str(v
))
23 def hlist_to_string(conf
, headers
=None):
24 '''convert a headers list to a set of #include lines'''
26 hlist
= conf
.env
.hlist
29 hlist
.extend(TO_LIST(headers
))
31 hdrs
+= '#include <%s>\n' % h
36 def COMPOUND_START(conf
, msg
):
37 '''start a compound test'''
38 def null_check_message_1(self
,*k
,**kw
):
40 def null_check_message_2(self
,*k
,**kw
):
43 v
= getattr(conf
.env
, 'in_compound', [])
44 if v
!= [] and v
!= 0:
45 conf
.env
.in_compound
= v
+ 1
47 conf
.check_message_1(msg
)
48 conf
.saved_check_message_1
= conf
.check_message_1
49 conf
.check_message_1
= null_check_message_1
50 conf
.saved_check_message_2
= conf
.check_message_2
51 conf
.check_message_2
= null_check_message_2
52 conf
.env
.in_compound
= 1
56 def COMPOUND_END(conf
, result
):
57 '''start a compound test'''
58 conf
.env
.in_compound
-= 1
59 if conf
.env
.in_compound
!= 0:
61 conf
.check_message_1
= conf
.saved_check_message_1
62 conf
.check_message_2
= conf
.saved_check_message_2
63 p
= conf
.check_message_2
67 p('not found', 'YELLOW')
74 '''using the nolink type in conf.check() allows us to avoid
75 the link stage of a test, thus speeding it up for tests
76 that where linking is not needed'''
80 def CHECK_HEADER(conf
, h
, add_headers
=False, lib
=None):
81 '''check for a header'''
82 if h
in missing_headers
:
84 d
= h
.upper().replace('/', '_')
85 d
= d
.replace('.', '_')
87 if CONFIG_SET(conf
, d
):
89 if not h
in conf
.env
.hlist
:
90 conf
.env
.hlist
.append(h
)
93 (ccflags
, ldflags
) = library_flags(conf
, lib
)
95 hdrs
= hlist_to_string(conf
, headers
=h
)
96 ret
= conf
.check(fragment
='%s\nint main(void) { return 0; }' % hdrs
,
100 msg
="Checking for header %s" % h
)
102 missing_headers
.add(h
)
106 if add_headers
and not h
in conf
.env
.hlist
:
107 conf
.env
.hlist
.append(h
)
112 def CHECK_HEADERS(conf
, headers
, add_headers
=False, together
=False, lib
=None):
113 '''check for a list of headers
115 when together==True, then the headers accumulate within this test.
116 This is useful for interdependent headers
119 if not add_headers
and together
:
120 saved_hlist
= conf
.env
.hlist
[:]
121 set_add_headers
= True
123 set_add_headers
= add_headers
124 for hdr
in TO_LIST(headers
):
125 if not CHECK_HEADER(conf
, hdr
, set_add_headers
, lib
=lib
):
127 if not add_headers
and together
:
128 conf
.env
.hlist
= saved_hlist
132 def header_list(conf
, headers
=None, lib
=None):
133 '''form a list of headers which exist, as a string'''
135 if headers
is not None:
136 for h
in TO_LIST(headers
):
137 if CHECK_HEADER(conf
, h
, add_headers
=False, lib
=lib
):
139 return hlist_to_string(conf
, headers
=hlist
)
143 def CHECK_TYPE(conf
, t
, alternate
=None, headers
=None, define
=None, lib
=None, msg
=None):
144 '''check for a single type'''
146 define
= 'HAVE_' + t
.upper().replace(' ', '_')
148 msg
='Checking for %s' % t
149 ret
= CHECK_CODE(conf
, '%s _x' % t
,
157 if not ret
and alternate
:
158 conf
.DEFINE(t
, alternate
)
163 def CHECK_TYPES(conf
, list, headers
=None, define
=None, alternate
=None, lib
=None):
164 '''check for a list of types'''
166 for t
in TO_LIST(list):
167 if not CHECK_TYPE(conf
, t
, headers
=headers
,
168 define
=define
, alternate
=alternate
, lib
=lib
):
174 def CHECK_TYPE_IN(conf
, t
, headers
=None, alternate
=None, define
=None):
175 '''check for a single type with a header'''
176 return CHECK_TYPE(conf
, t
, headers
=headers
, alternate
=alternate
, define
=define
)
180 def CHECK_VARIABLE(conf
, v
, define
=None, always
=False,
181 headers
=None, msg
=None, lib
=None):
182 '''check for a variable declaration (or define)'''
184 define
= 'HAVE_%s' % v
.upper()
187 msg
="Checking for variable %s" % v
189 return CHECK_CODE(conf
,
192 void *_x; _x=(void *)&%s;
207 def CHECK_DECLS(conf
, vars, reverse
=False, headers
=None, always
=False):
208 '''check a list of variable declarations, using the HAVE_DECL_xxx form
211 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
214 for v
in TO_LIST(vars):
216 define
='HAVE_DECL_%s' % v
.upper()
218 define
='HAVE_%s_DECL' % v
.upper()
219 if not CHECK_VARIABLE(conf
, v
,
222 msg
='Checking for declaration of %s' % v
,
228 def CHECK_FUNC(conf
, f
, link
=True, lib
=None, headers
=None):
229 '''check for a function'''
230 define
='HAVE_%s' % f
.upper()
234 conf
.COMPOUND_START('Checking for %s' % f
)
236 if link
is None or link
== True:
237 ret
= CHECK_CODE(conf
,
238 # this is based on the autoconf strategy
240 #define %s __fake__%s
247 #if defined __stub_%s || defined __stub___%s
248 #error "bad glibc stub"
251 int main() { return %s(); }
252 ''' % (f
, f
, f
, f
, f
, f
, f
),
261 msg
='Checking for %s' % f
)
264 ret
= CHECK_CODE(conf
,
265 # it might be a macro
266 'void *__x = (void *)%s' % f
,
275 msg
='Checking for macro %s' % f
)
277 if not ret
and (link
is None or link
== False):
278 ret
= CHECK_VARIABLE(conf
, f
,
281 msg
='Checking for declaration of %s' % f
)
282 conf
.COMPOUND_END(ret
)
287 def CHECK_FUNCS(conf
, list, link
=True, lib
=None, headers
=None):
288 '''check for a list of functions'''
290 for f
in TO_LIST(list):
291 if not CHECK_FUNC(conf
, f
, link
=link
, lib
=lib
, headers
=headers
):
297 def CHECK_SIZEOF(conf
, vars, headers
=None, define
=None):
298 '''check the size of a type'''
300 for v
in TO_LIST(vars):
303 v_define
= 'SIZEOF_%s' % v
.upper().replace(' ', '_')
304 if not CHECK_CODE(conf
,
305 'printf("%%u\\n", (unsigned)sizeof(%s))' % v
,
312 msg
="Checking size of %s" % v
):
319 def CHECK_CODE(conf
, code
, define
,
320 always
=False, execute
=False, addmain
=True,
321 add_headers
=True, mandatory
=False,
322 headers
=None, msg
=None, cflags
='', includes
='# .',
323 local_include
=True, lib
=None, link
=True,
324 define_ret
=False, quote
=False):
325 '''check if some code compiles and/or runs'''
327 if CONFIG_SET(conf
, define
):
330 if headers
is not None:
331 CHECK_HEADERS(conf
, headers
=headers
, lib
=lib
)
334 hdrs
= header_list(conf
, headers
=headers
, lib
=lib
)
343 fragment
='#include "__confdefs.h"\n%s\n int main(void) { %s; return 0; }\n' % (hdrs
, code
)
345 fragment
='#include "__confdefs.h"\n%s\n%s\n' % (hdrs
, code
)
347 conf
.write_config_header('__confdefs.h', top
=True)
350 msg
="Checking for %s" % define
352 # include the directory containing __confdefs.h
353 cflags
+= ' -I../../default'
356 cflags
+= ' -I%s' % conf
.curdir
363 uselib
= TO_LIST(lib
)
365 (ccflags
, ldflags
) = library_flags(conf
, uselib
)
367 cflags
= TO_LIST(cflags
)
368 cflags
.extend(ccflags
)
370 ret
= conf
.check(fragment
=fragment
,
372 define_name
= define
,
373 mandatory
= mandatory
,
381 define_ret
=define_ret
)
382 if not ret
and CONFIG_SET(conf
, define
):
383 # sometimes conf.check() returns false, but it
384 # sets the define. Maybe a waf bug?
388 conf
.DEFINE(define
, 1)
391 conf
.DEFINE(define
, 0)
397 def CHECK_STRUCTURE_MEMBER(conf
, structname
, member
,
398 always
=False, define
=None, headers
=None):
399 '''check for a structure member'''
401 define
= 'HAVE_%s' % member
.upper()
402 return CHECK_CODE(conf
,
403 '%s s; void *_x; _x=(void *)&s.%s' % (structname
, member
),
410 msg
="Checking for member %s in %s" % (member
, structname
))
414 def CHECK_CFLAGS(conf
, cflags
):
415 '''check if the given cflags are accepted by the compiler
417 return conf
.check(fragment
='int main(void) { return 0; }\n',
421 msg
="Checking compiler accepts %s" % cflags
)
425 def CONFIG_SET(conf
, option
):
426 '''return True if a configuration option was found'''
427 return (option
in conf
.env
) and (conf
.env
[option
] != ())
428 Build
.BuildContext
.CONFIG_SET
= CONFIG_SET
431 def library_flags(conf
, libs
):
432 '''work out flags from pkg_config'''
435 for lib
in TO_LIST(libs
):
437 inc_path
= getattr(conf
.env
, 'CPPPATH_%s' % lib
.upper(), [])
438 lib_path
= getattr(conf
.env
, 'LIBPATH_%s' % lib
.upper(), [])
440 ccflags
.append('-I%s' % i
)
442 ldflags
.append('-L%s' % l
)
443 return (ccflags
, ldflags
)
447 def CHECK_LIB(conf
, libs
, mandatory
=False, empty_decl
=True):
448 '''check if a set of libraries exist'''
450 liblist
= TO_LIST(libs
)
452 for lib
in liblist
[:]:
453 if GET_TARGET_TYPE(conf
, lib
) == 'SYSLIB':
456 (ccflags
, ldflags
) = library_flags(conf
, lib
)
458 if not conf
.check(lib
=lib
, uselib_store
=lib
, ccflags
=ccflags
, ldflags
=ldflags
):
460 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
463 # if it isn't a mandatory library, then remove it from dependency lists
464 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
467 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_'), 1)
468 conf
.env
['LIB_' + lib
.upper()] = lib
469 LOCAL_CACHE_SET(conf
, 'TARGET_TYPE', lib
, 'SYSLIB')
476 def CHECK_FUNCS_IN(conf
, list, library
, mandatory
=False, checklibc
=False,
477 headers
=None, link
=True, empty_decl
=True):
479 check that the functions in 'list' are available in 'library'
480 if they are, then make that library available as a dependency
482 if the library is not available and mandatory==True, then
485 If the library is not available and mandatory==False, then
486 add the library to the list of dependencies to remove from
489 optionally check for the functions first in libc
491 remaining
= TO_LIST(list)
492 liblist
= TO_LIST(library
)
494 # check if some already found
495 for f
in remaining
[:]:
496 if CONFIG_SET(conf
, 'HAVE_%s' % f
.upper()):
499 # see if the functions are in libc
501 for f
in remaining
[:]:
502 if CHECK_FUNC(conf
, f
, link
=True, headers
=headers
):
507 if GET_TARGET_TYPE(conf
, lib
) != 'SYSLIB' and empty_decl
:
508 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
511 conf
.CHECK_LIB(liblist
, empty_decl
=empty_decl
)
512 for lib
in liblist
[:]:
513 if not GET_TARGET_TYPE(conf
, lib
) == 'SYSLIB':
515 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
517 # if it isn't a mandatory library, then remove it from dependency lists
523 if not CHECK_FUNC(conf
, f
, lib
=' '.join(liblist
), headers
=headers
, link
=link
):
530 def IN_LAUNCH_DIR(conf
):
531 '''return True if this rule is being run from the launch directory'''
532 return os
.path
.realpath(conf
.curdir
) == os
.path
.realpath(Options
.launch_dir
)
536 def SAMBA_CONFIG_H(conf
, path
=None):
537 '''write out config.h in the right directory'''
538 # we don't want to produce a config.h in places like lib/replace
539 # when we are building projects that depend on lib/replace
540 if not IN_LAUNCH_DIR(conf
):
543 if Options
.options
.developer
:
544 # we add these here to ensure that -Wstrict-prototypes is not set during configure
545 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',
548 if Options
.options
.picky_developer
:
549 conf
.ADD_CFLAGS('-Werror', testflags
=True)
551 if Options
.options
.fatal_errors
:
552 conf
.ADD_CFLAGS('-Wfatal-errors', testflags
=True)
554 if Options
.options
.pedantic
:
555 conf
.ADD_CFLAGS('-W', testflags
=True)
558 conf
.write_config_header('config.h', top
=True)
560 conf
.write_config_header(path
)
564 def CONFIG_PATH(conf
, name
, default
):
565 '''setup a configurable path'''
566 if not name
in conf
.env
:
567 if default
[0] == '/':
568 conf
.env
[name
] = default
570 conf
.env
[name
] = conf
.env
['PREFIX'] + default
573 def ADD_CFLAGS(conf
, flags
, testflags
=False):
574 '''add some CFLAGS to the command line
575 optionally set testflags to ensure all the flags work
579 for f
in flags
.split():
580 if CHECK_CFLAGS(conf
, f
):
583 if not 'EXTRA_CFLAGS' in conf
.env
:
584 conf
.env
['EXTRA_CFLAGS'] = []
585 conf
.env
['EXTRA_CFLAGS'].extend(TO_LIST(flags
))
590 def ADD_EXTRA_INCLUDES(conf
, includes
):
591 '''add some extra include directories to all builds'''
592 if not 'EXTRA_INCLUDES' in conf
.env
:
593 conf
.env
['EXTRA_INCLUDES'] = []
594 conf
.env
['EXTRA_INCLUDES'].extend(TO_LIST(includes
))
598 def CURRENT_CFLAGS(bld
, target
, cflags
):
599 '''work out the current flags. local flags are added first'''
600 if not 'EXTRA_CFLAGS' in bld
.env
:
603 list = bld
.env
['EXTRA_CFLAGS'];
604 ret
= TO_LIST(cflags
)
610 def CHECK_CC_ENV(conf
):
611 """trim whitespaces from 'CC'.
612 The build farm sometimes puts a space at the start"""
613 if os
.environ
.get('CC'):
614 conf
.env
.CC
= TO_LIST(os
.environ
.get('CC'))
615 if len(conf
.env
.CC
) == 1:
616 # make for nicer logs if just a single command
617 conf
.env
.CC
= conf
.env
.CC
[0]
621 def SETUP_CONFIGURE_CACHE(conf
, enable
):
622 '''enable/disable cache of configure results'''
624 # when -C is chosen, we will use a private cache and will
625 # not look into system includes. This roughtly matches what
626 # autoconf does with -C
627 cache_path
= os
.path
.join(conf
.blddir
, '.confcache')
629 Options
.cache_global
= os
.environ
['WAFCACHE'] = cache_path
631 # when -C is not chosen we will not cache configure checks
632 # We set the recursion limit low to prevent waf from spending
633 # a lot of time on the signatures of the files.
634 Options
.cache_global
= os
.environ
['WAFCACHE'] = ''
635 preproc
.recursion_limit
= 1
636 # in either case we don't need to scan system includes
637 preproc
.go_absolute
= False