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