1 # a waf tool to add autoconf-like macros to the configure section
3 import Build
, os
, Options
, preproc
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):
18 '''define a config option'''
19 conf
.define(d
, v
, quote
=False)
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
37 '''using the nolink type in conf.check() allows us to avoid
38 the link stage of a test, thus speeding it up for tests
39 that where linking is not needed'''
43 def CHECK_HEADER(conf
, h
, add_headers
=False):
44 '''check for a header'''
45 if h
in missing_headers
:
47 d
= h
.upper().replace('/', '_')
48 d
= d
.replace('.', '_')
50 if CONFIG_SET(conf
, d
):
52 if not h
in conf
.env
.hlist
:
53 conf
.env
.hlist
.append(h
)
56 hdrs
= hlist_to_string(conf
, headers
=h
)
57 ret
= conf
.check(fragment
='%s\nint main(void) { return 0; }' % hdrs
,
60 msg
="Checking for header %s" % h
)
62 missing_headers
.add(h
)
66 if add_headers
and not h
in conf
.env
.hlist
:
67 conf
.env
.hlist
.append(h
)
72 def CHECK_HEADERS(conf
, headers
, add_headers
=False):
73 '''check for a list of headers'''
75 for hdr
in TO_LIST(headers
):
76 if not CHECK_HEADER(conf
, hdr
, add_headers
):
80 def header_list(conf
, headers
=None):
81 '''form a list of headers which exist, as a string'''
83 if headers
is not None:
84 for h
in TO_LIST(headers
):
85 if CHECK_HEADER(conf
, h
, add_headers
=False):
87 return hlist_to_string(conf
, headers
=hlist
)
91 def CHECK_TYPE(conf
, t
, alternate
=None, headers
=None, define
=None):
92 '''check for a single type'''
94 define
= 'HAVE_' + t
.upper().replace(' ', '_')
95 ret
= CHECK_CODE(conf
, '%s _x' % t
,
99 msg
='Checking for %s' % t
,
102 if not ret
and alternate
:
103 conf
.DEFINE(t
, alternate
)
108 def CHECK_TYPES(conf
, list, headers
=None, define
=None, alternate
=None):
109 '''check for a list of types'''
111 for t
in TO_LIST(list):
112 if not CHECK_TYPE(conf
, t
, headers
=headers
, define
=define
, alternate
=alternate
):
118 def CHECK_TYPE_IN(conf
, t
, headers
=None, alternate
=None, define
=None):
119 '''check for a single type with a header'''
120 return CHECK_TYPE(conf
, t
, headers
=headers
, alternate
=alternate
, define
=define
)
124 def CHECK_VARIABLE(conf
, v
, define
=None, always
=False, headers
=None, msg
=None):
125 '''check for a variable declaration (or define)'''
127 define
= 'HAVE_%s' % v
.upper()
130 msg
="Checking for variable %s" % v
132 return CHECK_CODE(conf
,
135 void *_x; _x=(void *)&%s;
149 def CHECK_DECLS(conf
, vars, reverse
=False, headers
=None):
150 '''check a list of variable declarations, using the HAVE_DECL_xxx form
153 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
156 for v
in TO_LIST(vars):
158 define
='HAVE_DECL_%s' % v
.upper()
160 define
='HAVE_%s_DECL' % v
.upper()
161 if not CHECK_VARIABLE(conf
, v
,
164 msg
='Checking for declaration of %s' % v
):
169 def CHECK_FUNC(conf
, f
, link
=None, lib
='c', headers
=None):
170 '''check for a function'''
171 define
='HAVE_%s' % f
.upper()
173 # there are two ways to find a function. The first is
174 # to see if there is a declaration of the function, the
175 # 2nd is to try and link a program that calls the function
176 # unfortunately both strategies have problems.
177 # the 'check the declaration' approach works fine as long
178 # as the function has a declaraion in a header. If there is
179 # no header declaration we can get a false negative.
180 # The link method works fine as long as the compiler
181 # doesn't have a builtin for the function, which could cause
182 # a false negative due to mismatched parameters
183 # so to be sure, we need to try both
186 if link
is None or link
== True:
187 ret
= CHECK_CODE(conf
,
188 'int main(void) { extern void %s(void); %s(); return 0; }' % (f
, f
),
197 msg
='Checking for %s' % f
)
199 if not ret
and (link
is None or link
== False):
200 ret
= CHECK_VARIABLE(conf
, f
,
203 msg
='Checking for declaration of %s' % f
)
208 def CHECK_FUNCS(conf
, list, link
=None, lib
='c', headers
=None):
209 '''check for a list of functions'''
211 for f
in TO_LIST(list):
212 if not CHECK_FUNC(conf
, f
, link
=link
, lib
=lib
, headers
=headers
):
218 def CHECK_SIZEOF(conf
, vars, headers
=None, define
=None):
219 '''check the size of a type'''
221 for v
in TO_LIST(vars):
224 v_define
= 'SIZEOF_%s' % v
.upper().replace(' ', '_')
225 if not CHECK_CODE(conf
,
226 'printf("%%u\\n", (unsigned)sizeof(%s))' % v
,
233 msg
="Checking size of %s" % v
):
240 def CHECK_CODE(conf
, code
, define
,
241 always
=False, execute
=False, addmain
=True,
242 add_headers
=True, mandatory
=False,
243 headers
=None, msg
=None, cflags
='', includes
='# .',
244 local_include
=True, lib
='c', link
=True,
245 define_ret
=False, quote
=False):
246 '''check if some code compiles and/or runs'''
248 if CONFIG_SET(conf
, define
):
251 if headers
is not None:
252 CHECK_HEADERS(conf
, headers
=headers
)
255 hdrs
= header_list(conf
, headers
=headers
)
264 fragment
='#include "__confdefs.h"\n%s\n int main(void) { %s; return 0; }' % (hdrs
, code
)
266 fragment
='#include "__confdefs.h"\n%s\n%s' % (hdrs
, code
)
268 conf
.write_config_header('__confdefs.h', top
=True)
271 msg
="Checking for %s" % define
273 # include the directory containing __confdefs.h
274 cflags
+= ' -I../../default'
277 cflags
+= ' -I%s' % conf
.curdir
284 if conf
.check(fragment
=fragment
,
286 define_name
= define
,
287 mandatory
= mandatory
,
288 ccflags
=TO_LIST(cflags
),
290 lib
=lib
, # how do I make this conditional, so I can avoid the -lc?
294 define_ret
=define_ret
):
296 conf
.DEFINE(define
, 1)
299 conf
.DEFINE(define
, 0)
305 def CHECK_STRUCTURE_MEMBER(conf
, structname
, member
,
306 always
=False, define
=None, headers
=None):
307 '''check for a structure member'''
309 define
= 'HAVE_%s' % member
.upper()
310 return CHECK_CODE(conf
,
311 '%s s; void *_x; _x=(void *)&s.%s' % (structname
, member
),
318 msg
="Checking for member %s in %s" % (member
, structname
))
322 def CHECK_CFLAGS(conf
, cflags
):
323 '''check if the given cflags are accepted by the compiler
325 return conf
.check(fragment
='int main(void) { return 0; }',
328 msg
="Checking compiler accepts %s" % cflags
)
331 #################################################
332 # return True if a configuration option was found
334 def CONFIG_SET(conf
, option
):
335 return (option
in conf
.env
) and (conf
.env
[option
] != ())
336 Build
.BuildContext
.CONFIG_SET
= CONFIG_SET
340 def CHECK_LIB(conf
, libs
):
341 '''check if a set of libraries exist'''
342 liblist
= TO_LIST(library
)
345 for lib
in liblist
[:]:
346 if GET_TARGET_TYPE(conf
, lib
):
348 if not conf
.check(lib
=lib
, uselib_store
=lib
):
349 conf
.ASSERT(not mandatory
,
350 "Mandatory library '%s' not found for functions '%s'" % (lib
, list))
351 # if it isn't a mandatory library, then remove it from dependency lists
352 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
355 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_'), 1)
356 conf
.env
['LIB_' + lib
.upper()] = lib
357 LOCAL_CACHE_SET(conf
, 'TARGET_TYPE', lib
, 'SYSLIB')
362 ###########################################################
363 # check that the functions in 'list' are available in 'library'
364 # if they are, then make that library available as a dependency
366 # if the library is not available and mandatory==True, then
369 # If the library is not available and mandatory==False, then
370 # add the library to the list of dependencies to remove from
373 # optionally check for the functions first in libc
375 def CHECK_FUNCS_IN(conf
, list, library
, mandatory
=False, checklibc
=False, headers
=None, link
=None):
376 remaining
= TO_LIST(list)
377 liblist
= TO_LIST(library
)
379 # check if some already found
380 for f
in remaining
[:]:
381 if CONFIG_SET(conf
, 'HAVE_%s' % f
.upper()):
384 # see if the functions are in libc
386 for f
in remaining
[:]:
387 if CHECK_FUNC(conf
, f
, link
=True, headers
=headers
):
392 if GET_TARGET_TYPE(conf
, lib
) != 'SYSLIB':
393 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
397 for lib
in liblist
[:]:
398 if GET_TARGET_TYPE(conf
, lib
):
400 if not conf
.check(lib
=lib
, uselib_store
=lib
):
401 conf
.ASSERT(not mandatory
,
402 "Mandatory library '%s' not found for functions '%s'" % (lib
, list))
403 # if it isn't a mandatory library, then remove it from dependency lists
404 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
407 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_'), 1)
408 conf
.env
['LIB_' + lib
.upper()] = lib
409 LOCAL_CACHE_SET(conf
, 'TARGET_TYPE', lib
, 'SYSLIB')
416 if not CHECK_FUNC(conf
, f
, lib
=' '.join(liblist
), headers
=headers
, link
=link
):
423 def CHECK_C_PROTOTYPE(conf
, function
, prototype
, define
, headers
=None):
424 '''verify that a C prototype matches the one on the current system'''
425 if not conf
.CHECK_DECLS(function
, headers
=headers
):
427 return conf
.CHECK_CODE('%s; void *_x = (void *)%s' % (prototype
, function
),
430 msg
='Checking C prototype for %s' % function
)
435 #################################################
436 # write out config.h in the right directory
438 def SAMBA_CONFIG_H(conf
, path
=None):
439 # we don't want to produce a config.h in places like lib/replace
440 # when we are building projects that depend on lib/replace
441 if os
.path
.realpath(conf
.curdir
) != os
.path
.realpath(Options
.launch_dir
):
444 if Options
.options
.developer
:
445 # we add these here to ensure that -Wstrict-prototypes is not set during configure
446 conf
.ADD_CFLAGS('-Wall -g -Wfatal-errors -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Werror-implicit-function-declaration -Wformat=2 -Wno-format-y2k')
449 conf
.write_config_header('config.h', top
=True)
451 conf
.write_config_header(path
)
454 ##############################################################
455 # setup a configurable path
457 def CONFIG_PATH(conf
, name
, default
):
458 if not name
in conf
.env
:
459 if default
[0] == '/':
460 conf
.env
[name
] = default
462 conf
.env
[name
] = conf
.env
['PREFIX'] + default
463 conf
.define(name
, conf
.env
[name
], quote
=True)
465 ##############################################################
466 # add some CFLAGS to the command line
468 def ADD_CFLAGS(conf
, flags
):
469 if not 'EXTRA_CFLAGS' in conf
.env
:
470 conf
.env
['EXTRA_CFLAGS'] = []
471 conf
.env
['EXTRA_CFLAGS'].extend(TO_LIST(flags
))
473 ##############################################################
474 # add some extra include directories to all builds
476 def ADD_EXTRA_INCLUDES(conf
, includes
):
477 if not 'EXTRA_INCLUDES' in conf
.env
:
478 conf
.env
['EXTRA_INCLUDES'] = []
479 conf
.env
['EXTRA_INCLUDES'].extend(TO_LIST(includes
))
482 ##############################################################
483 # work out the current flags. local flags are added first
484 def CURRENT_CFLAGS(bld
, target
, cflags
):
485 if not 'EXTRA_CFLAGS' in bld
.env
:
488 list = bld
.env
['EXTRA_CFLAGS'];
489 ret
= TO_LIST(cflags
)
494 def CHECK_RPATH_SUPPORT(conf
):
495 '''see if the system supports rpath'''
496 return conf
.CHECK_CODE('int x',
497 define
='HAVE_RPATH_SUPPORT',
500 msg
='Checking for rpath support',
501 cflags
='-Wl,-rpath=.')
504 def CHECK_CC_ENV(conf
):
505 '''trim whitespaces from 'CC'.
506 The build farm sometimes puts a space at the start'''
507 if os
.environ
.get('CC'):
508 conf
.env
.CC
= TO_LIST(os
.environ
.get('CC'))
509 if len(conf
.env
.CC
) == 1:
510 # make for nicer logs if just a single command
511 conf
.env
.CC
= conf
.env
.CC
[0]
515 def SETUP_CONFIGURE_CACHE(conf
, enable
):
516 '''enable/disable cache of configure results'''
518 # when -C is chosen, we will use a private cache and will
519 # not look into system includes. This roughtly matches what
520 # autoconf does with -C
521 cache_path
= os
.path
.join(conf
.blddir
, '.confcache')
523 Options
.cache_global
= os
.environ
['WAFCACHE'] = cache_path
525 # when -C is not chosen we will not cache configure checks
526 # We set the recursion limit low to prevent waf from spending
527 # a lot of time on the signatures of the files.
528 Options
.cache_global
= os
.environ
['WAFCACHE'] = ''
529 preproc
.recursion_limit
= 1
530 # in either case we don't need to scan system includes
531 preproc
.go_absolute
= False