lib:util: Add (PULL|PUSH)_(BE|LE)_I(8|16|32|64) byterarray macros
[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                            lib=None):
459     '''check for a structure member'''
460     if define is None:
461         define = 'HAVE_%s' % member.upper()
462     return CHECK_CODE(conf,
463                       '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
464                       define,
465                       execute=False,
466                       link=False,
467                       lib=lib,
468                       always=always,
469                       headers=headers,
470                       local_include=False,
471                       msg="Checking for member %s in %s" % (member, structname))
472
473
474 @conf
475 def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'):
476     '''check if the given cflags are accepted by the compiler
477     '''
478     check_cflags = TO_LIST(cflags)
479     if 'WERROR_CFLAGS' in conf.env:
480         check_cflags.extend(conf.env['WERROR_CFLAGS'])
481     return conf.check(fragment=fragment,
482                       execute=0,
483                       type='nolink',
484                       ccflags=check_cflags,
485                       msg="Checking compiler accepts %s" % cflags)
486
487 @conf
488 def CHECK_LDFLAGS(conf, ldflags):
489     '''check if the given ldflags are accepted by the linker
490     '''
491     return conf.check(fragment='int main(void) { return 0; }\n',
492                       execute=0,
493                       ldflags=ldflags,
494                       mandatory=False,
495                       msg="Checking linker accepts %s" % ldflags)
496
497
498 @conf
499 def CONFIG_GET(conf, option):
500     '''return True if a configuration option was found'''
501     if (option in conf.env):
502         return conf.env[option]
503     else:
504         return None
505
506 @conf
507 def CONFIG_SET(conf, option):
508     '''return True if a configuration option was found'''
509     if option not in conf.env:
510         return False
511     v = conf.env[option]
512     if v is None:
513         return False
514     if v == []:
515         return False
516     if v == ():
517         return False
518     return True
519
520 @conf
521 def CONFIG_RESET(conf, option):
522     if option not in conf.env:
523         return
524     del conf.env[option]
525
526 Build.BuildContext.CONFIG_RESET = CONFIG_RESET
527 Build.BuildContext.CONFIG_SET = CONFIG_SET
528 Build.BuildContext.CONFIG_GET = CONFIG_GET
529
530
531 def library_flags(self, libs):
532     '''work out flags from pkg_config'''
533     ccflags = []
534     ldflags = []
535     cpppath = []
536     for lib in TO_LIST(libs):
537         # note that we do not add the -I and -L in here, as that is added by the waf
538         # core. Adding it here would just change the order that it is put on the link line
539         # which can cause system paths to be added before internal libraries
540         extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
541         extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
542         extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), []))
543         ccflags.extend(extra_ccflags)
544         ldflags.extend(extra_ldflags)
545         cpppath.extend(extra_cpppath)
546     if 'EXTRA_LDFLAGS' in self.env:
547         ldflags.extend(self.env['EXTRA_LDFLAGS'])
548
549     ccflags = unique_list(ccflags)
550     ldflags = unique_list(ldflags)
551     cpppath = unique_list(cpppath)
552     return (ccflags, ldflags, cpppath)
553
554
555 @conf
556 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
557     '''check if a set of libraries exist as system libraries
558
559     returns the sublist of libs that do exist as a syslib or []
560     '''
561
562     fragment= '''
563 int foo()
564 {
565     int v = 2;
566     return v*2;
567 }
568 '''
569     ret = []
570     liblist  = TO_LIST(libs)
571     for lib in liblist[:]:
572         if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
573             ret.append(lib)
574             continue
575
576         (ccflags, ldflags, cpppath) = library_flags(conf, lib)
577         if shlib:
578             res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False)
579         else:
580             res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False)
581
582         if not res:
583             if mandatory:
584                 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
585                 sys.exit(1)
586             if empty_decl:
587                 # if it isn't a mandatory library, then remove it from dependency lists
588                 if set_target:
589                     SET_TARGET_TYPE(conf, lib, 'EMPTY')
590         else:
591             conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1)
592             conf.env['LIB_' + lib.upper()] = lib
593             if set_target:
594                 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
595             ret.append(lib)
596
597     return ret
598
599
600
601 @conf
602 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
603                    headers=None, link=True, empty_decl=True, set_target=True):
604     """
605     check that the functions in 'list' are available in 'library'
606     if they are, then make that library available as a dependency
607
608     if the library is not available and mandatory==True, then
609     raise an error.
610
611     If the library is not available and mandatory==False, then
612     add the library to the list of dependencies to remove from
613     build rules
614
615     optionally check for the functions first in libc
616     """
617     remaining = TO_LIST(list)
618     liblist   = TO_LIST(library)
619
620     # check if some already found
621     for f in remaining[:]:
622         if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
623             remaining.remove(f)
624
625     # see if the functions are in libc
626     if checklibc:
627         for f in remaining[:]:
628             if CHECK_FUNC(conf, f, link=True, headers=headers):
629                 remaining.remove(f)
630
631     if remaining == []:
632         for lib in liblist:
633             if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
634                 SET_TARGET_TYPE(conf, lib, 'EMPTY')
635         return True
636
637     checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
638     for lib in liblist[:]:
639         if not lib in checklist and mandatory:
640             Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
641             sys.exit(1)
642
643     ret = True
644     for f in remaining:
645         if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
646             ret = False
647
648     return ret
649
650
651 @conf
652 def IN_LAUNCH_DIR(conf):
653     '''return True if this rule is being run from the launch directory'''
654     return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
655 Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
656
657
658 @conf
659 def SAMBA_CONFIG_H(conf, path=None):
660     '''write out config.h in the right directory'''
661     # we don't want to produce a config.h in places like lib/replace
662     # when we are building projects that depend on lib/replace
663     if not IN_LAUNCH_DIR(conf):
664         return
665
666     # we need to build real code that can't be optimized away to test
667     if conf.check(fragment='''
668         #include <stdio.h>
669
670         int main(void)
671         {
672             char t[100000];
673             while (fgets(t, sizeof(t), stdin));
674             return 0;
675         }
676         ''',
677         execute=0,
678         ccflags='-fstack-protector',
679         ldflags='-fstack-protector',
680         mandatory=False,
681         msg='Checking if toolchain accepts -fstack-protector'):
682             conf.ADD_CFLAGS('-fstack-protector')
683             conf.ADD_LDFLAGS('-fstack-protector')
684
685     if Options.options.debug:
686         conf.ADD_CFLAGS('-g', testflags=True)
687
688     if Options.options.developer:
689         conf.env.DEVELOPER_MODE = True
690
691         conf.ADD_CFLAGS('-g', testflags=True)
692         conf.ADD_CFLAGS('-Wall', testflags=True)
693         conf.ADD_CFLAGS('-Wshadow', testflags=True)
694         conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True)
695         conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True)
696         conf.ADD_CFLAGS('-fno-common', testflags=True)
697
698         conf.ADD_CFLAGS('-Werror=address', testflags=True)
699         # we add these here to ensure that -Wstrict-prototypes is not set during configure
700         conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
701                         testflags=True)
702         conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
703                         testflags=True)
704         conf.ADD_CFLAGS('-Werror-implicit-function-declaration',
705                         testflags=True)
706         conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
707                         testflags=True)
708         conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
709                         testflags=True)
710         conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type',
711                         testflags=True)
712         conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
713                         testflags=True)
714
715         conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
716         conf.ADD_CFLAGS('-Wno-format-zero-length', testflags=True)
717         conf.ADD_CFLAGS('-Werror=format-security -Wformat-security',
718                         testflags=True, prereq_flags='-Wformat')
719         # This check is because for ldb_search(), a NULL format string
720         # is not an error, but some compilers complain about that.
721         if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], '''
722 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
723
724 int main(void) {
725         testformat(0);
726         return 0;
727 }
728
729 '''):
730             if not 'EXTRA_CFLAGS' in conf.env:
731                 conf.env['EXTRA_CFLAGS'] = []
732             conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
733
734     if Options.options.picky_developer:
735         conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True)
736         conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags=True)
737
738     if Options.options.fatal_errors:
739         conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
740
741     if Options.options.pedantic:
742         conf.ADD_CFLAGS('-W', testflags=True)
743
744     if Options.options.address_sanitizer:
745         conf.ADD_CFLAGS('-fno-omit-frame-pointer -O1 -fsanitize=address', testflags=True)
746         conf.ADD_LDFLAGS('-fsanitize=address', testflags=True)
747         conf.env['ADDRESS_SANITIZER'] = True
748
749
750     # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS}
751     # environment variables which are only used the for final build.
752     #
753     # The CFLAGS and LDFLAGS environment variables are also
754     # used for the configure checks which might impact their results.
755     conf.add_os_flags('ADDITIONAL_CFLAGS')
756     if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']):
757         conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS'])
758     conf.add_os_flags('ADDITIONAL_LDFLAGS')
759     if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']):
760         conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS'])
761
762     if path is None:
763         conf.write_config_header('config.h', top=True)
764     else:
765         conf.write_config_header(path)
766     conf.SAMBA_CROSS_CHECK_COMPLETE()
767
768
769 @conf
770 def CONFIG_PATH(conf, name, default):
771     '''setup a configurable path'''
772     if not name in conf.env:
773         if default[0] == '/':
774             conf.env[name] = default
775         else:
776             conf.env[name] = conf.env['PREFIX'] + default
777
778 @conf
779 def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False, prereq_flags=[]):
780     '''add some CFLAGS to the command line
781        optionally set testflags to ensure all the flags work
782     '''
783     prereq_flags = TO_LIST(prereq_flags)
784     if testflags:
785         ok_flags=[]
786         for f in flags.split():
787             if CHECK_CFLAGS(conf, [f] + prereq_flags):
788                 ok_flags.append(f)
789         flags = ok_flags
790     if not name in conf.env:
791         conf.env[name] = []
792     conf.env[name].extend(TO_LIST(flags))
793
794 @conf
795 def ADD_CFLAGS(conf, flags, testflags=False, prereq_flags=[]):
796     '''add some CFLAGS to the command line
797        optionally set testflags to ensure all the flags work
798     '''
799     ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags,
800                      prereq_flags=prereq_flags)
801
802 @conf
803 def ADD_LDFLAGS(conf, flags, testflags=False):
804     '''add some LDFLAGS to the command line
805        optionally set testflags to ensure all the flags work
806
807        this will return the flags that are added, if any
808     '''
809     if testflags:
810         ok_flags=[]
811         for f in flags.split():
812             if CHECK_LDFLAGS(conf, f):
813                 ok_flags.append(f)
814         flags = ok_flags
815     if not 'EXTRA_LDFLAGS' in conf.env:
816         conf.env['EXTRA_LDFLAGS'] = []
817     conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
818     return flags
819
820
821 @conf
822 def ADD_EXTRA_INCLUDES(conf, includes):
823     '''add some extra include directories to all builds'''
824     if not 'EXTRA_INCLUDES' in conf.env:
825         conf.env['EXTRA_INCLUDES'] = []
826     conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
827
828
829
830 def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False):
831     '''work out the current flags. local flags are added first'''
832     ret = TO_LIST(cflags)
833     if not 'EXTRA_CFLAGS' in bld.env:
834         list = []
835     else:
836         list = bld.env['EXTRA_CFLAGS'];
837     ret.extend(list)
838     if not allow_warnings and 'PICKY_CFLAGS' in bld.env:
839         list = bld.env['PICKY_CFLAGS'];
840         ret.extend(list)
841     if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
842         ret.append(bld.env.VISIBILITY_CFLAGS)
843     return ret
844
845
846 @conf
847 def CHECK_CC_ENV(conf):
848     """trim whitespaces from 'CC'.
849     The build farm sometimes puts a space at the start"""
850     if os.environ.get('CC'):
851         conf.env.CC = TO_LIST(os.environ.get('CC'))
852         if len(conf.env.CC) == 1:
853             # make for nicer logs if just a single command
854             conf.env.CC = conf.env.CC[0]
855
856
857 @conf
858 def SETUP_CONFIGURE_CACHE(conf, enable):
859     '''enable/disable cache of configure results'''
860     if enable:
861         # when -C is chosen, we will use a private cache and will
862         # not look into system includes. This roughtly matches what
863         # autoconf does with -C
864         cache_path = os.path.join(conf.blddir, '.confcache')
865         mkdir_p(cache_path)
866         Options.cache_global = os.environ['WAFCACHE'] = cache_path
867     else:
868         # when -C is not chosen we will not cache configure checks
869         # We set the recursion limit low to prevent waf from spending
870         # a lot of time on the signatures of the files.
871         Options.cache_global = os.environ['WAFCACHE'] = ''
872         preproc.recursion_limit = 1
873     # in either case we don't need to scan system includes
874     preproc.go_absolute = False
875
876
877 @conf
878 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
879     # we don't want any libraries or modules to rely on runtime
880     # resolution of symbols
881     if not sys.platform.startswith("openbsd"):
882         conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
883
884     if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
885         if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
886             conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']
887
888 @conf
889 def CHECK_CFG(self, *k, **kw):
890     return self.check_cfg(*k, **kw)