Package SCons :: Module Conftest
[hide private]
[frames] | no frames]

Source Code for Module SCons.Conftest

  1  """SCons.Conftest 
  2   
  3  Autoconf-like configuration support; low level implementation of tests. 
  4  """ 
  5   
  6  # 
  7  # Copyright (c) 2003 Stichting NLnet Labs 
  8  # Copyright (c) 2001, 2002, 2003 Steven Knight 
  9  # 
 10  # Permission is hereby granted, free of charge, to any person obtaining 
 11  # a copy of this software and associated documentation files (the 
 12  # "Software"), to deal in the Software without restriction, including 
 13  # without limitation the rights to use, copy, modify, merge, publish, 
 14  # distribute, sublicense, and/or sell copies of the Software, and to 
 15  # permit persons to whom the Software is furnished to do so, subject to 
 16  # the following conditions: 
 17  # 
 18  # The above copyright notice and this permission notice shall be included 
 19  # in all copies or substantial portions of the Software. 
 20  # 
 21  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 22  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 23  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 24  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
 25  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 26  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 27  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 28  # 
 29   
 30  # 
 31  # The purpose of this module is to define how a check is to be performed. 
 32  # Use one of the Check...() functions below. 
 33  # 
 34   
 35  # 
 36  # A context class is used that defines functions for carrying out the tests, 
 37  # logging and messages.  The following methods and members must be present: 
 38  # 
 39  # context.Display(msg)  Function called to print messages that are normally 
 40  #                       displayed for the user.  Newlines are explicitly used. 
 41  #                       The text should also be written to the logfile! 
 42  # 
 43  # context.Log(msg)      Function called to write to a log file. 
 44  # 
 45  # context.BuildProg(text, ext) 
 46  #                       Function called to build a program, using "ext" for the 
 47  #                       file extention.  Must return an empty string for 
 48  #                       success, an error message for failure. 
 49  #                       For reliable test results building should be done just 
 50  #                       like an actual program would be build, using the same 
 51  #                       command and arguments (including configure results so 
 52  #                       far). 
 53  # 
 54  # context.CompileProg(text, ext) 
 55  #                       Function called to compile a program, using "ext" for 
 56  #                       the file extention.  Must return an empty string for 
 57  #                       success, an error message for failure. 
 58  #                       For reliable test results compiling should be done just 
 59  #                       like an actual source file would be compiled, using the 
 60  #                       same command and arguments (including configure results 
 61  #                       so far). 
 62  # 
 63  # context.AppendLIBS(lib_name_list) 
 64  #                       Append "lib_name_list" to the value of LIBS. 
 65  #                       "lib_namelist" is a list of strings. 
 66  #                       Return the value of LIBS before changing it (any type 
 67  #                       can be used, it is passed to SetLIBS() later.) 
 68  # 
 69  # context.PrependLIBS(lib_name_list) 
 70  #                       Prepend "lib_name_list" to the value of LIBS. 
 71  #                       "lib_namelist" is a list of strings. 
 72  #                       Return the value of LIBS before changing it (any type 
 73  #                       can be used, it is passed to SetLIBS() later.) 
 74  # 
 75  # context.SetLIBS(value) 
 76  #                       Set LIBS to "value".  The type of "value" is what 
 77  #                       AppendLIBS() returned. 
 78  #                       Return the value of LIBS before changing it (any type 
 79  #                       can be used, it is passed to SetLIBS() later.) 
 80  # 
 81  # context.headerfilename 
 82  #                       Name of file to append configure results to, usually 
 83  #                       "confdefs.h". 
 84  #                       The file must not exist or be empty when starting. 
 85  #                       Empty or None to skip this (some tests will not work!). 
 86  # 
 87  # context.config_h      (may be missing). If present, must be a string, which 
 88  #                       will be filled with the contents of a config_h file. 
 89  # 
 90  # context.vardict       Dictionary holding variables used for the tests and 
 91  #                       stores results from the tests, used for the build 
 92  #                       commands. 
 93  #                       Normally contains "CC", "LIBS", "CPPFLAGS", etc. 
 94  # 
 95  # context.havedict      Dictionary holding results from the tests that are to 
 96  #                       be used inside a program. 
 97  #                       Names often start with "HAVE_".  These are zero 
 98  #                       (feature not present) or one (feature present).  Other 
 99  #                       variables may have any value, e.g., "PERLVERSION" can 
