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