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