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