wafsamba: make sure build fails when uninitialized variable is detected
[samba.git] / buildtools / wafsamba / samba_autoconf.py
1 # a waf tool to add autoconf-like macros to the configure section
2
3 import Build, os, sys, Options, preproc, Logs
4 import string
5 from Configure import conf
6 from samba_utils import *
7 import samba_cross
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 @runonce
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('CCDEFINES', d + '=' + str(v))
23
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
34
35
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
43
44     v = getattr(conf.env, 'in_compound', [])
45     if v != [] and v != 0:
46         conf.env.in_compound = v + 1
47         return
48     conf.check_message_1(msg)
49     conf.saved_check_message_1 = conf.check_message_1
50     conf.check_message_1 = null_check_message_1
51     conf.saved_check_message_2 = conf.check_message_2
52     conf.check_message_2 = null_check_message_2
53     conf.env.in_compound = 1
54
55
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.check_message_1 = conf.saved_check_message_1
63     conf.check_message_2 = conf.saved_check_message_2
64     p = conf.check_message_2
65     if result is True:
66         p('ok')
67     elif not result:
68         p('not found', 'YELLOW')
69     else:
70         p(result)
71
72
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
79
80
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
94
95     (ccflags, ldflags, cpppath) = library_flags(conf, lib)
96
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                      ccflags=ccflags,
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             ret = False
233     return ret
234
235
236 def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
237     '''check for a function'''
238     define='HAVE_%s' % f.upper()
239
240     ret = False
241
242     conf.COMPOUND_START('Checking for %s' % f)
243
244     if link is None or link:
245         ret = CHECK_CODE(conf,
246                          # this is based on the autoconf strategy
247                          '''
248                          #define %s __fake__%s
249                          #ifdef HAVE_LIMITS_H
250                          # include <limits.h>
251                          #else
252                          # include <assert.h>
253                          #endif
254                          #undef %s
255                          #if defined __stub_%s || defined __stub___%s
256                          #error "bad glibc stub"
257                          #endif
258                          extern char %s();
259                          int main() { return %s(); }
260                          ''' % (f, f, f, f, f, f, f),
261                          execute=False,
262                          link=True,
263                          addmain=False,
264                          add_headers=False,
265                          define=define,
266                          local_include=False,
267                          lib=lib,
268                          headers=headers,
269                          msg='Checking for %s' % f)
270
271         if not ret:
272             ret = CHECK_CODE(conf,
273                              # it might be a macro
274                              # we need to make sure the compiler doesn't
275                              # optimize it out...
276                              'void *__x = (void *)%s; return (int)__x' % f,
277                              execute=False,
278                              link=True,
279                              addmain=True,
280                              add_headers=True,
281                              define=define,
282                              local_include=False,
283                              lib=lib,
284                              headers=headers,
285                              msg='Checking for macro %s' % f)
286
287     if not ret and (link is None or not link):
288         ret = CHECK_VARIABLE(conf, f,
289                              define=define,
290                              headers=headers,
291                              msg='Checking for declaration of %s' % f)
292     conf.COMPOUND_END(ret)
293     return ret
294
295
296 @conf
297 def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None):
298     '''check for a list of functions'''
299     ret = True
300     for f in TO_LIST(list):
301         if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers):
302             ret = False
303     return ret
304
305
306 @conf
307 def CHECK_SIZEOF(conf, vars, headers=None, define=None, critical=True):
308     '''check the size of a type'''
309     for v in TO_LIST(vars):
310         v_define = define
311         ret = False
312         if v_define is None:
313             v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
314         for size in list((1, 2, 4, 8, 16, 32)):
315             if CHECK_CODE(conf,
316                       'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v, size),
317                       define=v_define,
318                       quote=False,
319                       headers=headers,
320                       local_include=False,
321                       msg="Checking if size of %s == %d" % (v, size)):
322                 conf.DEFINE(v_define, size)
323                 ret = True
324                 break
325         if not ret and critical:
326             Logs.error("Couldn't determine size of '%s'" % v)
327             sys.exit(1)
328     return ret
329
330 @conf
331 def CHECK_VALUEOF(conf, v, headers=None, define=None):
332     '''check the value of a variable/define'''
333     ret = True
334     v_define = define
335     if v_define is None:
336         v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_')
337     if CHECK_CODE(conf,
338                   'printf("%%u", (unsigned)(%s))' % v,
339                   define=v_define,
340                   execute=True,
341                   define_ret=True,
342                   quote=False,
343                   headers=headers,
344                   local_include=False,
345                   msg="Checking value of %s" % v):
346         return int(conf.env[v_define])
347
348     return None
349
350 @conf
351 def CHECK_CODE(conf, code, define,
352                always=False, execute=False, addmain=True,
353                add_headers=True, mandatory=False,
354                headers=None, msg=None, cflags='', includes='# .',
355                local_include=True, lib=None, link=True,
356                define_ret=False, quote=False,
357                on_target=True):
358     '''check if some code compiles and/or runs'''
359
360     if CONFIG_SET(conf, define):
361         return True
362
363     if headers is not None:
364         CHECK_HEADERS(conf, headers=headers, lib=lib)
365
366     if add_headers:
367         hdrs = header_list(conf, headers=headers, lib=lib)
368     else:
369         hdrs = ''
370     if execute:
371         execute = 1
372     else:
373         execute = 0
374
375     defs = conf.get_config_header()
376
377     if addmain:
378         fragment='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs, hdrs, code)
379     else:
380         fragment='%s\n%s\n%s\n' % (defs, hdrs, code)
381
382     if msg is None:
383         msg="Checking for %s" % define
384
385     cflags = TO_LIST(cflags)
386
387     if local_include:
388         cflags.append('-I%s' % conf.curdir)
389
390     if not link:
391         type='nolink'
392     else:
393         type='cprogram'
394
395     uselib = TO_LIST(lib)
396
397     (ccflags, ldflags, cpppath) = library_flags(conf, uselib)
398
399     includes = TO_LIST(includes)
400     includes.extend(cpppath)
401
402     uselib = [l.upper() for l in uselib]
403
404     cflags.extend(ccflags)
405
406     if on_target:
407         exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
408     else:
409         exec_args = []
410
411     conf.COMPOUND_START(msg)
412
413     ret = conf.check(fragment=fragment,
414                      execute=execute,
415                      define_name = define,
416                      mandatory = mandatory,
417                      ccflags=cflags,
418                      ldflags=ldflags,
419                      includes=includes,
420                      uselib=uselib,
421                      type=type,
422                      msg=msg,
423                      quote=quote,
424                      exec_args=exec_args,
425                      define_ret=define_ret)
426     if not ret and CONFIG_SET(conf, define):
427         # sometimes conf.check() returns false, but it
428         # sets the define. Maybe a waf bug?
429         ret = True
430     if ret:
431         if not define_ret:
432             conf.DEFINE(define, 1)
433             conf.COMPOUND_END(True)
434         else:
435             conf.COMPOUND_END(conf.env[define])
436         return True
437     if always:
438         conf.DEFINE(define, 0)
439     conf.COMPOUND_END(False)
440     return False
441
442
443
444 @conf
445 def CHECK_STRUCTURE_MEMBER(conf, structname, member,
446                            always=False, define=None, headers=None):
447     '''check for a structure member'''
448     if define is None:
449         define = 'HAVE_%s' % member.upper()
450     return CHECK_CODE(conf,
451                       '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
452                       define,
453                       execute=False,
454                       link=False,
455                       always=always,
456                       headers=headers,
457                       local_include=False,
458                       msg="Checking for member %s in %s" % (member, structname))
459
460
461 @conf
462 def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'):
463     '''check if the given cflags are accepted by the compiler
464     '''
465     return conf.check(fragment=fragment,
466                       execute=0,
467                       type='nolink',
468                       ccflags=cflags,
469                       msg="Checking compiler accepts %s" % cflags)
470
471 @conf
472 def CHECK_LDFLAGS(conf, ldflags):
473     '''check if the given ldflags are accepted by the linker
474     '''
475     return conf.check(fragment='int main(void) { return 0; }\n',
476                       execute=0,
477                       ldflags=ldflags,
478                       msg="Checking linker accepts %s" % ldflags)
479
480
481 @conf
482 def CONFIG_GET(conf, option):
483     '''return True if a configuration option was found'''
484     if (option in conf.env):
485         return conf.env[option]
486     else:
487         return None
488
489 @conf
490 def CONFIG_SET(conf, option):
491     '''return True if a configuration option was found'''
492     if option not in conf.env:
493         return False
494     v = conf.env[option]
495     if v is None:
496         return False
497     if v == []:
498         return False
499     if v == ():
500         return False
501     return True
502
503 @conf
504 def CONFIG_RESET(conf, option):
505     if option not in conf.env:
506         return
507     del conf.env[option]
508
509 Build.BuildContext.CONFIG_RESET = CONFIG_RESET
510 Build.BuildContext.CONFIG_SET = CONFIG_SET
511 Build.BuildContext.CONFIG_GET = CONFIG_GET
512
513
514 def library_flags(self, libs):
515     '''work out flags from pkg_config'''
516     ccflags = []
517     ldflags = []
518     cpppath = []
519     for lib in TO_LIST(libs):
520         # note that we do not add the -I and -L in here, as that is added by the waf
521         # core. Adding it here would just change the order that it is put on the link line
522         # which can cause system paths to be added before internal libraries
523         extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
524         extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
525         extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), []))
526         ccflags.extend(extra_ccflags)
527         ldflags.extend(extra_ldflags)
528         cpppath.extend(extra_cpppath)
529     if 'EXTRA_LDFLAGS' in self.env:
530         ldflags.extend(self.env['EXTRA_LDFLAGS'])
531
532     ccflags = unique_list(ccflags)
533     ldflags = unique_list(ldflags)
534     cpppath = unique_list(cpppath)
535     return (ccflags, ldflags, cpppath)
536
537
538 @conf
539 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
540     '''check if a set of libraries exist as system libraries
541
542     returns the sublist of libs that do exist as a syslib or []
543     '''
544
545     fragment= '''
546 int foo()
547 {
548     int v = 2;
549     return v*2;
550 }
551 '''
552     ret = []
553     liblist  = TO_LIST(libs)
554     for lib in liblist[:]:
555         if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
556             ret.append(lib)
557             continue
558
559         (ccflags, ldflags, cpppath) = library_flags(conf, lib)
560         if shlib:
561             res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
562         else:
563             res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
564
565         if not res:
566             if mandatory:
567                 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
568                 sys.exit(1)
569             if empty_decl:
570                 # if it isn't a mandatory library, then remove it from dependency lists
571                 if set_target:
572                     SET_TARGET_TYPE(conf, lib, 'EMPTY')
573         else:
574             conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1)
575             conf.env['LIB_' + lib.upper()] = lib
576             if set_target:
577                 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
578             ret.append(lib)
579
580     return ret
581
582
583
584 @conf
585 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
586                    headers=None, link=True, empty_decl=True, set_target=True):
587     """
588     check that the functions in 'list' are available in 'library'
589     if they are, then make that library available as a dependency
590
591     if the library is not available and mandatory==True, then
592     raise an error.
593
594     If the library is not available and mandatory==False, then
595     add the library to the list of dependencies to remove from
596     build rules
597
598     optionally check for the functions first in libc
599     """
600     remaining = TO_LIST(list)
601     liblist   = TO_LIST(library)
602
603     # check if some already found
604     for f in remaining[:]:
605         if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
606             remaining.remove(f)
607
608     # see if the functions are in libc
609     if checklibc:
610         for f in remaining[:]:
611             if CHECK_FUNC(conf, f, link=True, headers=headers):
612                 remaining.remove(f)
613
614     if remaining == []:
615         for lib in liblist:
616             if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
617                 SET_TARGET_TYPE(conf, lib, 'EMPTY')
618         return True
619
620     checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
621     for lib in liblist[:]:
622         if not lib in checklist and mandatory:
623             Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
624             sys.exit(1)
625
626     ret = True
627     for f in remaining:
628         if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
629             ret = False
630
631     return ret
632
633
634 @conf
635 def IN_LAUNCH_DIR(conf):
636     '''return True if this rule is being run from the launch directory'''
637     return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
638 Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
639
640
641 @conf
642 def SAMBA_CONFIG_H(conf, path=None):
643     '''write out config.h in the right directory'''
644     # we don't want to produce a config.h in places like lib/replace
645     # when we are building projects that depend on lib/replace
646     if not IN_LAUNCH_DIR(conf):
647         return
648
649     if conf.CHECK_CFLAGS(['-fstack-protector']) and conf.CHECK_LDFLAGS(['-fstack-protector']):
650         conf.ADD_CFLAGS('-fstack-protector')
651         conf.ADD_LDFLAGS('-fstack-protector')
652
653     if Options.options.debug:
654         conf.ADD_CFLAGS('-g', testflags=True)
655
656     if Options.options.developer:
657         conf.env.DEVELOPER_MODE = True
658
659         conf.ADD_CFLAGS('-g', testflags=True)
660         conf.ADD_CFLAGS('-Wall', testflags=True)
661         conf.ADD_CFLAGS('-Wshadow', testflags=True)
662         conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True)
663         conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True)
664         conf.ADD_CFLAGS('-fno-common', testflags=True)
665
666         conf.ADD_CFLAGS('-Werror=address', testflags=True)
667         # we add these here to ensure that -Wstrict-prototypes is not set during configure
668         conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes',
669                         testflags=True)
670         conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings',
671                         testflags=True)
672         conf.ADD_CFLAGS('-Werror-implicit-function-declaration',
673                         testflags=True)
674         conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith',
675                         testflags=True)
676         conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement',
677                         testflags=True)
678         conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type',
679                         testflags=True)
680         conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized',
681                         testflags=True)
682
683         conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True)
684         # This check is because for ldb_search(), a NULL format string
685         # is not an error, but some compilers complain about that.
686         if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], '''
687 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
688
689 int main(void) {
690         testformat(0);
691         return 0;
692 }
693
694 '''):
695             if not 'EXTRA_CFLAGS' in conf.env:
696                 conf.env['EXTRA_CFLAGS'] = []
697             conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
698
699     if Options.options.picky_developer:
700         conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True)
701
702     if Options.options.fatal_errors:
703         conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
704
705     if Options.options.pedantic:
706         conf.ADD_CFLAGS('-W', testflags=True)
707
708     if Options.options.address_sanitizer:
709         conf.ADD_CFLAGS('-fno-omit-frame-pointer -O1 -fsanitize=address', testflags=True)
710         conf.ADD_LDFLAGS('-fsanitize=address', testflags=True)
711         conf.env['ADDRESS_SANITIZER'] = True
712
713
714     # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS}
715     # environment variables which are only used the for final build.
716     #
717     # The CFLAGS and LDFLAGS environment variables are also
718     # used for the configure checks which might impact their results.
719     conf.add_os_flags('ADDITIONAL_CFLAGS')
720     if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']):
721         conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS'])
722     conf.add_os_flags('ADDITIONAL_LDFLAGS')
723     if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']):
724         conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS'])
725
726     if path is None:
727         conf.write_config_header('config.h', top=True)
728     else:
729         conf.write_config_header(path)
730     conf.SAMBA_CROSS_CHECK_COMPLETE()
731
732
733 @conf
734 def CONFIG_PATH(conf, name, default):
735     '''setup a configurable path'''
736     if not name in conf.env:
737         if default[0] == '/':
738             conf.env[name] = default
739         else:
740             conf.env[name] = conf.env['PREFIX'] + default
741
742 @conf
743 def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False):
744     '''add some CFLAGS to the command line
745        optionally set testflags to ensure all the flags work
746     '''
747     if testflags:
748         ok_flags=[]
749         for f in flags.split():
750             if CHECK_CFLAGS(conf, f):
751                 ok_flags.append(f)
752         flags = ok_flags
753     if not name in conf.env:
754         conf.env[name] = []
755     conf.env[name].extend(TO_LIST(flags))
756
757 @conf
758 def ADD_CFLAGS(conf, flags, testflags=False):
759     '''add some CFLAGS to the command line
760        optionally set testflags to ensure all the flags work
761     '''
762     ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags)
763
764 @conf
765 def ADD_LDFLAGS(conf, flags, testflags=False):
766     '''add some LDFLAGS to the command line
767        optionally set testflags to ensure all the flags work
768
769        this will return the flags that are added, if any
770     '''
771     if testflags:
772         ok_flags=[]
773         for f in flags.split():
774             if CHECK_LDFLAGS(conf, f):
775                 ok_flags.append(f)
776         flags = ok_flags
777     if not 'EXTRA_LDFLAGS' in conf.env:
778         conf.env['EXTRA_LDFLAGS'] = []
779     conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
780     return flags
781
782
783 @conf
784 def ADD_EXTRA_INCLUDES(conf, includes):
785     '''add some extra include directories to all builds'''
786     if not 'EXTRA_INCLUDES' in conf.env:
787         conf.env['EXTRA_INCLUDES'] = []
788     conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
789
790
791
792 def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False):
793     '''work out the current flags. local flags are added first'''
794     ret = TO_LIST(cflags)
795     if not 'EXTRA_CFLAGS' in bld.env:
796         list = []
797     else:
798         list = bld.env['EXTRA_CFLAGS'];
799     ret.extend(list)
800     if not allow_warnings and 'PICKY_CFLAGS' in bld.env:
801         list = bld.env['PICKY_CFLAGS'];
802         ret.extend(list)
803     if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
804         ret.append(bld.env.VISIBILITY_CFLAGS)
805     return ret
806
807
808 @conf
809 def CHECK_CC_ENV(conf):
810     """trim whitespaces from 'CC'.
811     The build farm sometimes puts a space at the start"""
812     if os.environ.get('CC'):
813         conf.env.CC = TO_LIST(os.environ.get('CC'))
814         if len(conf.env.CC) == 1:
815             # make for nicer logs if just a single command
816             conf.env.CC = conf.env.CC[0]
817
818
819 @conf
820 def SETUP_CONFIGURE_CACHE(conf, enable):
821     '''enable/disable cache of configure results'''
822     if enable:
823         # when -C is chosen, we will use a private cache and will
824         # not look into system includes. This roughtly matches what
825         # autoconf does with -C
826         cache_path = os.path.join(conf.blddir, '.confcache')
827         mkdir_p(cache_path)
828         Options.cache_global = os.environ['WAFCACHE'] = cache_path
829     else:
830         # when -C is not chosen we will not cache configure checks
831         # We set the recursion limit low to prevent waf from spending
832         # a lot of time on the signatures of the files.
833         Options.cache_global = os.environ['WAFCACHE'] = ''
834         preproc.recursion_limit = 1
835     # in either case we don't need to scan system includes
836     preproc.go_absolute = False
837
838
839 @conf
840 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
841     # we don't want any libraries or modules to rely on runtime
842     # resolution of symbols
843     if not sys.platform.startswith("openbsd"):
844         conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
845
846     if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
847         if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
848             conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']