100  #                       be a number and "SYSTEMNAME" a string. 
101  # 
102   
103  import re 
104   
105  # 
106  # PUBLIC VARIABLES 
107  # 
108   
109  LogInputFiles = 1    # Set that to log the input files in case of a failed test 
110  LogErrorMessages = 1 # Set that to log Conftest-generated error messages 
111   
112  # 
113  # PUBLIC FUNCTIONS 
114  # 
115   
116  # Generic remarks: 
117  # - When a language is specified which is not supported the test fails.  The 
118  #   message is a bit different, because not all the arguments for the normal 
119  #   message are available yet (chicken-egg problem). 
120   
121   
122 -def CheckBuilder(context, text = None, language = None):
123 """ 124 Configure check to see if the compiler works. 125 Note that this uses the current value of compiler and linker flags, make 126 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 127 "language" should be "C" or "C++" and is used to select the compiler. 128 Default is "C". 129 "text" may be used to specify the code to be build. 130 Returns an empty string for success, an error message for failure. 131 """ 132 lang, suffix, msg = _lang2suffix(language) 133 if msg: 134 context.Display("%s\n" % msg) 135 return msg 136 137 if not text: 138 text = """ 139 int main() { 140 return 0; 141 } 142 """ 143 144 context.Display("Checking if building a %s file works... " % lang) 145 ret = context.BuildProg(text, suffix) 146 _YesNoResult(context, ret, None, text) 147 return ret
148
149 -def CheckCC(context):
150 """ 151 Configure check for a working C compiler. 152 153 This checks whether the C compiler, as defined in the $CC construction 154 variable, can compile a C source file. It uses the current $CCCOM value 155 too, so that it can test against non working flags. 156 157 """ 158 context.Display("Checking whether the C compiler works... ") 159 text = """ 160 int main() 161 { 162 return 0; 163 } 164 """ 165 ret = _check_empty_program(context, 'CC', text, 'C') 166 _YesNoResult(context, ret, None, text) 167 return ret
168
169 -def CheckSHCC(context):
170 """ 171 Configure check for a working shared C compiler. 172 173 This checks whether the C compiler, as defined in the $SHCC construction 174 variable, can compile a C source file. It uses the current $SHCCCOM value 175 too, so that it can test against non working flags. 176 177 """ 178 context.Display("Checking whether the (shared) C compiler works... ") 179 text = """ 180 int foo() 181 { 182 return 0; 183 } 184 """ 185 ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True) 186 _YesNoResult(context, ret, None, text) 187 return ret
188
189 -def CheckCXX(context):
190 """ 191 Configure check for a working CXX compiler. 192 193 This checks whether the CXX compiler, as defined in the $CXX construction 194 variable, can compile a CXX source file. It uses the current $CXXCOM value 195 too, so that it can test against non working flags. 196 197 """ 198 context.Display("Checking whether the C++ compiler works... ") 199 text = """ 200 int main() 201 { 202 return 0; 203 } 204 """ 205 ret = _check_empty_program(context, 'CXX', text, 'C++') 206 _YesNoResult(context, ret, None, text) 207 return ret
208
209 -def CheckSHCXX(context):
210 """ 211 Configure check for a working shared CXX compiler. 212 213 This checks whether the CXX compiler, as defined in the $SHCXX construction 214 variable, can compile a CXX source file. It uses the current $SHCXXCOM value 215 too, so that it can test against non working flags. 216 217 """ 218 context.Display("Checking whether the (shared) C++ compiler works... ") 219 text = """ 220 int main() 221 { 222 return 0; 223 } 224 """ 225 ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True) 226 _YesNoResult(context, ret, None, text) 227 return ret
228
229 -def _check_empty_program(context, comp, text, language, use_shared = False):
230 """Return 0 on success, 1 otherwise.""" 231 if comp not in context.env or not context.env[comp]: 232 # The compiler construction variable is not set or empty 233 return 1 234 235 lang, suffix, msg = _lang2suffix(language) 236 if msg: 237 return 1 238 239 if use_shared: 240 return context.CompileSharedObject(text, suffix) 241 else: 242 return context.CompileProg(text, suffix)
243 244
245 -def CheckFunc(context, function_name, header = None, language = None):
246 """ 247 Configure check for a function "function_name". 248 "language" should be "C" or "C++" and is used to select the compiler. 249 Default is "C". 250 Optional "header" can be defined to define a function prototype, include a 251 header file or anything else that comes before main(). 252 Sets HAVE_function_name in context.havedict according to the result. 253 Note that this uses the current value of compiler and linker flags, make 254 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 255 Returns an empty string for success, an error message for failure. 256 """ 257 258 # Remarks from autoconf: 259 # - Don't include <ctype.h> because on OSF/1 3.0 it includes <sys/types.h> 260 # which includes <sys/select.h> which contains a prototype for select. 261 # Similarly for bzero. 262 # - assert.h is included to define __stub macros and hopefully few 263 # prototypes, which can conflict with char $1(); below. 264 # - Override any gcc2 internal prototype to avoid an error. 265 # - We use char for the function declaration because int might match the 266 # return type of a gcc2 builtin and then its argument prototype would 267 # still apply. 268 # - The GNU C library defines this for functions which it implements to 269 # always fail with ENOSYS. Some functions are actually named something 270 # starting with __ and the normal name is an alias. 271 272 if context.headerfilename: 273 includetext = '#include "%s"' % context.headerfilename 274 else: 275 includetext = '' 276 if not header: 277 header = """ 278 #ifdef __cplusplus 279 extern "C" 280 #endif 281 char %s();""" % function_name 282 283 lang, suffix, msg = _lang2suffix(language) 284 if msg: 285 context.Display("Cannot check for %s(): %s\n" % (function_name, msg)) 286 return msg 287 288 text = """ 289 %(include)s 290 #include <assert.h> 291 %(hdr)s 292 293 int main() { 294 #if defined (__stub_%(name)s) || defined (__stub___%(name)s) 295 fail fail fail 296 #else 297 %(name)s(); 298 #endif 299 300 return 0; 301 } 302 """ % { 'name': function_name, 303 'include': includetext, 304 'hdr': header } 305 306 context.Display("Checking for %s function %s()... " % (lang, function_name)) 307 ret = context.BuildProg(text, suffix) 308 _YesNoResult(context, ret, "HAVE_" + function_name, text, 309 "Define to 1 if the system has the function `%s'." %\ 310 function_name) 311 return ret
312 313
314 -def CheckHeader(context, header_name, header = None, language = None, 315 include_quotes = None):
316 """ 317 Configure check for a C or C++ header file "header_name". 318 Optional "header" can be defined to do something before including the 319 header file (unusual, supported for consistency). 320 "language" should be "C" or "C++" and is used to select the compiler. 321 Default is "C". 322 Sets HAVE_header_name in context.havedict according to the result. 323 Note that this uses the current value of compiler and linker flags, make 324 sure $CFLAGS and $CPPFLAGS are set correctly. 325 Returns an empty string for success, an error message for failure. 326 """ 327 # Why compile the program instead of just running the preprocessor? 328 # It is possible that the header file exists, but actually using it may 329 # fail (e.g., because it depends on other header files). Thus this test is 330 # more strict. It may require using the "header" argument. 331 # 332 # Use <> by default, because the check is normally used for system header 333 # files. SCons passes '""' to overrule this. 334 335 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 336 if context.headerfilename: 337 includetext = '#include "%s"\n' % context.headerfilename 338 else: 339 includetext = '' 340 if not header: 341 header = "" 342 343 lang, suffix, msg = _lang2suffix(language) 344 if msg: 345 context.Display("Cannot check for header file %s: %s\n" 346 % (header_name, msg)) 347 return msg 348 349 if not include_quotes: 350 include_quotes = "<>" 351 352 text = "%s%s\n#include %s%s%s\n\n" % (includetext, header, 353 include_quotes[0], header_name, include_quotes[1]) 354 355 context.Display("Checking for %s header file %s... " % (lang, header_name)) 356 ret = context.CompileProg(text, suffix) 357 _YesNoResult(context, ret, "HAVE_" + header_name, text, 358 "Define to 1 if you have the <%s> header file." % header_name) 359 return ret
360 361
362 -def CheckType(context, type_name, fallback = None, 363 header = None, language = None):
364 """ 365 Configure check for a C or C++ type "type_name". 366 Optional "header" can be defined to include a header file. 367 "language" should be "C" or "C++" and is used to select the compiler. 368 Default is "C". 369 Sets HAVE_type_name in context.havedict according to the result. 370 Note that this uses the current value of compiler and linker flags, make 371 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 372 Returns an empty string for success, an error message for failure. 373 """ 374 375 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 376 if context.headerfilename: 377 includetext = '#include "%s"' % context.headerfilename 378 else: 379 includetext = '' 380 if not header: 381 header = "" 382 383 lang, suffix, msg = _lang2suffix(language) 384 if msg: 385 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 386 return msg 387 388 # Remarks from autoconf about this test: 389 # - Grepping for the type in include files is not reliable (grep isn't 390 # portable anyway). 391 # - Using "TYPE my_var;" doesn't work for const qualified types in C++. 392 # Adding an initializer is not valid for some C++ classes. 393 # - Using the type as parameter to a function either fails for K&$ C or for 394 # C++. 395 # - Using "TYPE *my_var;" is valid in C for some types that are not 396 # declared (struct something). 397 # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable. 398 # - Using the previous two together works reliably. 399 text = """ 400 %(include)s 401 %(header)s 402 403 int main() { 404 if ((%(name)s *) 0) 405 return 0; 406 if (sizeof (%(name)s)) 407 return 0; 408 } 409 """ % { 'include': includetext, 410 'header': header, 411 'name': type_name } 412 413 context.Display("Checking for %s type %s... " % (lang, type_name)) 414 ret = context.BuildProg(text, suffix) 415 _YesNoResult(context, ret, "HAVE_" + type_name, text, 416 "Define to 1 if the system has the type `%s'." % type_name) 417 if ret and fallback and context.headerfilename: 418 f = open(context.headerfilename, "a") 419 f.write("typedef %s %s;\n" % (fallback, type_name)) 420 f.close() 421 422 return ret
423
424 -def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
425 """This check can be used to get the size of a given type, or to check whether 426 the type is of expected size. 427 428 Arguments: 429 - type : str 430 the type to check 431 - includes : sequence 432 list of headers to include in the test code before testing the type 433 - language : str 434 'C' or 'C++' 435 - expect : int 436 if given, will test wether the type has the given number of bytes. 437 If not given, will automatically find the size. 438 439 Returns: 440 status : int 441 0 if the check failed, or the found size of the type if the check succeeded.""" 442 443 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 444 if context.headerfilename: 445 includetext = '#include "%s"' % context.headerfilename 446 else: 447 includetext = '' 448 449 if not header: 450 header = "" 451 452 lang, suffix, msg = _lang2suffix(language) 453 if msg: 454 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 455 return msg 456 457 src = includetext + header 458 if not expect is None: 459 # Only check if the given size is the right one 460 context.Display('Checking %s is %d bytes... ' % (type_name, expect)) 461 462 # test code taken from autoconf: this is a pretty clever hack to find that 463 # a type is of a given size using only compilation. This speeds things up 464 # quite a bit compared to straightforward code using TryRun 465 src = src + r""" 466 typedef %s scons_check_type; 467 468 int main() 469 { 470 static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)]; 471 test_array[0] = 0; 472 473 return 0; 474 } 475 """ 476 477 st = context.CompileProg(src % (type_name, expect), suffix) 478 if not st: 479 context.Display("yes\n") 480 _Have(context, "SIZEOF_%s" % type_name, expect, 481 "The size of `%s', as computed by sizeof." % type_name) 482 return expect 483 else: 484 context.Display("no\n") 485 _LogFailed(context, src, st) 486 return 0 487 else: 488 # Only check if the given size is the right one 489 context.Message('Checking size of %s ... ' % type_name) 490 491 # We have to be careful with the program we wish to test here since 492 # compilation will be attempted using the current environment's flags. 493 # So make sure that the program will compile without any warning. For 494 # example using: 'int main(int argc, char** argv)' will fail with the 495 # '-Wall -Werror' flags since the variables argc and argv would not be 496 # used in the program... 497 # 498 src = src + """ 499 #include <stdlib.h> 500 #include <stdio.h> 501 int main() { 502 printf("%d", (int)sizeof(""" + type_name + """)); 503 return 0; 504 } 505 """ 506 st, out = context.RunProg(src, suffix) 507 try: 508 size = int(out) 509 except ValueError: 510 # If cannot convert output of test prog to an integer (the size), 511 # something went wront, so just fail 512 st = 1 513 size = 0 514 515 if not st: 516 context.Display("yes\n") 517 _Have(context, "SIZEOF_%s" % type_name, size, 518 "The size of `%s', as computed by sizeof." % type_name) 519 return size 520 else: 521 context.Display("no\n") 522 _LogFailed(context, src, st) 523 return 0 524 525 return 0
526
527 -def CheckDeclaration(context, symbol, includes = None, language = None):
528 """Checks whether symbol is declared. 529 530 Use the same test as autoconf, that is test whether the symbol is defined 531 as a macro or can be used as an r-value. 532 533 Arguments: 534 symbol : str 535 the symbol to check 536 includes : str 537 Optional "header" can be defined to include a header file. 538 language : str 539 only C and C++ supported. 540 541 Returns: 542 status : bool 543 True if the check failed, False if succeeded.""" 544 545 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 546 if context.headerfilename: 547 includetext = '#include "%s"' % context.headerfilename 548 else: 549 includetext = '' 550 551 if not includes: 552 includes = "" 553 554 lang, suffix, msg = _lang2suffix(language) 555 if msg: 556 context.Display("Cannot check for declaration %s: %s\n" % (symbol, msg)) 557 return msg 558 559 src = includetext + includes 560 context.Display('Checking whether %s is declared... ' % symbol) 561 562 src = src + r""" 563 int main() 564 { 565 #ifndef %s 566 (void) %s; 567 #endif 568 ; 569 return 0; 570 } 571 """ % (symbol, symbol) 572 573 st = context.CompileProg(src, suffix) 574 _YesNoResult(context, st, "HAVE_DECL_" + symbol, src, 575 "Set to 1 if %s is defined." % symbol) 576 return st
577
578 -def CheckLib(context, libs, func_name = None, header = None, 579 extra_libs = None, call = None, language = None, autoadd = 1, 580 append = True):
581 """ 582 Configure check for a C or C++ libraries "libs". Searches through 583 the list of libraries, until one is found where the test succeeds. 584 Tests if "func_name" or "call" exists in the library. Note: if it exists 585 in another library the test succeeds anyway! 586 Optional "header" can be defined to include a header file. If not given a 587 default prototype for "func_name" is added. 588 Optional "extra_libs" is a list of library names to be added after 589 "lib_name" in the build command. To be used for libraries that "lib_name" 590 depends on. 591 Optional "call" replaces the call to "func_name" in the test code. It must 592 consist of complete C statements, including a trailing ";". 593 Both "func_name" and "call" arguments are optional, and in that case, just 594 linking against the libs is tested. 595 "language" should be "C" or "C++" and is used to select the compiler. 596 Default is "C". 597 Note that this uses the current value of compiler and linker flags, make 598 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 599 Returns an empty string for success, an error message for failure. 600 """ 601 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 602 if context.headerfilename: 603 includetext = '#include "%s"' % context.headerfilename 604 else: 605 includetext = '' 606 if not header: 607 header = "" 608 609 text = """ 610 %s 611 %s""" % (includetext, header) 612 613 # Add a function declaration if needed. 614 if func_name and func_name != "main": 615 if not header: 616 text = text + """ 617 #ifdef __cplusplus 618 extern "C" 619 #endif 620 char %s(); 621 """ % func_name 622 623 # The actual test code. 624 if not call: 625 call = "%s();" % func_name 626 627 # if no function to test, leave main() blank 628 text = text + """ 629 int 630 main() { 631 %s 632 return 0; 633 } 634 """ % (call or "") 635 636 if call: 637 i = call.find("\n") 638 if i > 0: 639 calltext = call[:i] + ".." 640 elif call[-1] == ';': 641 calltext = call[:-1] 642 else: 643 calltext = call 644 645 for lib_name in libs: 646 647 lang, suffix, msg = _lang2suffix(language) 648 if msg: 649 context.Display("Cannot check for library %s: %s\n" % (lib_name, msg)) 650 return msg 651 652 # if a function was specified to run in main(), say it 653 if call: 654 context.Display("Checking for %s in %s library %s... " 655 % (calltext, lang, lib_name)) 656 # otherwise, just say the name of library and language 657 else: 658 context.Display("Checking for %s library %s... " 659 % (lang, lib_name)) 660 661 if lib_name: 662 l = [ lib_name ] 663 if extra_libs: 664 l.extend(extra_libs) 665 if append: 666 oldLIBS = context.AppendLIBS(l) 667 else: 668 oldLIBS = context.PrependLIBS(l) 669 sym = "HAVE_LIB" + lib_name 670 else: 671 oldLIBS = -1 672 sym = None 673 674 ret = context.BuildProg(text, suffix) 675 676 _YesNoResult(context, ret, sym, text, 677 "Define to 1 if you have the `%s' library." % lib_name) 678 if oldLIBS != -1 and (ret or not autoadd): 679 context.SetLIBS(oldLIBS) 680 681 if not ret: 682 return ret 683 684 return ret
685
686 -def CheckProg(context, prog_name):
687 """ 688 Configure check for a specific program. 689 690 Check whether program prog_name exists in path. If it is found, 691 returns the path for it, otherwise returns None. 692 """ 693 context.Display("Checking whether %s program exists..." % prog_name) 694 path = context.env.WhereIs(prog_name) 695 if path: 696 context.Display(path + "\n") 697 else: 698 context.Display("no\n") 699 return path
700 701 702 # 703 # END OF PUBLIC FUNCTIONS 704 # 705
706 -def _YesNoResult(context, ret, key, text, comment = None):
707 """ 708 Handle the result of a test with a "yes" or "no" result. 709 710 :Parameters: 711 - `ret` is the return value: empty if OK, error message when not. 712 - `key` is the name of the symbol to be defined (HAVE_foo). 713 - `text` is the source code of the program used for testing. 714 - `comment` is the C comment to add above the line defining the symbol (the comment is automatically put inside a /\* \*/). If None, no comment is added. 715 """ 716 if key: 717 _Have(context, key, not ret, comment) 718 if ret: 719 context.Display("no\n") 720 _LogFailed(context, text, ret) 721 else: 722 context.Display("yes\n")
723 724
725 -def _Have(context, key, have, comment = None):
726 """ 727 Store result of a test in context.havedict and context.headerfilename. 728 729 :Parameters: 730 - `key` - is a "HAVE_abc" name. It is turned into all CAPITALS and non-alphanumerics are replaced by an underscore. 731 - `have` - value as it should appear in the header file, include quotes when desired and escape special characters! 732 - `comment` is the C comment to add above the line defining the symbol (the comment is automatically put inside a /\* \*/). If None, no comment is added. 733 734 735 The value of "have" can be: 736 - 1 - Feature is defined, add "#define key". 737 - 0 - Feature is not defined, add "/\* #undef key \*/". Adding "undef" is what autoconf does. Not useful for the compiler, but it shows that the test was done. 738 - number - Feature is defined to this number "#define key have". Doesn't work for 0 or 1, use a string then. 739 - string - Feature is defined to this string "#define key have". 740 741 742 """ 743 key_up = key.upper() 744 key_up = re.sub('[^A-Z0-9_]', '_', key_up) 745 context.havedict[key_up] = have 746 if have == 1: 747 line = "#define %s 1\n" % key_up 748 elif have == 0: 749 line = "/* #undef %s */\n" % key_up 750 elif isinstance(have, int): 751 line = "#define %s %d\n" % (key_up, have) 752 else: 753 line = "#define %s %s\n" % (key_up, str(have)) 754 755 if comment is not None: 756 lines = "\n/* %s */\n" % comment + line 757 else: 758 lines = "\n" + line 759 760 if context.headerfilename: 761 f = open(context.headerfilename, "a") 762 f.write(lines) 763 f.close() 764 elif hasattr(context,'config_h'): 765 context.config_h = context.config_h + lines
766 767
768 -def _LogFailed(context, text, msg):
769 """ 770 Write to the log about a failed program. 771 Add line numbers, so that error messages can be understood. 772 """ 773 if LogInputFiles: 774 context.Log("Failed program was:\n") 775 lines = text.split('\n') 776 if len(lines) and lines[-1] == '': 777 lines = lines[:-1] # remove trailing empty line 778 n = 1 779 for line in lines: 780 context.Log("%d: %s\n" % (n, line)) 781 n = n + 1 782 if LogErrorMessages: 783 context.Log("Error message: %s\n" % msg)
784 785
786 -def _lang2suffix(lang):
787 """ 788 Convert a language name to a suffix. 789 When "lang" is empty or None C is assumed. 790 Returns a tuple (lang, suffix, None) when it works. 791 For an unrecognized language returns (None, None, msg). 792 793 Where: 794 - lang = the unified language name 795 - suffix = the suffix, including the leading dot 796 - msg = an error message 797 """ 798 if not lang or lang in ["C", "c"]: 799 return ("C", ".c", None) 800 if lang in ["c++", "C++", "cpp", "CXX", "cxx"]: 801 return ("C++", ".cpp", None) 802 803 return None, None, "Unsupported language: %s" % lang
804 805 806 # vim: set sw=4 et sts=4 tw=79 fo+=l: 807 808 # Local Variables: 809 # tab-width:4 810 # indent-tabs-mode:nil 811 # End: 812 # vim: set expandtab tabstop=4 shiftwidth=4: 813