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(void) { 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(void) 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(void) 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(void) 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(void) 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 #if _MSC_VER && !__INTEL_COMPILER 294 #pragma function(%(name)s) 295 #endif 296 297 int main(void) { 298 #if defined (__stub_%(name)s) || defined (__stub___%(name)s) 299 fail fail fail 300 #else 301 %(name)s(); 302 #endif 303 304 return 0; 305 } 306 """ % { 'name': function_name, 307 'include': includetext, 308 'hdr': header } 309 310 context.Display("Checking for %s function %s()... " % (lang, function_name)) 311 ret = context.BuildProg(text, suffix) 312 _YesNoResult(context, ret, "HAVE_" + function_name, text, 313 "Define to 1 if the system has the function `%s'." %\ 314 function_name) 315 return ret
316 317
318 -def CheckHeader(context, header_name, header = None, language = None, 319 include_quotes = None):
320 """ 321 Configure check for a C or C++ header file "header_name". 322 Optional "header" can be defined to do something before including the 323 header file (unusual, supported for consistency). 324 "language" should be "C" or "C++" and is used to select the compiler. 325 Default is "C". 326 Sets HAVE_header_name in context.havedict according to the result. 327 Note that this uses the current value of compiler and linker flags, make 328 sure $CFLAGS and $CPPFLAGS are set correctly. 329 Returns an empty string for success, an error message for failure. 330 """ 331 # Why compile the program instead of just running the preprocessor? 332 # It is possible that the header file exists, but actually using it may 333 # fail (e.g., because it depends on other header files). Thus this test is 334 # more strict. It may require using the "header" argument. 335 # 336 # Use <> by default, because the check is normally used for system header 337 # files. SCons passes '""' to overrule this. 338 339 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 340 if context.headerfilename: 341 includetext = '#include "%s"\n' % context.headerfilename 342 else: 343 includetext = '' 344 if not header: 345 header = "" 346 347 lang, suffix, msg = _lang2suffix(language) 348 if msg: 349 context.Display("Cannot check for header file %s: %s\n" 350 % (header_name, msg)) 351 return msg 352 353 if not include_quotes: 354 include_quotes = "<>" 355 356 text = "%s%s\n#include %s%s%s\n\n" % (includetext, header, 357 include_quotes[0], header_name, include_quotes[1]) 358 359 context.Display("Checking for %s header file %s... " % (lang, header_name)) 360 ret = context.CompileProg(text, suffix) 361 _YesNoResult(context, ret, "HAVE_" + header_name, text, 362 "Define to 1 if you have the <%s> header file." % header_name) 363 return ret
364 365
366 -def CheckType(context, type_name, fallback = None, 367 header = None, language = None):
368 """ 369 Configure check for a C or C++ type "type_name". 370 Optional "header" can be defined to include a header file. 371 "language" should be "C" or "C++" and is used to select the compiler. 372 Default is "C". 373 Sets HAVE_type_name in context.havedict according to the result. 374 Note that this uses the current value of compiler and linker flags, make 375 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 376 Returns an empty string for success, an error message for failure. 377 """ 378 379 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 380 if context.headerfilename: 381 includetext = '#include "%s"' % context.headerfilename 382 else: 383 includetext = '' 384 if not header: 385 header = "" 386 387 lang, suffix, msg = _lang2suffix(language) 388 if msg: 389 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 390 return msg 391 392 # Remarks from autoconf about this test: 393 # - Grepping for the type in include files is not reliable (grep isn't 394 # portable anyway). 395 # - Using "TYPE my_var;" doesn't work for const qualified types in C++. 396 # Adding an initializer is not valid for some C++ classes. 397 # - Using the type as parameter to a function either fails for K&$ C or for 398 # C++. 399 # - Using "TYPE *my_var;" is valid in C for some types that are not 400 # declared (struct something). 401 # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable. 402 # - Using the previous two together works reliably. 403 text = """ 404 %(include)s 405 %(header)s 406 407 int main(void) { 408 if ((%(name)s *) 0) 409 return 0; 410 if (sizeof (%(name)s)) 411 return 0; 412 } 413 """ % { 'include': includetext, 414 'header': header, 415 'name': type_name } 416 417 context.Display("Checking for %s type %s... " % (lang, type_name)) 418 ret = context.BuildProg(text, suffix) 419 _YesNoResult(context, ret, "HAVE_" + type_name, text, 420 "Define to 1 if the system has the type `%s'." % type_name) 421 if ret and fallback and context.headerfilename: 422 f = open(context.headerfilename, "a") 423 f.write("typedef %s %s;\n" % (fallback, type_name)) 424 f.close() 425 426 return ret
427
428 -def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
429 """This check can be used to get the size of a given type, or to check whether 430 the type is of expected size. 431 432 Arguments: 433 - type : str 434 the type to check 435 - includes : sequence 436 list of headers to include in the test code before testing the type 437 - language : str 438 'C' or 'C++' 439 - expect : int 440 if given, will test wether the type has the given number of bytes. 441 If not given, will automatically find the size. 442 443 Returns: 444 status : int 445 0 if the check failed, or the found size of the type if the check succeeded.""" 446 447 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 448 if context.headerfilename: 449 includetext = '#include "%s"' % context.headerfilename 450 else: 451 includetext = '' 452 453 if not header: 454 header = "" 455 456 lang, suffix, msg = _lang2suffix(language) 457 if msg: 458 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 459 return msg 460 461 src = includetext + header 462 if expect is not None: 463 # Only check if the given size is the right one 464 context.Display('Checking %s is %d bytes... ' % (type_name, expect)) 465 466 # test code taken from autoconf: this is a pretty clever hack to find that 467 # a type is of a given size using only compilation. This speeds things up 468 # quite a bit compared to straightforward code using TryRun 469 src = src + r""" 470 typedef %s scons_check_type; 471 472 int main(void) 473 { 474 static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)]; 475 test_array[0] = 0; 476 477 return 0; 478 } 479 """ 480 481 st = context.CompileProg(src % (type_name, expect), suffix) 482 if not st: 483 context.Display("yes\n") 484 _Have(context, "SIZEOF_%s" % type_name, expect, 485 "The size of `%s', as computed by sizeof." % type_name) 486 return expect 487 else: 488 context.Display("no\n") 489 _LogFailed(context, src, st) 490 return 0 491 else: 492 # Only check if the given size is the right one 493 context.Message('Checking size of %s ... ' % type_name) 494 495 # We have to be careful with the program we wish to test here since 496 # compilation will be attempted using the current environment's flags. 497 # So make sure that the program will compile without any warning. For 498 # example using: 'int main(int argc, char** argv)' will fail with the 499 # '-Wall -Werror' flags since the variables argc and argv would not be 500 # used in the program... 501 # 502 src = src + """ 503 #include <stdlib.h> 504 #include <stdio.h> 505 int main(void) { 506 printf("%d", (int)sizeof(""" + type_name + """)); 507 return 0; 508 } 509 """ 510 st, out = context.RunProg(src, suffix) 511 try: 512 size = int(out) 513 except ValueError: 514 # If cannot convert output of test prog to an integer (the size), 515 # something went wront, so just fail 516 st = 1 517 size = 0 518 519 if not st: 520 context.Display("yes\n") 521 _Have(context, "SIZEOF_%s" % type_name, size, 522 "The size of `%s', as computed by sizeof." % type_name) 523 return size 524 else: 525 context.Display("no\n") 526 _LogFailed(context, src, st) 527 return 0 528 529 return 0
530
531 -def CheckDeclaration(context, symbol, includes = None, language = None):
532 """Checks whether symbol is declared. 533 534 Use the same test as autoconf, that is test whether the symbol is defined 535 as a macro or can be used as an r-value. 536 537 Arguments: 538 symbol : str 539 the symbol to check 540 includes : str 541 Optional "header" can be defined to include a header file. 542 language : str 543 only C and C++ supported. 544 545 Returns: 546 status : bool 547 True if the check failed, False if succeeded.""" 548 549 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 550 if context.headerfilename: 551 includetext = '#include "%s"' % context.headerfilename 552 else: 553 includetext = '' 554 555 if not includes: 556 includes = "" 557 558 lang, suffix, msg = _lang2suffix(language) 559 if msg: 560 context.Display("Cannot check for declaration %s: %s\n" % (symbol, msg)) 561 return msg 562 563 src = includetext + includes 564 context.Display('Checking whether %s is declared... ' % symbol) 565 566 src = src + r""" 567 int main(void) 568 { 569 #ifndef %s 570 (void) %s; 571 #endif 572 ; 573 return 0; 574 } 575 """ % (symbol, symbol) 576 577 st = context.CompileProg(src, suffix) 578 _YesNoResult(context, st, "HAVE_DECL_" + symbol, src, 579 "Set to 1 if %s is defined." % symbol) 580 return st
581
582 -def CheckLib(context, libs, func_name = None, header = None, 583 extra_libs = None, call = None, language = None, autoadd = 1, 584 append = True):
585 """ 586 Configure check for a C or C++ libraries "libs". Searches through 587 the list of libraries, until one is found where the test succeeds. 588 Tests if "func_name" or "call" exists in the library. Note: if it exists 589 in another library the test succeeds anyway! 590 Optional "header" can be defined to include a header file. If not given a 591 default prototype for "func_name" is added. 592 Optional "extra_libs" is a list of library names to be added after 593 "lib_name" in the build command. To be used for libraries that "lib_name" 594 depends on. 595 Optional "call" replaces the call to "func_name" in the test code. It must 596 consist of complete C statements, including a trailing ";". 597 Both "func_name" and "call" arguments are optional, and in that case, just 598 linking against the libs is tested. 599 "language" should be "C" or "C++" and is used to select the compiler. 600 Default is "C". 601 Note that this uses the current value of compiler and linker flags, make 602 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 603 Returns an empty string for success, an error message for failure. 604 """ 605 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 606 if context.headerfilename: 607 includetext = '#include "%s"' % context.headerfilename 608 else: 609 includetext = '' 610 if not header: 611 header = "" 612 613 text = """ 614 %s 615 %s""" % (includetext, header) 616 617 # Add a function declaration if needed. 618 if func_name and func_name != "main": 619 if not header: 620 text = text + """ 621 #ifdef __cplusplus 622 extern "C" 623 #endif 624 char %s(); 625 """ % func_name 626 627 # The actual test code. 628 if not call: 629 call = "%s();" % func_name 630 631 # if no function to test, leave main() blank 632 text = text + """ 633 int 634 main() { 635 %s 636 return 0; 637 } 638 """ % (call or "") 639 640 if call: 641 i = call.find("\n") 642 if i > 0: 643 calltext = call[:i] + ".." 644 elif call[-1] == ';': 645 calltext = call[:-1] 646 else: 647 calltext = call 648 649 for lib_name in libs: 650 651 lang, suffix, msg = _lang2suffix(language) 652 if msg: 653 context.Display("Cannot check for library %s: %s\n" % (lib_name, msg)) 654 return msg 655 656 # if a function was specified to run in main(), say it 657 if call: 658 context.Display("Checking for %s in %s library %s... " 659 % (calltext, lang, lib_name)) 660 # otherwise, just say the name of library and language 661 else: 662 context.Display("Checking for %s library %s... " 663 % (lang, lib_name)) 664 665 if lib_name: 666 l = [ lib_name ] 667 if extra_libs: 668 l.extend(extra_libs) 669 if append: 670 oldLIBS = context.AppendLIBS(l) 671 else: 672 oldLIBS = context.PrependLIBS(l) 673 sym = "HAVE_LIB" + lib_name 674 else: 675 oldLIBS = -1 676 sym = None 677 678 ret = context.BuildProg(text, suffix) 679 680 _YesNoResult(context, ret, sym, text, 681 "Define to 1 if you have the `%s' library." % lib_name) 682 if oldLIBS != -1 and (ret or not autoadd): 683 context.SetLIBS(oldLIBS) 684 685 if not ret: 686 return ret 687 688 return ret
689
690 -def CheckProg(context, prog_name):
691 """ 692 Configure check for a specific program. 693 694 Check whether program prog_name exists in path. If it is found, 695 returns the path for it, otherwise returns None. 696 """ 697 context.Display("Checking whether %s program exists..." % prog_name) 698 path = context.env.WhereIs(prog_name) 699 if path: 700 context.Display(path + "\n") 701 else: 702 context.Display("no\n") 703 return path
704 705 706 # 707 # END OF PUBLIC FUNCTIONS 708 # 709
710 -def _YesNoResult(context, ret, key, text, comment = None):
711 r""" 712 Handle the result of a test with a "yes" or "no" result. 713 714 :Parameters: 715 - `ret` is the return value: empty if OK, error message when not. 716 - `key` is the name of the symbol to be defined (HAVE_foo). 717 - `text` is the source code of the program used for testing. 718 - `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. 719 """ 720 if key: 721 _Have(context, key, not ret, comment) 722 if ret: 723 context.Display("no\n") 724 _LogFailed(context, text, ret) 725 else: 726 context.Display("yes\n")
727 728
729 -def _Have(context, key, have, comment = None):
730 r""" 731 Store result of a test in context.havedict and context.headerfilename. 732 733 :Parameters: 734 - `key` - is a "HAVE_abc" name. It is turned into all CAPITALS and non-alphanumerics are replaced by an underscore. 735 - `have` - value as it should appear in the header file, include quotes when desired and escape special characters! 736 - `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. 737 738 739 The value of "have" can be: 740 - 1 - Feature is defined, add "#define key". 741 - 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. 742 - number - Feature is defined to this number "#define key have". Doesn't work for 0 or 1, use a string then. 743 - string - Feature is defined to this string "#define key have". 744 745 746 """ 747 key_up = key.upper() 748 key_up = re.sub('[^A-Z0-9_]', '_', key_up) 749 context.havedict[key_up] = have 750 if have == 1: 751 line = "#define %s 1\n" % key_up 752 elif have == 0: 753 line = "/* #undef %s */\n" % key_up 754 elif isinstance(have, int): 755 line = "#define %s %d\n" % (key_up, have) 756 else: 757 line = "#define %s %s\n" % (key_up, str(have)) 758 759 if comment is not None: 760 lines = "\n/* %s */\n" % comment + line 761 else: 762 lines = "\n" + line 763 764 if context.headerfilename: 765 f = open(context.headerfilename, "a") 766 f.write(lines) 767 f.close() 768 elif hasattr(context,'config_h'): 769 context.config_h = context.config_h + lines
770 771
772 -def _LogFailed(context, text, msg):
773 """ 774 Write to the log about a failed program. 775 Add line numbers, so that error messages can be understood. 776 """ 777 if LogInputFiles: 778 context.Log("Failed program was:\n") 779 lines = text.split('\n') 780 if len(lines) and lines[-1] == '': 781 lines = lines[:-1] # remove trailing empty line 782 n = 1 783 for line in lines: 784 context.Log("%d: %s\n" % (n, line)) 785 n = n + 1 786 if LogErrorMessages: 787 context.Log("Error message: %s\n" % msg)
788 789
790 -def _lang2suffix(lang):
791 """ 792 Convert a language name to a suffix. 793 When "lang" is empty or None C is assumed. 794 Returns a tuple (lang, suffix, None) when it works. 795 For an unrecognized language returns (None, None, msg). 796 797 Where: 798 - lang = the unified language name 799 - suffix = the suffix, including the leading dot 800 - msg = an error message 801 """ 802 if not lang or lang in ["C", "c"]: 803 return ("C", ".c", None) 804 if lang in ["c++", "C++", "cpp", "CXX", "cxx"]: 805 return ("C++", ".cpp", None) 806 807 return None, None, "Unsupported language: %s" % lang
808 809 810 # vim: set sw=4 et sts=4 tw=79 fo+=l: 811 812 # Local Variables: 813 # tab-width:4 814 # indent-tabs-mode:nil 815 # End: 816 # vim: set expandtab tabstop=4 shiftwidth=4: 817