1 # a waf tool to add autoconf-like macros to the configure section
4 from waflib
import Build
, Options
, Logs
, Context
5 from waflib
.Configure
import conf
6 from waflib
.TaskGen
import feature
7 from waflib
.Tools
import c_preproc
as preproc
8 from samba_utils
import TO_LIST
, GET_TARGET_TYPE
, SET_TARGET_TYPE
, unique_list
, mkdir_p
10 missing_headers
= set()
12 ####################################################
13 # some autoconf like helpers, to make the transition
14 # 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('CFLAGS', '-D%s=%s' % (d
, str(v
)))
24 def hlist_to_string(conf
, headers
=None):
25 '''convert a headers list to a set of #include lines'''
26 hlist
= conf
.env
.hlist
29 hlist
.extend(TO_LIST(headers
))
30 hdrs
= "\n".join('#include <%s>' % h
for h
in hlist
)
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
48 conf
.saved_check_message_1
= conf
.start_msg
49 conf
.start_msg
= null_check_message_1
50 conf
.saved_check_message_2
= conf
.end_msg
51 conf
.end_msg
= 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
.start_msg
= conf
.saved_check_message_1
62 conf
.end_msg
= conf
.saved_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
and lib
is None:
84 d
= h
.upper().replace('/', '_')
85 d
= d
.replace('.', '_')
86 d
= d
.replace('-', '_')
88 if CONFIG_SET(conf
, d
):
90 if not h
in conf
.env
.hlist
:
91 conf
.env
.hlist
.append(h
)
94 (ccflags
, ldflags
, cpppath
, libs
) = library_flags(conf
, lib
)
96 hdrs
= hlist_to_string(conf
, headers
=h
)
99 ret
= conf
.check(fragment
='%s\nint main(void) { return 0; }\n' % 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, cflags
=''):
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
,
164 if not ret
and alternate
:
165 conf
.DEFINE(t
, alternate
)
170 def CHECK_TYPES(conf
, list, headers
=None, define
=None, alternate
=None, lib
=None):
171 '''check for a list of types'''
173 for t
in TO_LIST(list):
174 if not CHECK_TYPE(conf
, t
, headers
=headers
,
175 define
=define
, alternate
=alternate
, lib
=lib
):
181 def CHECK_TYPE_IN(conf
, t
, headers
=None, alternate
=None, define
=None, cflags
=''):
182 '''check for a single type with a header'''
183 return CHECK_TYPE(conf
, t
, headers
=headers
, alternate
=alternate
, define
=define
, cflags
=cflags
)
187 def CHECK_VARIABLE(conf
, v
, define
=None, always
=False,
188 headers
=None, msg
=None, lib
=None,
190 '''check for a variable declaration (or define)'''
192 define
= 'HAVE_%s' % v
.upper()
195 msg
="Checking for variable %s" % v
197 return CHECK_CODE(conf
,
198 # we need to make sure the compiler doesn't
202 void *_x; _x=(void *)&%s; return (int)_x;
218 def CHECK_DECLS(conf
, vars, reverse
=False, headers
=None, lib
=None, always
=False):
219 '''check a list of variable declarations, using the HAVE_DECL_xxx form
222 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
225 for v
in TO_LIST(vars):
227 define
='HAVE_DECL_%s' % v
.upper()
229 define
='HAVE_%s_DECL' % v
.upper()
230 if not CHECK_VARIABLE(conf
, v
,
234 msg
='Checking for declaration of %s' % v
,
236 if not CHECK_CODE(conf
,
242 msg
='Checking for declaration of %s (as enum)' % v
,
252 def CHECK_FUNC(conf
, f
, link
=True, lib
=None, headers
=None):
253 '''check for a function'''
254 define
='HAVE_%s' % f
.upper()
260 in_lib_str
= " in %s" % lib
261 conf
.COMPOUND_START('Checking for %s%s' % (f
, in_lib_str
))
263 if link
is None or link
:
264 ret
= CHECK_CODE(conf
,
265 # this is based on the autoconf strategy
267 #define %s __fake__%s
274 #if defined __stub_%s || defined __stub___%s
275 #error "bad glibc stub"
278 int main() { return %s(); }
279 ''' % (f
, f
, f
, f
, f
, f
, f
),
288 msg
='Checking for %s' % f
)
291 ret
= CHECK_CODE(conf
,
292 # it might be a macro
293 # we need to make sure the compiler doesn't
295 'void *__x = (void *)%s; return (int)__x' % f
,
304 msg
='Checking for macro %s' % f
)
306 if not ret
and (link
is None or not link
):
307 ret
= CHECK_VARIABLE(conf
, f
,
310 msg
='Checking for declaration of %s' % f
)
311 conf
.COMPOUND_END(ret
)
316 def CHECK_FUNCS(conf
, list, link
=True, lib
=None, headers
=None):
317 '''check for a list of functions'''
319 for f
in TO_LIST(list):
320 if not CHECK_FUNC(conf
, f
, link
=link
, lib
=lib
, headers
=headers
):
326 def CHECK_SIZEOF(conf
, vars, headers
=None, define
=None, critical
=True):
327 '''check the size of a type'''
328 for v
in TO_LIST(vars):
332 v_define
= 'SIZEOF_%s' % v
.upper().replace(' ', '_')
333 for size
in list((1, 2, 4, 8, 16, 32, 64)):
335 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v
, size
),
340 msg
="Checking if size of %s == %d" % (v
, size
)):
341 conf
.DEFINE(v_define
, size
)
344 if not ret
and critical
:
345 Logs
.error("Couldn't determine size of '%s'" % v
)
350 def CHECK_SIGN(conf
, v
, headers
=None):
351 '''check the sign of a type'''
352 define_name
= v
.upper().replace(' ', '_')
353 for op
, signed
in [('<', 'signed'),
356 f
'static int test_array[1 - 2 * !((({v})-1) {op} 0)];',
357 define
=f
'{define_name}_{signed.upper()}',
361 msg
=f
"Checking if '{v}' is {signed}"):
367 def CHECK_VALUEOF(conf
, v
, headers
=None, define
=None, lib
=None):
368 '''check the value of a variable/define'''
372 v_define
= 'VALUEOF_%s' % v
.upper().replace(' ', '_')
374 'printf("%%u", (unsigned)(%s))' % v
,
382 msg
="Checking value of %s" % v
):
383 return int(conf
.env
[v_define
])
388 def CHECK_CODE(conf
, code
, define
,
389 always
=False, execute
=False, addmain
=True,
390 add_headers
=True, mandatory
=False,
391 headers
=None, msg
=None, cflags
='', includes
='# .',
392 local_include
=True, lib
=None, link
=True,
393 define_ret
=False, quote
=False,
394 on_target
=True, strict
=False):
395 '''check if some code compiles and/or runs'''
397 if CONFIG_SET(conf
, define
):
400 if headers
is not None:
401 CHECK_HEADERS(conf
, headers
=headers
, lib
=lib
)
404 hdrs
= header_list(conf
, headers
=headers
, lib
=lib
)
413 fragment
='%s\n int main(void) { %s; return 0; }\n' % (hdrs
, code
)
415 fragment
='%s\n%s\n' % (hdrs
, code
)
418 msg
="Checking for %s" % define
420 cflags
= TO_LIST(cflags
)
422 # Be strict when relying on a compiler check
423 # Some compilers (e.g. xlc) ignore non-supported features as warnings
425 if 'WERROR_CFLAGS' in conf
.env
:
426 cflags
.extend(conf
.env
['WERROR_CFLAGS'])
429 cflags
.append('-I%s' % conf
.path
.abspath())
436 uselib
= TO_LIST(lib
)
438 (ccflags
, ldflags
, cpppath
, libs
) = library_flags(conf
, uselib
)
440 includes
= TO_LIST(includes
)
441 includes
.extend(cpppath
)
443 uselib
= [l
.upper() for l
in uselib
]
445 cflags
.extend(ccflags
)
448 test_args
= conf
.SAMBA_CROSS_ARGS(msg
=msg
)
452 conf
.COMPOUND_START(msg
)
455 ret
= conf
.check(fragment
=fragment
,
457 define_name
= define
,
466 define_ret
=define_ret
)
469 conf
.DEFINE(define
, 0)
471 conf
.undefine(define
)
472 conf
.COMPOUND_END(False)
477 # Success is indicated by ret but we should unset
478 # defines set by WAF's c_config.check() because it
479 # defines it to int(ret) and we want to undefine it
481 conf
.undefine(define
)
482 conf
.COMPOUND_END(False)
485 conf
.DEFINE(define
, 1)
486 conf
.COMPOUND_END(True)
488 conf
.DEFINE(define
, ret
, quote
=quote
)
489 conf
.COMPOUND_END(ret
)
494 def CHECK_STRUCTURE_MEMBER(conf
, structname
, member
,
495 always
=False, define
=None, headers
=None,
497 '''check for a structure member'''
499 define
= 'HAVE_%s' % member
.upper()
500 return CHECK_CODE(conf
,
501 '%s s; void *_x; _x=(void *)&s.%s' % (structname
, member
),
509 msg
="Checking for member %s in %s" % (member
, structname
))
513 def CHECK_CFLAGS(conf
, cflags
, fragment
='int main(void) { return 0; }\n',
515 '''check if the given cflags are accepted by the compiler
517 check_cflags
= TO_LIST(cflags
)
518 if 'WERROR_CFLAGS' in conf
.env
:
519 check_cflags
.extend(conf
.env
['WERROR_CFLAGS'])
520 return conf
.check(fragment
=fragment
,
525 msg
="Checking compiler accepts %s" % cflags
)
528 def CHECK_LDFLAGS(conf
, ldflags
,
530 '''check if the given ldflags are accepted by the linker
532 return conf
.check(fragment
='int main(void) { return 0; }\n',
536 msg
="Checking linker accepts %s" % ldflags
)
540 def CONFIG_GET(conf
, option
):
541 '''return True if a configuration option was found'''
542 if (option
in conf
.env
):
543 return conf
.env
[option
]
548 def CONFIG_SET(conf
, option
):
549 '''return True if a configuration option was found'''
550 if option
not in conf
.env
:
562 def CONFIG_RESET(conf
, option
):
563 if option
not in conf
.env
:
567 Build
.BuildContext
.CONFIG_RESET
= CONFIG_RESET
568 Build
.BuildContext
.CONFIG_SET
= CONFIG_SET
569 Build
.BuildContext
.CONFIG_GET
= CONFIG_GET
572 def library_flags(self
, library
):
573 '''work out flags from pkg_config'''
578 for lib
in TO_LIST(library
):
579 # note that we do not add the -I and -L in here, as that is added by the waf
580 # core. Adding it here would just change the order that it is put on the link line
581 # which can cause system paths to be added before internal libraries
582 extra_ccflags
= TO_LIST(getattr(self
.env
, 'CFLAGS_%s' % lib
.upper(), []))
583 extra_ldflags
= TO_LIST(getattr(self
.env
, 'LDFLAGS_%s' % lib
.upper(), []))
584 extra_cpppath
= TO_LIST(getattr(self
.env
, 'CPPPATH_%s' % lib
.upper(), []))
585 extra_libs
= TO_LIST(getattr(self
.env
, 'LIB_%s' % lib
.upper(), []))
586 ccflags
.extend(extra_ccflags
)
587 ldflags
.extend(extra_ldflags
)
588 cpppath
.extend(extra_cpppath
)
589 libs
.extend(extra_libs
)
591 extra_cpppath
= TO_LIST(getattr(self
.env
, 'INCLUDES_%s' % lib
.upper(), []))
592 cpppath
.extend(extra_cpppath
)
593 if 'EXTRA_LDFLAGS' in self
.env
:
594 ldflags
.extend(self
.env
['EXTRA_LDFLAGS'])
596 ccflags
= unique_list(ccflags
)
597 ldflags
= unique_list(ldflags
)
598 cpppath
= unique_list(cpppath
)
599 libs
= unique_list(libs
)
600 return (ccflags
, ldflags
, cpppath
, libs
)
604 def CHECK_LIB(conf
, library
, mandatory
=False, empty_decl
=True, set_target
=True, shlib
=False):
605 '''check if a set of libraries exist as system libraries
607 returns the sublist of libs that do exist as a syslib or []
618 liblist
= TO_LIST(library
)
620 if GET_TARGET_TYPE(conf
, lib
) == 'SYSLIB':
624 (ccflags
, ldflags
, cpppath
, libs
) = library_flags(conf
, lib
)
626 # Avoid repeating the library if it is already named by
631 res
= conf
.check(features
='c cshlib', fragment
=fragment
, uselib_store
=lib
, cflags
=ccflags
, ldflags
=ldflags
, uselib
=lib
.upper(), mandatory
=False, **kw
)
633 res
= conf
.check(lib
=lib
, uselib_store
=lib
, cflags
=ccflags
, ldflags
=ldflags
, uselib
=lib
.upper(), mandatory
=False)
637 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, libs
))
640 # if it isn't a mandatory library, then remove it from dependency lists
642 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
644 conf
.define('HAVE_LIB%s' % lib
.upper().replace('-','_').replace('.','_'), 1)
645 # To avoid losing information from pkg-config, append the library
646 # only it is not already present.
648 conf
.env
.append_value('LIB_' + lib
.upper(), lib
)
650 conf
.SET_TARGET_TYPE(lib
, 'SYSLIB')
658 def CHECK_FUNCS_IN(conf
, list, library
, mandatory
=False, checklibc
=False,
659 headers
=None, link
=True, empty_decl
=True, set_target
=True):
661 check that the functions in 'list' are available in 'library'
662 if they are, then make that library available as a dependency
664 if the library is not available and mandatory==True, then
667 If the library is not available and mandatory==False, then
668 add the library to the list of dependencies to remove from
671 optionally check for the functions first in libc
673 remaining
= TO_LIST(list)
674 liblist
= TO_LIST(library
)
676 # check if some already found
677 for f
in remaining
[:]:
678 if CONFIG_SET(conf
, 'HAVE_%s' % f
.upper()):
681 # see if the functions are in libc
683 for f
in remaining
[:]:
684 if CHECK_FUNC(conf
, f
, link
=True, headers
=headers
):
689 if GET_TARGET_TYPE(conf
, lib
) != 'SYSLIB' and empty_decl
:
690 SET_TARGET_TYPE(conf
, lib
, 'EMPTY')
693 checklist
= conf
.CHECK_LIB(liblist
, empty_decl
=empty_decl
, set_target
=set_target
)
694 for lib
in liblist
[:]:
695 if not lib
in checklist
and mandatory
:
696 Logs
.error("Mandatory library '%s' not found for functions '%s'" % (lib
, list))
701 if not CHECK_FUNC(conf
, f
, lib
=' '.join(checklist
), headers
=headers
, link
=link
):
708 def IN_LAUNCH_DIR(conf
):
709 '''return True if this rule is being run from the launch directory'''
710 return os
.path
.realpath(conf
.path
.abspath()) == os
.path
.realpath(Context
.launch_dir
)
711 Options
.OptionsContext
.IN_LAUNCH_DIR
= IN_LAUNCH_DIR
715 def SAMBA_CONFIG_H(conf
, path
=None):
716 '''write out config.h in the right directory'''
717 # we don't want to produce a config.h in places like lib/replace
718 # when we are building projects that depend on lib/replace
719 if not IN_LAUNCH_DIR(conf
):
722 # we need to build real code that can't be optimized away to test
723 stack_protect_list
= ['-fstack-protector-strong', '-fstack-protector']
724 for stack_protect_flag
in stack_protect_list
:
725 flag_supported
= conf
.check(fragment
='''
731 while (fgets(t, sizeof(t), stdin));
736 cflags
=[ '-Werror', '-Wp,-D_FORTIFY_SOURCE=2', stack_protect_flag
],
738 msg
='Checking if compiler accepts %s' % (stack_protect_flag
))
740 conf
.ADD_CFLAGS('%s' % (stack_protect_flag
))
743 flag_supported
= conf
.check(fragment
='''
749 while (fgets(t, sizeof(t), stdin));
754 cflags
=[ '-Werror', '-fstack-clash-protection'],
756 msg
='Checking if compiler accepts -fstack-clash-protection')
758 conf
.ADD_CFLAGS('-fstack-clash-protection')
760 if Options
.options
.debug
:
761 conf
.ADD_CFLAGS('-g', testflags
=True)
763 if Options
.options
.pidl_developer
:
764 conf
.env
.PIDL_DEVELOPER_MODE
= True
766 if Options
.options
.developer
:
767 conf
.env
.DEVELOPER_MODE
= True
769 conf
.ADD_CFLAGS('-g', testflags
=True)
770 conf
.ADD_CFLAGS('-Wall', testflags
=True)
771 conf
.ADD_CFLAGS('-Wshadow', testflags
=True)
772 conf
.ADD_CFLAGS('-Wmissing-prototypes', testflags
=True)
774 'struct a { int b; }; struct c { struct a d; } e = { };',
777 cflags
='-Wmissing-field-initializers -Werror=missing-field-initializers',
778 msg
="Checking C99 init of nested structs."):
779 conf
.ADD_CFLAGS('-Wmissing-field-initializers', testflags
=True)
780 conf
.ADD_CFLAGS('-Wformat-overflow=2', testflags
=True)
781 conf
.ADD_CFLAGS('-Wformat-zero-length', testflags
=True)
782 conf
.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags
=True)
783 conf
.ADD_CFLAGS('-fno-common', testflags
=True)
785 conf
.ADD_CFLAGS('-Werror=address', testflags
=True)
786 # we add these here to ensure that -Wstrict-prototypes is not set during configure
787 conf
.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
789 conf
.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
791 conf
.ADD_CFLAGS('-Werror-implicit-function-declaration',
793 conf
.ADD_CFLAGS('-Werror=implicit-int',
795 conf
.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
797 conf
.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
799 conf
.ADD_CFLAGS('-Werror=return-type -Wreturn-type',
801 conf
.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
803 conf
.ADD_CFLAGS('-Wimplicit-fallthrough',
805 conf
.ADD_CFLAGS('-Werror=strict-overflow -Wstrict-overflow=2',
807 conf
.ADD_CFLAGS('-Werror=old-style-definition -Wold-style-definition',
810 conf
.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags
=True)
811 conf
.ADD_CFLAGS('-Wno-format-zero-length', testflags
=True)
812 conf
.ADD_CFLAGS('-Werror=format-security -Wformat-security',
813 testflags
=True, prereq_flags
='-Wformat')
814 # This check is because for ldb_search(), a NULL format string
815 # is not an error, but some compilers complain about that.
816 if CHECK_CFLAGS(conf
, ["-Werror=format", "-Wformat=2"], '''
817 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
825 if not 'EXTRA_CFLAGS' in conf
.env
:
826 conf
.env
['EXTRA_CFLAGS'] = []
827 conf
.env
['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
829 if CHECK_CFLAGS(conf
, ["-Wno-error=array-bounds"]):
830 conf
.define('HAVE_WNO_ERROR_ARRAY_BOUNDS', 1)
832 if CHECK_CFLAGS(conf
, ["-Wno-error=stringop-overflow"]):
833 conf
.define('HAVE_WNO_ERROR_STRINGOP_OVERFLOW', 1)
835 if CHECK_CFLAGS(conf
, ["-Wno-error=declaration-after-statement"]):
836 conf
.define('HAVE_WNO_ERROR_DECLARATION_AFTER_STATEMENT', 1)
838 if not Options
.options
.disable_warnings_as_errors
:
839 conf
.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags
=True)
840 conf
.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags
=True)
841 conf
.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=cast-align', testflags
=True)
843 if Options
.options
.fatal_errors
:
844 conf
.ADD_CFLAGS('-Wfatal-errors', testflags
=True)
846 if Options
.options
.pedantic
:
847 conf
.ADD_CFLAGS('-W', testflags
=True)
849 if (Options
.options
.address_sanitizer
or
850 Options
.options
.undefined_sanitizer
):
851 conf
.ADD_CFLAGS('-g -O1', testflags
=True)
852 if (Options
.options
.address_sanitizer
853 or Options
.options
.memory_sanitizer
):
854 conf
.ADD_CFLAGS('-fno-omit-frame-pointer', testflags
=True)
855 if Options
.options
.address_sanitizer
:
856 conf
.ADD_CFLAGS('-fsanitize=address', testflags
=True)
857 conf
.ADD_LDFLAGS('-fsanitize=address', testflags
=True)
858 conf
.env
['ADDRESS_SANITIZER'] = True
859 if Options
.options
.undefined_sanitizer
:
860 conf
.ADD_CFLAGS('-fsanitize=undefined', testflags
=True)
861 conf
.ADD_CFLAGS('-fsanitize=null', testflags
=True)
862 conf
.ADD_CFLAGS('-fsanitize=alignment', testflags
=True)
863 conf
.ADD_LDFLAGS('-fsanitize=undefined', testflags
=True)
864 conf
.env
['UNDEFINED_SANITIZER'] = True
866 # MemorySanitizer is only available if you build with clang
867 if Options
.options
.memory_sanitizer
:
868 conf
.ADD_CFLAGS('-g -O2', testflags
=True)
869 conf
.ADD_CFLAGS('-fsanitize=memory', testflags
=True)
870 conf
.ADD_CFLAGS('-fsanitize-memory-track-origins=2', testflags
=True)
871 conf
.ADD_LDFLAGS('-fsanitize=memory')
872 conf
.env
['MEMORY_SANITIZER'] = True
874 # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS}
875 # environment variables which are only used the for final build.
877 # The CFLAGS and LDFLAGS environment variables are also
878 # used for the configure checks which might impact their results.
880 # If these variables don't pass a smoke test, fail the configure
882 conf
.add_os_flags('ADDITIONAL_CFLAGS')
883 if conf
.env
.ADDITIONAL_CFLAGS
:
884 conf
.CHECK_CFLAGS(conf
.env
['ADDITIONAL_CFLAGS'],
886 conf
.env
['EXTRA_CFLAGS'].extend(conf
.env
['ADDITIONAL_CFLAGS'])
888 conf
.add_os_flags('ADDITIONAL_LDFLAGS')
889 if conf
.env
.ADDITIONAL_LDFLAGS
:
890 conf
.CHECK_LDFLAGS(conf
.env
['ADDITIONAL_LDFLAGS'],
892 conf
.env
['EXTRA_LDFLAGS'].extend(conf
.env
['ADDITIONAL_LDFLAGS'])
895 conf
.write_config_header('default/config.h', top
=True, remove
=False)
897 conf
.write_config_header(os
.path
.join(conf
.variant
, path
), remove
=False)
898 for key
in conf
.env
.define_key
:
899 conf
.undefine(key
, from_env
=False)
900 conf
.env
.define_key
= []
901 conf
.SAMBA_CROSS_CHECK_COMPLETE()
905 def CONFIG_PATH(conf
, name
, default
):
906 '''setup a configurable path'''
907 if not name
in conf
.env
:
908 if default
[0] == '/':
909 conf
.env
[name
] = default
911 conf
.env
[name
] = conf
.env
['PREFIX'] + default
914 def ADD_NAMED_CFLAGS(conf
, name
, flags
, testflags
=False, prereq_flags
=None):
915 '''add some CFLAGS to the command line
916 optionally set testflags to ensure all the flags work
918 if prereq_flags
is None:
920 prereq_flags
= TO_LIST(prereq_flags
)
923 for f
in flags
.split():
924 if CHECK_CFLAGS(conf
, [f
] + prereq_flags
):
927 if not name
in conf
.env
:
929 conf
.env
[name
].extend(TO_LIST(flags
))
932 def ADD_CFLAGS(conf
, flags
, testflags
=False, prereq_flags
=None):
933 '''add some CFLAGS to the command line
934 optionally set testflags to ensure all the flags work
936 if prereq_flags
is None:
938 ADD_NAMED_CFLAGS(conf
, 'EXTRA_CFLAGS', flags
, testflags
=testflags
,
939 prereq_flags
=prereq_flags
)
942 def ADD_LDFLAGS(conf
, flags
, testflags
=False):
943 '''add some LDFLAGS to the command line
944 optionally set testflags to ensure all the flags work
946 this will return the flags that are added, if any
950 for f
in flags
.split():
951 if CHECK_LDFLAGS(conf
, f
):
954 if not 'EXTRA_LDFLAGS' in conf
.env
:
955 conf
.env
['EXTRA_LDFLAGS'] = []
956 conf
.env
['EXTRA_LDFLAGS'].extend(TO_LIST(flags
))
961 def ADD_EXTRA_INCLUDES(conf
, includes
):
962 '''add some extra include directories to all builds'''
963 if not 'EXTRA_INCLUDES' in conf
.env
:
964 conf
.env
['EXTRA_INCLUDES'] = []
965 conf
.env
['EXTRA_INCLUDES'].extend(TO_LIST(includes
))
969 def CURRENT_CFLAGS(bld
, target
, cflags
,
970 allow_warnings
=False,
973 '''work out the current flags. local flags are added first'''
976 ret
+= ['-D_SAMBA_HOSTCC_']
977 ret
+= TO_LIST(cflags
)
978 if not 'EXTRA_CFLAGS' in bld
.env
:
981 list = bld
.env
['EXTRA_CFLAGS']
983 if not allow_warnings
and 'PICKY_CFLAGS' in bld
.env
:
984 list = bld
.env
['PICKY_CFLAGS']
986 if hide_symbols
and bld
.env
.HAVE_VISIBILITY_ATTR
:
987 ret
.append(bld
.env
.VISIBILITY_CFLAGS
)
992 def CHECK_CC_ENV(conf
):
993 """trim whitespaces from 'CC'.
994 The build farm sometimes puts a space at the start"""
995 if os
.environ
.get('CC'):
996 conf
.env
.CC
= TO_LIST(os
.environ
.get('CC'))
1000 def SETUP_CONFIGURE_CACHE(conf
, enable
):
1001 '''enable/disable cache of configure results'''
1003 # when -C is chosen, we will use a private cache and will
1004 # not look into system includes. This roughly matches what
1005 # autoconf does with -C
1006 cache_path
= os
.path
.join(conf
.bldnode
.abspath(), '.confcache')
1008 Options
.cache_global
= os
.environ
['WAFCACHE'] = cache_path
1010 # when -C is not chosen we will not cache configure checks
1011 # We set the recursion limit low to prevent waf from spending
1012 # a lot of time on the signatures of the files.
1013 Options
.cache_global
= os
.environ
['WAFCACHE'] = ''
1014 preproc
.recursion_limit
= 1
1015 # in either case we don't need to scan system includes
1016 preproc
.go_absolute
= False
1020 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf
):
1021 if (Options
.options
.address_sanitizer
1022 or Options
.options
.memory_sanitizer
1023 or Options
.options
.enable_libfuzzer
):
1024 # Sanitizers can rely on symbols undefined at library link time and the
1025 # symbols used for fuzzers are only defined by compiler wrappers.
1028 if not sys
.platform
.startswith("openbsd"):
1029 # we don't want any libraries or modules to rely on runtime
1030 # resolution of symbols
1031 conf
.env
.undefined_ldflags
= conf
.ADD_LDFLAGS('-Wl,-no-undefined', testflags
=True)
1033 if (conf
.env
.undefined_ignore_ldflags
== [] and
1034 conf
.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup'])):
1035 conf
.env
.undefined_ignore_ldflags
= ['-undefined', 'dynamic_lookup']