5 This looks for modules that define a callable object that can modify
6 a construction environment as appropriate for a given tool (or tool
9 Note that because this subsysem just *selects* a callable that can
10 modify a construction environment, it's possible for people to define
11 their own "tool specification" in an arbitrary callable function. No
12 one needs to use or tie in to this subsystem in order to roll their own
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:
27 # The above copyright notice and this permission notice shall be included
28 # in all copies or substantial portions of the Software.
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.
39 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
48 def __init__(self, name):
54 def Tool(name, platform = None):
55 """Select a canned Tool specification.
57 full_name = 'SCons.Tool.' + name
58 if not sys.modules.has_key(full_name):
60 file, path, desc = imp.find_module(name,
61 sys.modules['SCons.Tool'].__path__)
62 imp.load_module(full_name, file, path, desc)
64 raise SCons.Errors.UserError, "No tool named '%s'" % name
68 spec.__call__ = sys.modules[full_name].generate
69 spec.exists = sys.modules[full_name].exists
72 def createObjBuilders(env):
73 """This is a utility function that creates the Object
74 and SharedObject Builders in an Environment if they
75 are not there already.
77 If they are there already, we return the existing ones.
79 This is a separate function because soooo many Tools
80 use this functionality.
82 The return is a 2-tuple of (StaticObject, SharedObject)
86 static_obj = env['BUILDERS']['Object']
88 static_obj = SCons.Defaults.StaticObject()
89 env['BUILDERS']['Object'] = static_obj
90 env['BUILDERS']['StaticObject'] = static_obj
93 shared_obj = env['BUILDERS']['SharedObject']
95 shared_obj = SCons.Defaults.SharedObject()
96 env['BUILDERS']['SharedObject'] = shared_obj
98 return (static_obj, shared_obj)
100 def createCFileBuilders(env):
101 """This is a utility function that creates the CFile/CXXFile
102 Builders in an Environment if they
103 are not there already.
105 If they are there already, we return the existing ones.
107 This is a separate function because soooo many Tools
108 use this functionality.
110 The return is a 2-tuple of (CFile, CXXFile)
114 c_file = env['BUILDERS']['CFile']
116 c_file = SCons.Defaults.CFile()
117 env['BUILDERS']['CFile'] = c_file
118 env['CFILESUFFIX'] = '.c'
121 cxx_file = env['BUILDERS']['CXXFile']
123 cxx_file = SCons.Defaults.CXXFile()
124 env['BUILDERS']['CXXFile'] = cxx_file
125 env['CXXFILESUFFIX'] = '.cc'
127 return (c_file, cxx_file)
129 def FindTool(tools, env):
136 def FindAllTools(tools, env):
137 def ToolExists(tool, env=env):
138 return Tool(tool).exists(env)
139 return filter (ToolExists, tools)
141 def tool_list(platform, env):
143 # XXX this logic about what tool to prefer on which platform
144 # should be moved into either the platform files or
145 # the tool files themselves.
146 if str(platform) == 'win32':
147 "prefer Microsoft tools on Windows"
148 linkers = ['mslink', 'gnulink', 'ilink', 'linkloc' ]
149 c_compilers = ['msvc', 'mingw', 'gcc', 'icc' ]
150 assemblers = ['masm', 'nasm', 'gas', '386asm' ]
151 fortran_compilers = ['g77', 'ifl']
152 ars = ['mslib', 'ar']
153 elif str(platform) == 'os2':
154 "prefer IBM tools on OS/2"
155 linkers = ['ilink', 'gnulink', 'mslink']
156 c_compilers = ['icc', 'gcc', 'msvc']
157 assemblers = ['nasm', 'masm', 'gas']
158 fortran_compilers = ['ifl', 'g77']
159 ars = ['ar', 'mslib']
161 "prefer GNU tools on all other platforms"
162 linkers = ['gnulink', 'mslink', 'ilink']
163 c_compilers = ['gcc', 'msvc', 'icc']
164 assemblers = ['gas', 'nasm', 'masm']
165 fortran_compilers = ['g77', 'ifl']
166 ars = ['ar', 'mslib']
168 c_compiler = FindTool(c_compilers, env) or c_compilers[0]
170 # XXX this logic about what tool provides what should somehow be
171 # moved into the tool files themselves.
172 if c_compiler and c_compiler == 'mingw':
173 # MinGW contains a linker, C compiler, C++ compiler,
174 # Fortran compiler, archiver and assember:
177 fortran_compiler = None
181 linker = FindTool(linkers, env) or linkers[0]
182 assembler = FindTool(assemblers, env) or assemblers[0]
183 fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0]
184 ar = FindTool(ars, env) or ars[0]
186 # Don't use g++ if the C compiler has built-in C++ support:
187 if c_compiler and (c_compiler == 'msvc' or c_compiler == 'icc'):
190 cxx_compiler = FindTool(['g++'], env)
192 other_tools = FindAllTools(['dvipdf', 'dvips',
194 'pdflatex', 'pdftex',
195 'tar', 'tex', 'yacc'], env)
197 tools = ([linker, c_compiler, cxx_compiler,
198 fortran_compiler, assembler, ar]
201 return filter(lambda x: x, tools)