wafsamba: Do not always set _FORTIFY_SOURCE=2
[Samba.git] / buildtools / wafsamba / samba_autoconf.py
blob58800d243512fac59425e1bca0d3b24fe5f8631e
1 # a waf tool to add autoconf-like macros to the configure section
3 import os, sys
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
15 # m4 files
17 @conf
18 def DEFINE(conf, d, v, add_to_cflags=False, quote=False):
19 '''define a config option'''
20 conf.define(d, v, quote=quote)
21 if add_to_cflags:
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 hdrs=''
27 hlist = conf.env.hlist
28 if headers:
29 hlist = hlist[:]
30 hlist.extend(TO_LIST(headers))
31 for h in hlist:
32 hdrs += '#include <%s>\n' % h
33 return hdrs
36 @conf
37 def COMPOUND_START(conf, msg):
38 '''start a compound test'''
39 def null_check_message_1(self,*k,**kw):
40 return
41 def null_check_message_2(self,*k,**kw):
42 return
44 v = getattr(conf.env, 'in_compound', [])
45 if v != [] and v != 0:
46 conf.env.in_compound = v + 1
47 return
48 conf.start_msg(msg)
49 conf.saved_check_message_1 = conf.start_msg
50 conf.start_msg = null_check_message_1
51 conf.saved_check_message_2 = conf.end_msg
52 conf.end_msg = null_check_message_2
53 conf.env.in_compound = 1
56 @conf
57 def COMPOUND_END(conf, result):
58 '''start a compound test'''
59 conf.env.in_compound -= 1
60 if conf.env.in_compound != 0:
61 return
62 conf.start_msg = conf.saved_check_message_1
63 conf.end_msg = conf.saved_check_message_2
64 p = conf.end_msg
65 if result is True:
66 p('ok')
67 elif not result:
68 p('not found', 'YELLOW')
69 else:
70 p(result)
73 @feature('nolink')
74 def nolink(self):
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'''
78 pass
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:
84 return False
85 d = h.upper().replace('/', '_')
86 d = d.replace('.', '_')
87 d = d.replace('-', '_')
88 d = 'HAVE_%s' % d
89 if CONFIG_SET(conf, d):
90 if add_headers:
91 if not h in conf.env.hlist:
92 conf.env.hlist.append(h)
93 return True
95 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
97 hdrs = hlist_to_string(conf, headers=h)
98 if lib is None:
99 lib = ""
100 ret = conf.check(fragment='%s\nint main(void) { return 0; }' % hdrs,
101 type='nolink',
102 execute=0,
103 cflags=ccflags,
104 mandatory=False,
105 includes=cpppath,
106 uselib=lib.upper(),
107 msg="Checking for header %s" % h)
108 if not ret:
109 missing_headers.add(h)
110 return False
112 conf.DEFINE(d, 1)
113 if add_headers and not h in conf.env.hlist:
114 conf.env.hlist.append(h)
115 return ret
118 @conf
119 def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None):
120 '''check for a list of headers
122 when together==True, then the headers accumulate within this test.
123 This is useful for interdependent headers
125 ret = True
126 if not add_headers and together:
127 saved_hlist = conf.env.hlist[:]
128 set_add_headers = True
129 else:
130 set_add_headers = add_headers
131 for hdr in TO_LIST(headers):
132 if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib):
133 ret = False
134 if not add_headers and together:
135 conf.env.hlist = saved_hlist
136 return ret
139 def header_list(conf, headers=None, lib=None):
140 '''form a list of headers which exist, as a string'''
141 hlist=[]
142 if headers is not None:
143 for h in TO_LIST(headers):
144 if CHECK_HEADER(conf, h, add_headers=False, lib=lib):
145 hlist.append(h)
146 return hlist_to_string(conf, headers=hlist)
149 @conf
150 def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None):
151 '''check for a single type'''
152 if define is None:
153 define = 'HAVE_' + t.upper().replace(' ', '_')
154 if msg is None:
155 msg='Checking for %s' % t
156 ret = CHECK_CODE(conf, '%s _x' % t,
157 define,
158 execute=False,
159 headers=headers,
160 local_include=False,
161 msg=msg,
162 lib=lib,
163 link=False)
164 if not ret and alternate:
165 conf.DEFINE(t, alternate)
166 return ret
169 @conf
170 def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None):
171 '''check for a list of types'''
172 ret = True
173 for t in TO_LIST(list):
174 if not CHECK_TYPE(conf, t, headers=headers,
175 define=define, alternate=alternate, lib=lib):
176 ret = False
177 return ret
180 @conf
181 def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None):
182 '''check for a single type with a header'''
183 return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define)
186 @conf
187 def CHECK_VARIABLE(conf, v, define=None, always=False,
188 headers=None, msg=None, lib=None):
189 '''check for a variable declaration (or define)'''
190 if define is None:
191 define = 'HAVE_%s' % v.upper()
193 if msg is None:
194 msg="Checking for variable %s" % v
196 return CHECK_CODE(conf,
197 # we need to make sure the compiler doesn't
198 # optimize it out...
200 #ifndef %s
201 void *_x; _x=(void *)&%s; return (int)_x;
202 #endif
203 return 0
204 ''' % (v, v),
205 execute=False,
206 link=False,
207 msg=msg,
208 local_include=False,
209 lib=lib,
210 headers=headers,
211 define=define,
212 always=always)
215 @conf
216 def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False):
217 '''check a list of variable declarations, using the HAVE_DECL_xxx form
218 of define
220 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
222 ret = True
223 for v in TO_LIST(vars):
224 if not reverse:
225 define='HAVE_DECL_%s' % v.upper()
226 else:
227 define='HAVE_%s_DECL' % v.upper()
228 if not CHECK_VARIABLE(conf, v,
229 define=define,
230 headers=headers,
231 msg='Checking for declaration of %s' % v,
232 always=always):
233 if not CHECK_CODE(conf,
235 return (int)%s;
236 ''' % (v),
237 execute=False,
238 link=False,
239 msg='Checking for declaration of %s (as enum)' % v,
240 local_include=False,
241 headers=headers,
242 define=define,
243 always=always):
244 ret = False
245 return ret
248 def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
249 '''check for a function'''
250 define='HAVE_%s' % f.upper()
252 ret = False
254 conf.COMPOUND_START('Checking for %s' % f)
256 if link is None or link:
257 ret = CHECK_CODE(conf,
258 # this is based on the autoconf strategy
260 #define %s __fake__%s
261 #ifdef HAVE_LIMITS_H
262 # include <limits.h>
263 #else
264 # include <assert.h>
265 #endif
266 #undef %s
267 #if defined __stub_%s || defined __stub___%s
268 #error "bad glibc stub"
269 #endif
270 extern char %s();
271 int main() { return %s(); }
272 ''' % (f, f, f, f, f, f, f),
273 execute=False,
274 link=True,
275 addmain=False,
276 add_headers=False,
277 define=define,
278 local_include=False,
279 lib=lib,
280 headers=headers,
281 msg='Checking for %s' % f)
283 if not ret:
284 ret = CHECK_CODE(conf,
285 # it might be a macro
286 # we need to make sure the compiler doesn't
287 # optimize it out...
288 'void *__x = (void *)%s; return (int)__x' % f,
289 execute=False,
290 link=True,
291 addmain=True,
292 add_headers=True,
293 define=define,
294 local_include=False,
295 lib=lib,
296 headers=headers,
297 msg='Checking for macro %s' % f)
299 if not ret and (link is None or not link):
300 ret = CHECK_VARIABLE(conf, f,
301 define=define,
302 headers=headers,
303 msg='Checking for declaration of %s' % f)
304 conf.COMPOUND_END(ret)
305 return ret
308 @conf
309 def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None):
310 '''check for a list of functions'''
311 ret = True
312 for f in TO_LIST(list):
313 if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers):
314 ret = False
315 return ret
318 @conf
319 def CHECK_SIZEOF(conf, vars, headers=None, define=None, critical=True):
320 '''check the size of a type'''
321 for v in TO_LIST(vars):
322 v_define = define
323 ret = False
324 if v_define is None:
325 v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
326 for size in list((1, 2, 4, 8, 16, 32)):
327 if CHECK_CODE(conf,
328 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v, size),
329 define=v_define,
330 quote=False,
331 headers=headers,
332 local_include=False,
333 msg="Checking if size of %s == %d" % (v, size)):
334 conf.DEFINE(v_define, size)
335 ret = True
336 break
337 if not ret and critical:
338 Logs.error("Couldn't determine size of '%s'" % v)
339 sys.exit(1)
340 return ret
342 @conf
343 def CHECK_VALUEOF(conf, v, headers=None, define=None):
344 '''check the value of a variable/define'''
345 ret = True
346 v_define = define
347 if v_define is None:
348 v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_')
349 if CHECK_CODE(conf,
350 'printf("%%u", (unsigned)(%s))' % v,
351 define=v_define,
352 execute=True,
353 define_ret=True,
354 quote=False,
355 headers=headers,
356 local_include=False,
357 msg="Checking value of %s" % v):
358 return int(conf.env[v_define])
360 return None
362 @conf
363 def CHECK_CODE(conf, code, define,
364 always=False, execute=False, addmain=True,
365 add_headers=True, mandatory=False,
366 headers=None, msg=None, cflags='', includes='# .',
367 local_include=True, lib=None, link=True,
368 define_ret=False, quote=False,
369 on_target=True, strict=False):
370 '''check if some code compiles and/or runs'''
372 if CONFIG_SET(conf, define):
373 return True
375 if headers is not None:
376 CHECK_HEADERS(conf, headers=headers, lib=lib)
378 if add_headers:
379 hdrs = header_list(conf, headers=headers, lib=lib)
380 else:
381 hdrs = ''
382 if execute:
383 execute = 1
384 else:
385 execute = 0
387 if addmain:
388 fragment='%s\n int main(void) { %s; return 0; }\n' % (hdrs, code)
389 else:
390 fragment='%s\n%s\n' % (hdrs, code)
392 if msg is None:
393 msg="Checking for %s" % define
395 cflags = TO_LIST(cflags)
397 # Be strict when relying on a compiler check
398 # Some compilers (e.g. xlc) ignore non-supported features as warnings
399 if strict:
400 extra_cflags = None
401 if conf.env["CC_NAME"] == "gcc":
402 extra_cflags = "-Werror"
403 elif conf.env["CC_NAME"] == "xlc":
404 extra_cflags = "-qhalt=w"
405 if extra_cflags:
406 cflags.append(extra_cflags)
408 if local_include:
409 cflags.append('-I%s' % conf.path.abspath())
411 if not link:
412 type='nolink'
413 else:
414 type='cprogram'
416 uselib = TO_LIST(lib)
418 (ccflags, ldflags, cpppath) = library_flags(conf, uselib)
420 includes = TO_LIST(includes)
421 includes.extend(cpppath)
423 uselib = [l.upper() for l in uselib]
425 cflags.extend(ccflags)
427 if on_target:
428 exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
429 else:
430 exec_args = []
432 conf.COMPOUND_START(msg)
434 try:
435 ret = conf.check(fragment=fragment,
436 execute=execute,
437 define_name = define,
438 cflags=cflags,
439 ldflags=ldflags,
440 includes=includes,
441 uselib=uselib,
442 type=type,
443 msg=msg,
444 quote=quote,
445 exec_args=exec_args,
446 define_ret=define_ret)
447 except Exception:
448 if always:
449 conf.DEFINE(define, 0)
450 else:
451 conf.undefine(define)
452 conf.COMPOUND_END(False)
453 if mandatory:
454 raise
455 return False
456 else:
457 # Success is indicated by ret but we should unset
458 # defines set by WAF's c_config.check() because it
459 # defines it to int(ret) and we want to undefine it
460 if not ret:
461 conf.undefine(define)
462 conf.COMPOUND_END(False)
463 return False
464 if not define_ret:
465 conf.DEFINE(define, 1)
466 conf.COMPOUND_END(True)
467 else:
468 conf.DEFINE(define, ret, quote=quote)
469 conf.COMPOUND_END(ret)
470 return True
473 @conf
474 def CHECK_STRUCTURE_MEMBER(conf, structname, member,
475 always=False, define=None, headers=None,
476 lib=None):
477 '''check for a structure member'''
478 if define is None:
479 define = 'HAVE_%s' % member.upper()
480 return CHECK_CODE(conf,
481 '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
482 define,
483 execute=False,
484 link=False,
485 lib=lib,
486 always=always,
487 headers=headers,
488 local_include=False,
489 msg="Checking for member %s in %s" % (member, structname))
492 @conf
493 def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'):
494 '''check if the given cflags are accepted by the compiler
496 check_cflags = TO_LIST(cflags)
497 if 'WERROR_CFLAGS' in conf.env:
498 check_cflags.extend(conf.env['WERROR_CFLAGS'])
499 return conf.check(fragment=fragment,
500 execute=0,
501 mandatory=False,
502 type='nolink',
503 cflags=check_cflags,
504 msg="Checking compiler accepts %s" % cflags)
506 @conf
507 def CHECK_LDFLAGS(conf, ldflags):
508 '''check if the given ldflags are accepted by the linker
510 return conf.check(fragment='int main(void) { return 0; }\n',
511 execute=0,
512 ldflags=ldflags,
513 mandatory=False,
514 msg="Checking linker accepts %s" % ldflags)
517 @conf
518 def CONFIG_GET(conf, option):
519 '''return True if a configuration option was found'''
520 if (option in conf.env):
521 return conf.env[option]
522 else:
523 return None
525 @conf
526 def CONFIG_SET(conf, option):
527 '''return True if a configuration option was found'''
528 if option not in conf.env:
529 return False
530 v = conf.env[option]
531 if v is None:
532 return False
533 if v == []:
534 return False
535 if v == ():
536 return False
537 return True
539 @conf
540 def CONFIG_RESET(conf, option):
541 if option not in conf.env:
542 return
543 del conf.env[option]
545 Build.BuildContext.CONFIG_RESET = CONFIG_RESET
546 Build.BuildContext.CONFIG_SET = CONFIG_SET
547 Build.BuildContext.CONFIG_GET = CONFIG_GET
550 def library_flags(self, libs):
551 '''work out flags from pkg_config'''
552 ccflags = []
553 ldflags = []
554 cpppath = []
555 for lib in TO_LIST(libs):
556 # note that we do not add the -I and -L in here, as that is added by the waf
557 # core. Adding it here would just change the order that it is put on the link line
558 # which can cause system paths to be added before internal libraries
559 extra_ccflags = TO_LIST(getattr(self.env, 'CFLAGS_%s' % lib.upper(), []))
560 extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
561 extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), []))
562 ccflags.extend(extra_ccflags)
563 ldflags.extend(extra_ldflags)
564 cpppath.extend(extra_cpppath)
566 extra_cpppath = TO_LIST(getattr(self.env, 'INCLUDES_%s' % lib.upper(), []))
567 cpppath.extend(extra_cpppath)
568 if 'EXTRA_LDFLAGS' in self.env:
569 ldflags.extend(self.env['EXTRA_LDFLAGS'])
571 ccflags = unique_list(ccflags)
572 ldflags = unique_list(ldflags)
573 cpppath = unique_list(cpppath)
574 return (ccflags, ldflags, cpppath)
577 @conf
578 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
579 '''check if a set of libraries exist as system libraries
581 returns the sublist of libs that do exist as a syslib or []
584 fragment= '''
585 int foo()
587 int v = 2;
588 return v*2;
591 ret = []
592 liblist = TO_LIST(libs)
593 for lib in liblist[:]:
594 if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
595 ret.append(lib)
596 continue
598 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
599 if shlib:
600 res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False)
601 else:
602 res = conf.check(lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False)
604 if not res:
605 if mandatory:
606 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
607 sys.exit(1)
608 if empty_decl:
609 # if it isn't a mandatory library, then remove it from dependency lists
610 if set_target:
611 SET_TARGET_TYPE(conf, lib, 'EMPTY')
612 else:
613 conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1)
614 conf.env['LIB_' + lib.upper()] = lib
615 if set_target:
616 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
617 ret.append(lib)
619 return ret
623 @conf
624 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
625 headers=None, link=True, empty_decl=True, set_target=True):
627 check that the functions in 'list' are available in 'library'
628 if they are, then make that library available as a dependency
630 if the library is not available and mandatory==True, then
631 raise an error.
633 If the library is not available and mandatory==False, then
634 add the library to the list of dependencies to remove from
635 build rules
637 optionally check for the functions first in libc
639 remaining = TO_LIST(list)
640 liblist = TO_LIST(library)
642 # check if some already found
643 for f in remaining[:]:
644 if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
645 remaining.remove(f)
647 # see if the functions are in libc
648 if checklibc:
649 for f in remaining[:]:
650 if CHECK_FUNC(conf, f, link=True, headers=headers):
651 remaining.remove(f)
653 if remaining == []:
654 for lib in liblist:
655 if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
656 SET_TARGET_TYPE(conf, lib, 'EMPTY')
657 return True
659 checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
660 for lib in liblist[:]:
661 if not lib in checklist and mandatory:
662 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
663 sys.exit(1)
665 ret = True
666 for f in remaining:
667 if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
668 ret = False
670 return ret
673 @conf
674 def IN_LAUNCH_DIR(conf):
675 '''return True if this rule is being run from the launch directory'''
676 return os.path.realpath(conf.path.abspath()) == os.path.realpath(Context.launch_dir)
677 Options.OptionsContext.IN_LAUNCH_DIR = IN_LAUNCH_DIR
680 @conf
681 def SAMBA_CONFIG_H(conf, path=None):
682 '''write out config.h in the right directory'''
683 # we don't want to produce a config.h in places like lib/replace
684 # when we are building projects that depend on lib/replace
685 if not IN_LAUNCH_DIR(conf):
686 return
688 # we need to build real code that can't be optimized away to test
689 stack_protect_list = ['-fstack-protector-strong', '-fstack-protector']
690 for stack_protect_flag in stack_protect_list:
691 flag_supported = conf.check(fragment='''
692 #include <stdio.h>
694 int main(void)
696 char t[100000];
697 while (fgets(t, sizeof(t), stdin));
698 return 0;
700 ''',
701 execute=0,
702 cflags=[ '-Werror', '-Wp,-D_FORTIFY_SOURCE=2', stack_protect_flag],
703 mandatory=False,
704 msg='Checking if compiler accepts %s' % (stack_protect_flag))
705 if flag_supported:
706 conf.ADD_CFLAGS('%s' % (stack_protect_flag))
707 break
709 flag_supported = conf.check(fragment='''
710 #include <stdio.h>
712 int main(void)
714 char t[100000];
715 while (fgets(t, sizeof(t), stdin));
716 return 0;
718 ''',
719 execute=0,
720 cflags=[ '-Werror', '-fstack-clash-protection'],
721 mandatory=False,
722 msg='Checking if compiler accepts -fstack-clash-protection')
723 if flag_supported:
724 conf.ADD_CFLAGS('-fstack-clash-protection')
726 if Options.options.debug:
727 conf.ADD_CFLAGS('-g', testflags=True)
729 if Options.options.developer:
730 conf.env.DEVELOPER_MODE = True
732 conf.ADD_CFLAGS('-g', testflags=True)
733 conf.ADD_CFLAGS('-Wall', testflags=True)
734 conf.ADD_CFLAGS('-Wshadow', testflags=True)
735 conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True)
736 conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True)
737 conf.ADD_CFLAGS('-fno-common', testflags=True)
739 conf.ADD_CFLAGS('-Werror=address', testflags=True)
740 # we add these here to ensure that -Wstrict-prototypes is not set during configure
741 conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
742 testflags=True)
743 conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
744 testflags=True)
745 conf.ADD_CFLAGS('-Werror-implicit-function-declaration',
746 testflags=True)
747 conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
748 testflags=True)
749 conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
750 testflags=True)
751 conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type',
752 testflags=True)
753 conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
754 testflags=True)
755 conf.ADD_CFLAGS('-Wimplicit-fallthrough',
756 testflags=True)
757 conf.ADD_CFLAGS('-Werror=strict-overflow -Wstrict-overflow=2',
758 testflags=True)
760 conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
761 conf.ADD_CFLAGS('-Wno-format-zero-length', testflags=True)
762 conf.ADD_CFLAGS('-Werror=format-security -Wformat-security',
763 testflags=True, prereq_flags='-Wformat')
764 # This check is because for ldb_search(), a NULL format string
765 # is not an error, but some compilers complain about that.
766 if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], '''
767 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
769 int main(void) {
770 testformat(0);
771 return 0;
774 '''):
775 if not 'EXTRA_CFLAGS' in conf.env:
776 conf.env['EXTRA_CFLAGS'] = []
777 conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
779 if Options.options.picky_developer:
780 conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True)
781 conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags=True)
783 if Options.options.fatal_errors:
784 conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
786 if Options.options.pedantic:
787 conf.ADD_CFLAGS('-W', testflags=True)
789 if Options.options.address_sanitizer:
790 conf.ADD_CFLAGS('-fno-omit-frame-pointer -O1 -fsanitize=address', testflags=True)
791 conf.ADD_LDFLAGS('-fsanitize=address', testflags=True)
792 conf.env['ADDRESS_SANITIZER'] = True
795 # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS}
796 # environment variables which are only used the for final build.
798 # The CFLAGS and LDFLAGS environment variables are also
799 # used for the configure checks which might impact their results.
800 conf.add_os_flags('ADDITIONAL_CFLAGS')
801 if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']):
802 conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS'])
803 conf.add_os_flags('ADDITIONAL_LDFLAGS')
804 if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']):
805 conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS'])
807 if path is None:
808 conf.write_config_header('default/config.h', top=True, remove=False)
809 else:
810 conf.write_config_header(os.path.join(conf.variant, path), remove=False)
811 for key in conf.env.define_key:
812 conf.undefine(key, from_env=False)
813 conf.env.define_key = []
814 conf.SAMBA_CROSS_CHECK_COMPLETE()
817 @conf
818 def CONFIG_PATH(conf, name, default):
819 '''setup a configurable path'''
820 if not name in conf.env:
821 if default[0] == '/':
822 conf.env[name] = default
823 else:
824 conf.env[name] = conf.env['PREFIX'] + default
826 @conf
827 def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False, prereq_flags=[]):
828 '''add some CFLAGS to the command line
829 optionally set testflags to ensure all the flags work
831 prereq_flags = TO_LIST(prereq_flags)
832 if testflags:
833 ok_flags=[]
834 for f in flags.split():
835 if CHECK_CFLAGS(conf, [f] + prereq_flags):
836 ok_flags.append(f)
837 flags = ok_flags
838 if not name in conf.env:
839 conf.env[name] = []
840 conf.env[name].extend(TO_LIST(flags))
842 @conf
843 def ADD_CFLAGS(conf, flags, testflags=False, prereq_flags=[]):
844 '''add some CFLAGS to the command line
845 optionally set testflags to ensure all the flags work
847 ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags,
848 prereq_flags=prereq_flags)
850 @conf
851 def ADD_LDFLAGS(conf, flags, testflags=False):
852 '''add some LDFLAGS to the command line
853 optionally set testflags to ensure all the flags work
855 this will return the flags that are added, if any
857 if testflags:
858 ok_flags=[]
859 for f in flags.split():
860 if CHECK_LDFLAGS(conf, f):
861 ok_flags.append(f)
862 flags = ok_flags
863 if not 'EXTRA_LDFLAGS' in conf.env:
864 conf.env['EXTRA_LDFLAGS'] = []
865 conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
866 return flags
869 @conf
870 def ADD_EXTRA_INCLUDES(conf, includes):
871 '''add some extra include directories to all builds'''
872 if not 'EXTRA_INCLUDES' in conf.env:
873 conf.env['EXTRA_INCLUDES'] = []
874 conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
878 def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False):
879 '''work out the current flags. local flags are added first'''
880 ret = TO_LIST(cflags)
881 if not 'EXTRA_CFLAGS' in bld.env:
882 list = []
883 else:
884 list = bld.env['EXTRA_CFLAGS'];
885 ret.extend(list)
886 if not allow_warnings and 'PICKY_CFLAGS' in bld.env:
887 list = bld.env['PICKY_CFLAGS'];
888 ret.extend(list)
889 if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
890 ret.append(bld.env.VISIBILITY_CFLAGS)
891 return ret
894 @conf
895 def CHECK_CC_ENV(conf):
896 """trim whitespaces from 'CC'.
897 The build farm sometimes puts a space at the start"""
898 if os.environ.get('CC'):
899 conf.env.CC = TO_LIST(os.environ.get('CC'))
902 @conf
903 def SETUP_CONFIGURE_CACHE(conf, enable):
904 '''enable/disable cache of configure results'''
905 if enable:
906 # when -C is chosen, we will use a private cache and will
907 # not look into system includes. This roughtly matches what
908 # autoconf does with -C
909 cache_path = os.path.join(conf.bldnode.abspath(), '.confcache')
910 mkdir_p(cache_path)
911 Options.cache_global = os.environ['WAFCACHE'] = cache_path
912 else:
913 # when -C is not chosen we will not cache configure checks
914 # We set the recursion limit low to prevent waf from spending
915 # a lot of time on the signatures of the files.
916 Options.cache_global = os.environ['WAFCACHE'] = ''
917 preproc.recursion_limit = 1
918 # in either case we don't need to scan system includes
919 preproc.go_absolute = False
922 @conf
923 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
924 # we don't want any libraries or modules to rely on runtime
925 # resolution of symbols
926 if not sys.platform.startswith("openbsd"):
927 conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
929 if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
930 if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
931 conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']