s3-auth: Do not leak tmp_ctx if make_server_info() fails.
[Samba.git] / buildtools / wafsamba / samba_autoconf.py
blobe14f9cd321e789f4145be53496aaffeefe41e00f
1 # a waf tool to add autoconf-like macros to the configure section
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
9 missing_headers = set()
11 ####################################################
12 # some autoconf like helpers, to make the transition
13 # to waf a bit easier for those used to autoconf
14 # m4 files
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))
24 def hlist_to_string(conf, headers=None):
25 '''convert a headers list to a set of #include lines'''
26 hdrs=''
27 hlist = conf.env.hlist
28 if headers:
29 hlist = hlist[:]
30 hlist.extend(TO_LIST(headers))
31 for h in hlist:
32 hdrs += '#include <%s>\n' % h
33 return hdrs
36 @conf
37 def COMPOUND_START(conf, msg):
38 '''start a compound test'''
39 def null_check_message_1(self,*k,**kw):
40 return
41 def null_check_message_2(self,*k,**kw):
42 return
44 v = getattr(conf.env, 'in_compound', [])
45 if v != [] and v != 0:
46 conf.env.in_compound = v + 1
47 return
48 conf.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
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)
73 @feature('nolink')
74 def nolink(self):
75 '''using the nolink type in conf.check() allows us to avoid
76 the link stage of a test, thus speeding it up for tests
77 that where linking is not needed'''
78 pass
81 def CHECK_HEADER(conf, h, add_headers=False, lib=None):
82 '''check for a header'''
83 if h in missing_headers and lib is None:
84 return False
85 d = h.upper().replace('/', '_')
86 d = d.replace('.', '_')
87 d = d.replace('-', '_')
88 d = 'HAVE_%s' % d
89 if CONFIG_SET(conf, d):
90 if add_headers:
91 if not h in conf.env.hlist:
92 conf.env.hlist.append(h)
93 return True
95 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
97 hdrs = hlist_to_string(conf, headers=h)
98 if lib is None:
99 lib = ""
100 ret = conf.check(fragment='%s\nint main(void) { return 0; }' % hdrs,
101 type='nolink',
102 execute=0,
103 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
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
117 @conf
118 def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None):
119 '''check for a list of headers
121 when together==True, then the headers accumulate within this test.
122 This is useful for interdependent headers
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
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)
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
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
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)
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()
192 if msg is None:
193 msg="Checking for variable %s" % v
195 return CHECK_CODE(conf,
196 # we need to make sure the compiler doesn't
197 # optimize it out...
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)
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
219 When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx
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
236 def CHECK_FUNC(conf, f, link=True, lib=None, headers=None):
237 '''check for a function'''
238 define='HAVE_%s' % f.upper()
240 ret = False
242 conf.COMPOUND_START('Checking for %s' % f)
244 if link is None or link:
245 ret = CHECK_CODE(conf,
246 # this is based on the autoconf strategy
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)
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)
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
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
306 @conf
307 def CHECK_SIZEOF(conf, vars, headers=None, define=None):
308 '''check the size of a type'''
309 ret = True
310 for v in TO_LIST(vars):
311 v_define = define
312 if v_define is None:
313 v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_')
314 if not CHECK_CODE(conf,
315 'printf("%%u", (unsigned)sizeof(%s))' % v,
316 define=v_define,
317 execute=True,
318 define_ret=True,
319 quote=False,
320 headers=headers,
321 local_include=False,
322 msg="Checking size of %s" % v):
323 ret = False
324 return ret
326 @conf
327 def CHECK_VALUEOF(conf, v, headers=None, define=None):
328 '''check the value of a variable/define'''
329 ret = True
330 v_define = define
331 if v_define is None:
332 v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_')
333 if CHECK_CODE(conf,
334 'printf("%%u", (unsigned)(%s))' % v,
335 define=v_define,
336 execute=True,
337 define_ret=True,
338 quote=False,
339 headers=headers,
340 local_include=False,
341 msg="Checking value of %s" % v):
342 return int(conf.env[v_define])
344 return None
346 @conf
347 def CHECK_CODE(conf, code, define,
348 always=False, execute=False, addmain=True,
349 add_headers=True, mandatory=False,
350 headers=None, msg=None, cflags='', includes='# .',
351 local_include=True, lib=None, link=True,
352 define_ret=False, quote=False,
353 on_target=True):
354 '''check if some code compiles and/or runs'''
356 if CONFIG_SET(conf, define):
357 return True
359 if headers is not None:
360 CHECK_HEADERS(conf, headers=headers, lib=lib)
362 if add_headers:
363 hdrs = header_list(conf, headers=headers, lib=lib)
364 else:
365 hdrs = ''
366 if execute:
367 execute = 1
368 else:
369 execute = 0
371 defs = conf.get_config_header()
373 if addmain:
374 fragment='%s\n%s\n int main(void) { %s; return 0; }\n' % (defs, hdrs, code)
375 else:
376 fragment='%s\n%s\n%s\n' % (defs, hdrs, code)
378 if msg is None:
379 msg="Checking for %s" % define
381 cflags = TO_LIST(cflags)
383 if local_include:
384 cflags.append('-I%s' % conf.curdir)
386 if not link:
387 type='nolink'
388 else:
389 type='cprogram'
391 uselib = TO_LIST(lib)
393 (ccflags, ldflags, cpppath) = library_flags(conf, uselib)
395 includes = TO_LIST(includes)
396 includes.extend(cpppath)
398 uselib = [l.upper() for l in uselib]
400 cflags.extend(ccflags)
402 if on_target:
403 exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
404 else:
405 exec_args = []
407 conf.COMPOUND_START(msg)
409 ret = conf.check(fragment=fragment,
410 execute=execute,
411 define_name = define,
412 mandatory = mandatory,
413 ccflags=cflags,
414 ldflags=ldflags,
415 includes=includes,
416 uselib=uselib,
417 type=type,
418 msg=msg,
419 quote=quote,
420 exec_args=exec_args,
421 define_ret=define_ret)
422 if not ret and CONFIG_SET(conf, define):
423 # sometimes conf.check() returns false, but it
424 # sets the define. Maybe a waf bug?
425 ret = True
426 if ret:
427 if not define_ret:
428 conf.DEFINE(define, 1)
429 conf.COMPOUND_END(True)
430 else:
431 conf.COMPOUND_END(conf.env[define])
432 return True
433 if always:
434 conf.DEFINE(define, 0)
435 conf.COMPOUND_END(False)
436 return False
440 @conf
441 def CHECK_STRUCTURE_MEMBER(conf, structname, member,
442 always=False, define=None, headers=None):
443 '''check for a structure member'''
444 if define is None:
445 define = 'HAVE_%s' % member.upper()
446 return CHECK_CODE(conf,
447 '%s s; void *_x; _x=(void *)&s.%s' % (structname, member),
448 define,
449 execute=False,
450 link=False,
451 always=always,
452 headers=headers,
453 local_include=False,
454 msg="Checking for member %s in %s" % (member, structname))
457 @conf
458 def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'):
459 '''check if the given cflags are accepted by the compiler
461 return conf.check(fragment=fragment,
462 execute=0,
463 type='nolink',
464 ccflags=cflags,
465 msg="Checking compiler accepts %s" % cflags)
467 @conf
468 def CHECK_LDFLAGS(conf, ldflags):
469 '''check if the given ldflags are accepted by the linker
471 return conf.check(fragment='int main(void) { return 0; }\n',
472 execute=0,
473 ldflags=ldflags,
474 msg="Checking linker accepts %s" % ldflags)
477 @conf
478 def CONFIG_GET(conf, option):
479 '''return True if a configuration option was found'''
480 if (option in conf.env):
481 return conf.env[option]
482 else:
483 return None
485 @conf
486 def CONFIG_SET(conf, option):
487 '''return True if a configuration option was found'''
488 if option not in conf.env:
489 return False
490 v = conf.env[option]
491 if v is None:
492 return False
493 if v == []:
494 return False
495 if v == ():
496 return False
497 return True
498 Build.BuildContext.CONFIG_SET = CONFIG_SET
499 Build.BuildContext.CONFIG_GET = CONFIG_GET
502 def library_flags(self, libs):
503 '''work out flags from pkg_config'''
504 ccflags = []
505 ldflags = []
506 cpppath = []
507 for lib in TO_LIST(libs):
508 # note that we do not add the -I and -L in here, as that is added by the waf
509 # core. Adding it here would just change the order that it is put on the link line
510 # which can cause system paths to be added before internal libraries
511 extra_ccflags = TO_LIST(getattr(self.env, 'CCFLAGS_%s' % lib.upper(), []))
512 extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), []))
513 extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), []))
514 ccflags.extend(extra_ccflags)
515 ldflags.extend(extra_ldflags)
516 cpppath.extend(extra_cpppath)
517 if 'EXTRA_LDFLAGS' in self.env:
518 ldflags.extend(self.env['EXTRA_LDFLAGS'])
520 ccflags = unique_list(ccflags)
521 ldflags = unique_list(ldflags)
522 cpppath = unique_list(cpppath)
523 return (ccflags, ldflags, cpppath)
526 @conf
527 def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False):
528 '''check if a set of libraries exist as system libraries
530 returns the sublist of libs that do exist as a syslib or []
533 fragment= '''
534 int foo()
536 int v = 2;
537 return v*2;
540 ret = []
541 liblist = TO_LIST(libs)
542 for lib in liblist[:]:
543 if GET_TARGET_TYPE(conf, lib) == 'SYSLIB':
544 ret.append(lib)
545 continue
547 (ccflags, ldflags, cpppath) = library_flags(conf, lib)
548 if shlib:
549 res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
550 else:
551 res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper())
553 if not res:
554 if mandatory:
555 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
556 sys.exit(1)
557 if empty_decl:
558 # if it isn't a mandatory library, then remove it from dependency lists
559 if set_target:
560 SET_TARGET_TYPE(conf, lib, 'EMPTY')
561 else:
562 conf.define('HAVE_LIB%s' % lib.upper().replace('-','_'), 1)
563 conf.env['LIB_' + lib.upper()] = lib
564 if set_target:
565 conf.SET_TARGET_TYPE(lib, 'SYSLIB')
566 ret.append(lib)
568 return ret
572 @conf
573 def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False,
574 headers=None, link=True, empty_decl=True, set_target=True):
576 check that the functions in 'list' are available in 'library'
577 if they are, then make that library available as a dependency
579 if the library is not available and mandatory==True, then
580 raise an error.
582 If the library is not available and mandatory==False, then
583 add the library to the list of dependencies to remove from
584 build rules
586 optionally check for the functions first in libc
588 remaining = TO_LIST(list)
589 liblist = TO_LIST(library)
591 # check if some already found
592 for f in remaining[:]:
593 if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
594 remaining.remove(f)
596 # see if the functions are in libc
597 if checklibc:
598 for f in remaining[:]:
599 if CHECK_FUNC(conf, f, link=True, headers=headers):
600 remaining.remove(f)
602 if remaining == []:
603 for lib in liblist:
604 if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl:
605 SET_TARGET_TYPE(conf, lib, 'EMPTY')
606 return True
608 checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target)
609 for lib in liblist[:]:
610 if not lib in checklist and mandatory:
611 Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list))
612 sys.exit(1)
614 ret = True
615 for f in remaining:
616 if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link):
617 ret = False
619 return ret
622 @conf
623 def IN_LAUNCH_DIR(conf):
624 '''return True if this rule is being run from the launch directory'''
625 return os.path.realpath(conf.curdir) == os.path.realpath(Options.launch_dir)
626 Options.Handler.IN_LAUNCH_DIR = IN_LAUNCH_DIR
629 @conf
630 def SAMBA_CONFIG_H(conf, path=None):
631 '''write out config.h in the right directory'''
632 # we don't want to produce a config.h in places like lib/replace
633 # when we are building projects that depend on lib/replace
634 if not IN_LAUNCH_DIR(conf):
635 return
637 if Options.options.debug:
638 conf.ADD_CFLAGS('-g',
639 testflags=True)
641 if Options.options.developer:
642 # we add these here to ensure that -Wstrict-prototypes is not set during configure
643 conf.ADD_CFLAGS('-Wall -g -Wshadow -Werror=strict-prototypes -Wstrict-prototypes -Werror=pointer-arith -Wpointer-arith -Wcast-align -Werror=write-strings -Wwrite-strings -Werror-implicit-function-declaration -Wformat=2 -Wno-format-y2k -Wmissing-prototypes -fno-common -Werror=address -Wdeclaration-after-statement',
644 testflags=True)
645 conf.ADD_CFLAGS('-Wcast-qual', testflags=True)
646 conf.env.DEVELOPER_MODE = True
648 # This check is because for ldb_search(), a NULL format string
649 # is not an error, but some compilers complain about that.
650 if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], '''
651 int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2)));
653 int main(void) {
654 testformat(0);
655 return 0;
658 '''):
659 if not 'EXTRA_CFLAGS' in conf.env:
660 conf.env['EXTRA_CFLAGS'] = []
661 conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format"))
663 if Options.options.picky_developer:
664 conf.ADD_CFLAGS('-Werror', testflags=True)
666 if Options.options.fatal_errors:
667 conf.ADD_CFLAGS('-Wfatal-errors', testflags=True)
669 if Options.options.pedantic:
670 conf.ADD_CFLAGS('-W', testflags=True)
672 if path is None:
673 conf.write_config_header('config.h', top=True)
674 else:
675 conf.write_config_header(path)
676 conf.SAMBA_CROSS_CHECK_COMPLETE()
679 @conf
680 def CONFIG_PATH(conf, name, default):
681 '''setup a configurable path'''
682 if not name in conf.env:
683 if default[0] == '/':
684 conf.env[name] = default
685 else:
686 conf.env[name] = conf.env['PREFIX'] + default
688 @conf
689 def ADD_CFLAGS(conf, flags, testflags=False):
690 '''add some CFLAGS to the command line
691 optionally set testflags to ensure all the flags work
693 if testflags:
694 ok_flags=[]
695 for f in flags.split():
696 if CHECK_CFLAGS(conf, f):
697 ok_flags.append(f)
698 flags = ok_flags
699 if not 'EXTRA_CFLAGS' in conf.env:
700 conf.env['EXTRA_CFLAGS'] = []
701 conf.env['EXTRA_CFLAGS'].extend(TO_LIST(flags))
703 @conf
704 def ADD_LDFLAGS(conf, flags, testflags=False):
705 '''add some LDFLAGS to the command line
706 optionally set testflags to ensure all the flags work
708 this will return the flags that are added, if any
710 if testflags:
711 ok_flags=[]
712 for f in flags.split():
713 if CHECK_LDFLAGS(conf, f):
714 ok_flags.append(f)
715 flags = ok_flags
716 if not 'EXTRA_LDFLAGS' in conf.env:
717 conf.env['EXTRA_LDFLAGS'] = []
718 conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags))
719 return flags
722 @conf
723 def ADD_EXTRA_INCLUDES(conf, includes):
724 '''add some extra include directories to all builds'''
725 if not 'EXTRA_INCLUDES' in conf.env:
726 conf.env['EXTRA_INCLUDES'] = []
727 conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes))
731 def CURRENT_CFLAGS(bld, target, cflags, hide_symbols=False):
732 '''work out the current flags. local flags are added first'''
733 if not 'EXTRA_CFLAGS' in bld.env:
734 list = []
735 else:
736 list = bld.env['EXTRA_CFLAGS'];
737 ret = TO_LIST(cflags)
738 ret.extend(list)
739 if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR:
740 ret.append('-fvisibility=hidden')
741 return ret
744 @conf
745 def CHECK_CC_ENV(conf):
746 """trim whitespaces from 'CC'.
747 The build farm sometimes puts a space at the start"""
748 if os.environ.get('CC'):
749 conf.env.CC = TO_LIST(os.environ.get('CC'))
750 if len(conf.env.CC) == 1:
751 # make for nicer logs if just a single command
752 conf.env.CC = conf.env.CC[0]
755 @conf
756 def SETUP_CONFIGURE_CACHE(conf, enable):
757 '''enable/disable cache of configure results'''
758 if enable:
759 # when -C is chosen, we will use a private cache and will
760 # not look into system includes. This roughtly matches what
761 # autoconf does with -C
762 cache_path = os.path.join(conf.blddir, '.confcache')
763 mkdir_p(cache_path)
764 Options.cache_global = os.environ['WAFCACHE'] = cache_path
765 else:
766 # when -C is not chosen we will not cache configure checks
767 # We set the recursion limit low to prevent waf from spending
768 # a lot of time on the signatures of the files.
769 Options.cache_global = os.environ['WAFCACHE'] = ''
770 preproc.recursion_limit = 1
771 # in either case we don't need to scan system includes
772 preproc.go_absolute = False
775 @conf
776 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
777 # we don't want any libraries or modules to rely on runtime
778 # resolution of symbols
779 if not sys.platform.startswith("openbsd"):
780 conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True)
782 if not sys.platform.startswith("openbsd") and conf.env.undefined_ignore_ldflags == []:
783 if conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup']):
784 conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup']