1"""SCons.Tool 2 3SCons tool selection. 4 5This looks for modules that define a callable object that can modify 6a construction environment as appropriate for a given tool (or tool 7chain). 8 9Note that because this subsystem just *selects* a callable that can 10modify a construction environment, it's possible for people to define 11their own "tool specification" in an arbitrary callable function. No 12one needs to use or tie in to this subsystem in order to roll their own 13tool definition. 14""" 15 16# 17# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation 18# 19# Permission is hereby granted, free of charge, to any person obtaining 20# a copy of this software and associated documentation files (the 21# "Software"), to deal in the Software without restriction, including 22# without limitation the rights to use, copy, modify, merge, publish, 23# distribute, sublicense, and/or sell copies of the Software, and to 24# permit persons to whom the Software is furnished to do so, subject to 25# the following conditions: 26# 27# The above copyright notice and this permission notice shall be included 28# in all copies or substantial portions of the Software. 29# 30# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 31# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 32# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37# 38 39__revision__ = "src/engine/SCons/Tool/__init__.py 4369 2009/09/19 15:58:29 scons" 40 41import imp 42import sys 43 44import SCons.Builder 45import SCons.Errors 46import SCons.Node.FS 47import SCons.Scanner 48import SCons.Scanner.C 49import SCons.Scanner.D 50import SCons.Scanner.LaTeX 51import SCons.Scanner.Prog 52 53DefaultToolpath=[] 54 55CScanner = SCons.Scanner.C.CScanner() 56DScanner = SCons.Scanner.D.DScanner() 57LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner() 58PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner() 59ProgramScanner = SCons.Scanner.Prog.ProgramScanner() 60SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner') 61 62CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", 63 ".h", ".H", ".hxx", ".hpp", ".hh", 64 ".F", ".fpp", ".FPP", 65 ".m", ".mm", 66 ".S", ".spp", ".SPP"] 67 68DSuffixes = ['.d'] 69 70IDLSuffixes = [".idl", ".IDL"] 71 72LaTeXSuffixes = [".tex", ".ltx", ".latex"] 73 74for suffix in CSuffixes: 75 SourceFileScanner.add_scanner(suffix, CScanner) 76 77for suffix in DSuffixes: 78 SourceFileScanner.add_scanner(suffix, DScanner) 79 80# FIXME: what should be done here? Two scanners scan the same extensions, 81# but look for different files, e.g., "picture.eps" vs. "picture.pdf". 82# The builders for DVI and PDF explicitly reference their scanners 83# I think that means this is not needed??? 84for suffix in LaTeXSuffixes: 85 SourceFileScanner.add_scanner(suffix, LaTeXScanner) 86 SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner) 87 88class Tool: 89 def __init__(self, name, toolpath=[], **kw): 90 self.name = name 91 self.toolpath = toolpath + DefaultToolpath 92 # remember these so we can merge them into the call 93 self.init_kw = kw 94 95 module = self._tool_module() 96 self.generate = module.generate 97 self.exists = module.exists 98 if hasattr(module, 'options'): 99 self.options = module.options 100 101 def _tool_module(self): 102 # TODO: Interchange zipimport with normal initilization for better error reporting 103 oldpythonpath = sys.path 104 sys.path = self.toolpath + sys.path 105 106 try: 107 try: 108 file, path, desc = imp.find_module(self.name, self.toolpath) 109 try: 110 return imp.load_module(self.name, file, path, desc) 111 finally: 112 if file: 113 file.close() 114 except ImportError as e: 115 if str(e)!="No module named %s"%self.name: 116 raise SCons.Errors.EnvironmentError(e) 117 try: 118 import zipimport 119 except ImportError: 120 pass 121 else: 122 for aPath in self.toolpath: 123 try: 124 importer = zipimport.zipimporter(aPath) 125 return importer.load_module(self.name) 126 except ImportError as e: 127 pass 128 finally: 129 sys.path = oldpythonpath 130 131 full_name = 'SCons.Tool.' + self.name 132 try: 133 return sys.modules[full_name] 134 except KeyError: 135 try: 136 smpath = sys.modules['SCons.Tool'].__path__ 137 try: 138 file, path, desc = imp.find_module(self.name, smpath) 139 module = imp.load_module(full_name, file, path, desc) 140 setattr(SCons.Tool, self.name, module) 141 if file: 142 file.close() 143 return module 144 except ImportError as e: 145 if str(e)!="No module named %s"%self.name: 146 raise SCons.Errors.EnvironmentError(e) 147 try: 148 import zipimport 149 importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] ) 150 module = importer.load_module(full_name) 151 setattr(SCons.Tool, self.name, module) 152 return module 153 except ImportError as e: 154 m = "No tool named '%s': %s" % (self.name, e) 155 raise SCons.Errors.EnvironmentError(m) 156 except ImportError as e: 157 m = "No tool named '%s': %s" % (self.name, e) 158 raise SCons.Errors.EnvironmentError(m) 159 160 def __call__(self, env, *args, **kw): 161 if self.init_kw is not None: 162 # Merge call kws into init kws; 163 # but don't bash self.init_kw. 164 if kw is not None: 165 call_kw = kw 166 kw = self.init_kw.copy() 167 kw.update(call_kw) 168 else: 169 kw = self.init_kw 170 env.Append(TOOLS = [ self.name ]) 171 if hasattr(self, 'options'): 172 import SCons.Variables 173 if 'options' not in env: 174 from SCons.Script import ARGUMENTS 175 env['options']=SCons.Variables.Variables(args=ARGUMENTS) 176 opts=env['options'] 177 178 self.options(opts) 179 opts.Update(env) 180 181 self.generate(*( env, ) + args, **kw) 182 183 def __str__(self): 184 return self.name 185 186########################################################################## 187# Create common executable program / library / object builders 188 189def createProgBuilder(env): 190 """This is a utility function that creates the Program 191 Builder in an Environment if it is not there already. 192 193 If it is already there, we return the existing one. 194 """ 195 196 try: 197 program = env['BUILDERS']['Program'] 198 except KeyError: 199 import SCons.Defaults 200 program = SCons.Builder.Builder(action = SCons.Defaults.LinkAction, 201 emitter = '$PROGEMITTER', 202 prefix = '$PROGPREFIX', 203 suffix = '$PROGSUFFIX', 204 src_suffix = '$OBJSUFFIX', 205 src_builder = 'Object', 206 target_scanner = ProgramScanner) 207 env['BUILDERS']['Program'] = program 208 209 return program 210 211def createStaticLibBuilder(env): 212 """This is a utility function that creates the StaticLibrary 213 Builder in an Environment if it is not there already. 214 215 If it is already there, we return the existing one. 216 """ 217 218 try: 219 static_lib = env['BUILDERS']['StaticLibrary'] 220 except KeyError: 221 action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] 222 if env.Detect('ranlib'): 223 ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") 224 action_list.append(ranlib_action) 225 226 static_lib = SCons.Builder.Builder(action = action_list, 227 emitter = '$LIBEMITTER', 228 prefix = '$LIBPREFIX', 229 suffix = '$LIBSUFFIX', 230 src_suffix = '$OBJSUFFIX', 231 src_builder = 'StaticObject') 232 env['BUILDERS']['StaticLibrary'] = static_lib 233 env['BUILDERS']['Library'] = static_lib 234 235 return static_lib 236 237def createSharedLibBuilder(env): 238 """This is a utility function that creates the SharedLibrary 239 Builder in an Environment if it is not there already. 240 241 If it is already there, we return the existing one. 242 """ 243 244 try: 245 shared_lib = env['BUILDERS']['SharedLibrary'] 246 except KeyError: 247 import SCons.Defaults 248 action_list = [ SCons.Defaults.SharedCheck, 249 SCons.Defaults.ShLinkAction ] 250 shared_lib = SCons.Builder.Builder(action = action_list, 251 emitter = "$SHLIBEMITTER", 252 prefix = '$SHLIBPREFIX', 253 suffix = '$SHLIBSUFFIX', 254 target_scanner = ProgramScanner, 255 src_suffix = '$SHOBJSUFFIX', 256 src_builder = 'SharedObject') 257 env['BUILDERS']['SharedLibrary'] = shared_lib 258 259 return shared_lib 260 261def createLoadableModuleBuilder(env): 262 """This is a utility function that creates the LoadableModule 263 Builder in an Environment if it is not there already. 264 265 If it is already there, we return the existing one. 266 """ 267 268 try: 269 ld_module = env['BUILDERS']['LoadableModule'] 270 except KeyError: 271 import SCons.Defaults 272 action_list = [ SCons.Defaults.SharedCheck, 273 SCons.Defaults.LdModuleLinkAction ] 274 ld_module = SCons.Builder.Builder(action = action_list, 275 emitter = "$LDMODULEEMITTER", 276 prefix = '$LDMODULEPREFIX', 277 suffix = '$LDMODULESUFFIX', 278 target_scanner = ProgramScanner, 279 src_suffix = '$SHOBJSUFFIX', 280 src_builder = 'SharedObject') 281 env['BUILDERS']['LoadableModule'] = ld_module 282 283 return ld_module 284 285def createObjBuilders(env): 286 """This is a utility function that creates the StaticObject 287 and SharedObject Builders in an Environment if they 288 are not there already. 289 290 If they are there already, we return the existing ones. 291 292 This is a separate function because soooo many Tools 293 use this functionality. 294 295 The return is a 2-tuple of (StaticObject, SharedObject) 296 """ 297 298 299 try: 300 static_obj = env['BUILDERS']['StaticObject'] 301 except KeyError: 302 static_obj = SCons.Builder.Builder(action = {}, 303 emitter = {}, 304 prefix = '$OBJPREFIX', 305 suffix = '$OBJSUFFIX', 306 src_builder = ['CFile', 'CXXFile'], 307 source_scanner = SourceFileScanner, 308 single_source = 1) 309 env['BUILDERS']['StaticObject'] = static_obj 310 env['BUILDERS']['Object'] = static_obj 311 312 try: 313 shared_obj = env['BUILDERS']['SharedObject'] 314 except KeyError: 315 shared_obj = SCons.Builder.Builder(action = {}, 316 emitter = {}, 317 prefix = '$SHOBJPREFIX', 318 suffix = '$SHOBJSUFFIX', 319 src_builder = ['CFile', 'CXXFile'], 320 source_scanner = SourceFileScanner, 321 single_source = 1) 322 env['BUILDERS']['SharedObject'] = shared_obj 323 324 return (static_obj, shared_obj) 325 326def createCFileBuilders(env): 327 """This is a utility function that creates the CFile/CXXFile 328 Builders in an Environment if they 329 are not there already. 330 331 If they are there already, we return the existing ones. 332 333 This is a separate function because soooo many Tools 334 use this functionality. 335 336 The return is a 2-tuple of (CFile, CXXFile) 337 """ 338 339 try: 340 c_file = env['BUILDERS']['CFile'] 341 except KeyError: 342 c_file = SCons.Builder.Builder(action = {}, 343 emitter = {}, 344 suffix = {None:'$CFILESUFFIX'}) 345 env['BUILDERS']['CFile'] = c_file 346 347 env.SetDefault(CFILESUFFIX = '.c') 348 349 try: 350 cxx_file = env['BUILDERS']['CXXFile'] 351 except KeyError: 352 cxx_file = SCons.Builder.Builder(action = {}, 353 emitter = {}, 354 suffix = {None:'$CXXFILESUFFIX'}) 355 env['BUILDERS']['CXXFile'] = cxx_file 356 env.SetDefault(CXXFILESUFFIX = '.cc') 357 358 return (c_file, cxx_file) 359 360########################################################################## 361# Create common Java builders 362 363def CreateJarBuilder(env): 364 try: 365 java_jar = env['BUILDERS']['Jar'] 366 except KeyError: 367 fs = SCons.Node.FS.get_default_fs() 368 jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR') 369 java_jar = SCons.Builder.Builder(action = jar_com, 370 suffix = '$JARSUFFIX', 371 src_suffix = '$JAVACLASSSUFIX', 372 src_builder = 'JavaClassFile', 373 source_factory = fs.Entry) 374 env['BUILDERS']['Jar'] = java_jar 375 return java_jar 376 377def CreateJavaHBuilder(env): 378 try: 379 java_javah = env['BUILDERS']['JavaH'] 380 except KeyError: 381 fs = SCons.Node.FS.get_default_fs() 382 java_javah_com = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR') 383 java_javah = SCons.Builder.Builder(action = java_javah_com, 384 src_suffix = '$JAVACLASSSUFFIX', 385 target_factory = fs.Entry, 386 source_factory = fs.File, 387 src_builder = 'JavaClassFile') 388 env['BUILDERS']['JavaH'] = java_javah 389 return java_javah 390 391def CreateJavaClassFileBuilder(env): 392 try: 393 java_class_file = env['BUILDERS']['JavaClassFile'] 394 except KeyError: 395 fs = SCons.Node.FS.get_default_fs() 396 javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') 397 java_class_file = SCons.Builder.Builder(action = javac_com, 398 emitter = {}, 399 #suffix = '$JAVACLASSSUFFIX', 400 src_suffix = '$JAVASUFFIX', 401 src_builder = ['JavaFile'], 402 target_factory = fs.Entry, 403 source_factory = fs.File) 404 env['BUILDERS']['JavaClassFile'] = java_class_file 405 return java_class_file 406 407def CreateJavaClassDirBuilder(env): 408 try: 409 java_class_dir = env['BUILDERS']['JavaClassDir'] 410 except KeyError: 411 fs = SCons.Node.FS.get_default_fs() 412 javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') 413 java_class_dir = SCons.Builder.Builder(action = javac_com, 414 emitter = {}, 415 target_factory = fs.Dir, 416 source_factory = fs.Dir) 417 env['BUILDERS']['JavaClassDir'] = java_class_dir 418 return java_class_dir 419 420def CreateJavaFileBuilder(env): 421 try: 422 java_file = env['BUILDERS']['JavaFile'] 423 except KeyError: 424 java_file = SCons.Builder.Builder(action = {}, 425 emitter = {}, 426 suffix = {None:'$JAVASUFFIX'}) 427 env['BUILDERS']['JavaFile'] = java_file 428 env['JAVASUFFIX'] = '.java' 429 return java_file 430 431class ToolInitializerMethod: 432 """ 433 This is added to a construction environment in place of a 434 method(s) normally called for a Builder (env.Object, env.StaticObject, 435 etc.). When called, it has its associated ToolInitializer 436 object search the specified list of tools and apply the first 437 one that exists to the construction environment. It then calls 438 whatever builder was (presumably) added to the construction 439 environment in place of this particular instance. 440 """ 441 def __init__(self, name, initializer): 442 """ 443 Note: we store the tool name as __name__ so it can be used by 444 the class that attaches this to a construction environment. 445 """ 446 self.__name__ = name 447 self.initializer = initializer 448 449 def get_builder(self, env): 450 """ 451 Returns the appropriate real Builder for this method name 452 after having the associated ToolInitializer object apply 453 the appropriate Tool module. 454 """ 455 builder = getattr(env, self.__name__) 456 457 self.initializer.apply_tools(env) 458 459 builder = getattr(env, self.__name__) 460 if builder is self: 461 # There was no Builder added, which means no valid Tool 462 # for this name was found (or possibly there's a mismatch 463 # between the name we were called by and the Builder name 464 # added by the Tool module). 465 return None 466 467 self.initializer.remove_methods(env) 468 469 return builder 470 471 def __call__(self, env, *args, **kw): 472 """ 473 """ 474 builder = self.get_builder(env) 475 if builder is None: 476 return [], [] 477 return builder(*args, **kw) 478 479class ToolInitializer: 480 """ 481 A class for delayed initialization of Tools modules. 482 483 Instances of this class associate a list of Tool modules with 484 a list of Builder method names that will be added by those Tool 485 modules. As part of instantiating this object for a particular 486 construction environment, we also add the appropriate 487 ToolInitializerMethod objects for the various Builder methods 488 that we want to use to delay Tool searches until necessary. 489 """ 490 def __init__(self, env, tools, names): 491 if not SCons.Util.is_List(tools): 492 tools = [tools] 493 if not SCons.Util.is_List(names): 494 names = [names] 495 self.env = env 496 self.tools = tools 497 self.names = names 498 self.methods = {} 499 for name in names: 500 method = ToolInitializerMethod(name, self) 501 self.methods[name] = method 502 env.AddMethod(method) 503 504 def remove_methods(self, env): 505 """ 506 Removes the methods that were added by the tool initialization 507 so we no longer copy and re-bind them when the construction 508 environment gets cloned. 509 """ 510 for method in self.methods.values(): 511 env.RemoveMethod(method) 512 513 def apply_tools(self, env): 514 """ 515 Searches the list of associated Tool modules for one that 516 exists, and applies that to the construction environment. 517 """ 518 for t in self.tools: 519 tool = SCons.Tool.Tool(t) 520 if tool.exists(env): 521 env.Tool(tool) 522 return 523 524 # If we fall through here, there was no tool module found. 525 # This is where we can put an informative error message 526 # about the inability to find the tool. We'll start doing 527 # this as we cut over more pre-defined Builder+Tools to use 528 # the ToolInitializer class. 529 530def Initializers(env): 531 ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs']) 532 def Install(self, *args, **kw): 533 return self._InternalInstall(*args, **kw) 534 def InstallAs(self, *args, **kw): 535 return self._InternalInstallAs(*args, **kw) 536 env.AddMethod(Install) 537 env.AddMethod(InstallAs) 538 539def FindTool(tools, env): 540 for tool in tools: 541 t = Tool(tool) 542 if t.exists(env): 543 return tool 544 return None 545 546def FindAllTools(tools, env): 547 def ToolExists(tool, env=env): 548 return Tool(tool).exists(env) 549 return filter (ToolExists, tools) 550 551def tool_list(platform, env): 552 553 other_plat_tools=[] 554 # XXX this logic about what tool to prefer on which platform 555 # should be moved into either the platform files or 556 # the tool files themselves. 557 # The search orders here are described in the man page. If you 558 # change these search orders, update the man page as well. 559 if str(platform) == 'win32': 560 "prefer Microsoft tools on Windows" 561 linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ] 562 c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ] 563 cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ] 564 assemblers = ['masm', 'nasm', 'gas', '386asm' ] 565 fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran'] 566 ars = ['mslib', 'ar', 'tlib'] 567 other_plat_tools=['msvs','midl'] 568 elif str(platform) == 'os2': 569 "prefer IBM tools on OS/2" 570 linkers = ['ilink', 'gnulink', ]#'mslink'] 571 c_compilers = ['icc', 'gcc',]# 'msvc', 'cc'] 572 cxx_compilers = ['icc', 'g++',]# 'msvc', 'c++'] 573 assemblers = ['nasm',]# 'masm', 'gas'] 574 fortran_compilers = ['ifl', 'g77'] 575 ars = ['ar',]# 'mslib'] 576 elif str(platform) == 'irix': 577 "prefer MIPSPro on IRIX" 578 linkers = ['sgilink', 'gnulink'] 579 c_compilers = ['sgicc', 'gcc', 'cc'] 580 cxx_compilers = ['sgic++', 'g++', 'c++'] 581 assemblers = ['as', 'gas'] 582 fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] 583 ars = ['sgiar'] 584 elif str(platform) == 'sunos': 585 "prefer Forte tools on SunOS" 586 linkers = ['sunlink', 'gnulink'] 587 c_compilers = ['suncc', 'gcc', 'cc'] 588 cxx_compilers = ['sunc++', 'g++', 'c++'] 589 assemblers = ['as', 'gas'] 590 fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77', 591 'gfortran', 'g77', 'fortran'] 592 ars = ['sunar'] 593 elif str(platform) == 'hpux': 594 "prefer aCC tools on HP-UX" 595 linkers = ['hplink', 'gnulink'] 596 c_compilers = ['hpcc', 'gcc', 'cc'] 597 cxx_compilers = ['hpc++', 'g++', 'c++'] 598 assemblers = ['as', 'gas'] 599 fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran'] 600 ars = ['ar'] 601 elif str(platform) == 'aix': 602 "prefer AIX Visual Age tools on AIX" 603 linkers = ['aixlink', 'gnulink'] 604 c_compilers = ['aixcc', 'gcc', 'cc'] 605 cxx_compilers = ['aixc++', 'g++', 'c++'] 606 assemblers = ['as', 'gas'] 607 fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran'] 608 ars = ['ar'] 609 elif str(platform) == 'darwin': 610 "prefer GNU tools on Mac OS X, except for some linkers and IBM tools" 611 linkers = ['applelink', 'gnulink'] 612 c_compilers = ['gcc', 'cc'] 613 cxx_compilers = ['g++', 'c++'] 614 assemblers = ['as'] 615 fortran_compilers = ['gfortran', 'f95', 'f90', 'g77'] 616 ars = ['ar'] 617 else: 618 "prefer GNU tools on all other platforms" 619 linkers = ['gnulink', 'mslink', 'ilink'] 620 c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc'] 621 cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++'] 622 assemblers = ['gas', 'nasm', 'masm'] 623 fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77'] 624 ars = ['ar', 'mslib'] 625 626 c_compiler = FindTool(c_compilers, env) or c_compilers[0] 627 628 # XXX this logic about what tool provides what should somehow be 629 # moved into the tool files themselves. 630 if c_compiler and c_compiler == 'mingw': 631 # MinGW contains a linker, C compiler, C++ compiler, 632 # Fortran compiler, archiver and assembler: 633 cxx_compiler = None 634 linker = None 635 assembler = None 636 fortran_compiler = None 637 ar = None 638 else: 639 # Don't use g++ if the C compiler has built-in C++ support: 640 if c_compiler in ('msvc', 'intelc', 'icc'): 641 cxx_compiler = None 642 else: 643 cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0] 644 linker = FindTool(linkers, env) or linkers[0] 645 assembler = FindTool(assemblers, env) or assemblers[0] 646 fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0] 647 ar = FindTool(ars, env) or ars[0] 648 649 other_tools = FindAllTools(['BitKeeper', 'CVS', 650 'dmd', 651 'filesystem', 652 'dvipdf', 'dvips', 'gs', 653 'jar', 'javac', 'javah', 654 'latex', 'lex', 655 'm4', #'midl', 'msvs', 656 'pdflatex', 'pdftex', 'Perforce', 657 'RCS', 'rmic', 'rpcgen', 658 'SCCS', 659 # 'Subversion', 660 'swig', 661 'tar', 'tex', 662 'yacc', 'zip', 'rpm', 'wix']+other_plat_tools, 663 env) 664 665 tools = ([linker, c_compiler, cxx_compiler, 666 fortran_compiler, assembler, ar] 667 + other_tools) 668 669 return filter(lambda x: x, tools) 670 671# Local Variables: 672# tab-width:4 673# indent-tabs-mode:nil 674# End: 675# vim: set expandtab tabstop=4 shiftwidth=4: 676