blob: ea35de9502c0944549bbdbdaaf6c1b356bb78ef3 [file] [log] [blame]
Daniel Dunbarf677a602009-01-21 02:03:52 +00001import os
2
Daniel Dunbarb3492762009-01-13 18:51:26 +00003import Arguments
Daniel Dunbar08dea462009-01-10 02:07:54 +00004import Phases
5import Tools
Daniel Dunbar7c2f91b2009-01-14 01:03:36 +00006import Types
Daniel Dunbar08dea462009-01-10 02:07:54 +00007
8###
9
10class ToolChain(object):
11 """ToolChain - Provide mappings of Actions to Tools."""
12
Daniel Dunbard47bf282009-02-20 01:36:35 +000013 def __init__(self, driver, archName,
Daniel Dunbarf677a602009-01-21 02:03:52 +000014 filePathPrefixes=[],
15 programPathPrefixes=[]):
Daniel Dunbar08dea462009-01-10 02:07:54 +000016 self.driver = driver
Daniel Dunbard47bf282009-02-20 01:36:35 +000017 self.archName = archName
Daniel Dunbarf677a602009-01-21 02:03:52 +000018 self.filePathPrefixes = list(filePathPrefixes)
19 self.programPathPrefixes = list(programPathPrefixes)
20
21 def getFilePath(self, name):
22 return self.driver.getFilePath(name, self)
23
24 def getProgramPath(self, name):
25 return self.driver.getProgramPath(name, self)
Daniel Dunbar08dea462009-01-10 02:07:54 +000026
27 def selectTool(self, action):
28 """selectTool - Return a Tool instance to use for handling
29 some particular action."""
30 abstract
31
Daniel Dunbarb3492762009-01-13 18:51:26 +000032 def translateArgs(self, args, arch):
33 """translateArgs - Callback to allow argument translation for
34 an entire toolchain."""
35
36 # FIXME: Would be nice to move arch handling out of generic
37 # code.
38 if arch:
39 archName = args.getValue(arch)
40 al = Arguments.DerivedArgList(args)
41 for arg in args.args:
42 if arg.opt is args.parser.archOption:
43 if arg is arch:
44 al.append(arg)
45 elif arg.opt is args.parser.XarchOption:
46 if args.getJoinedValue(arg) == archName:
47 # FIXME: Fix this.
48 arg = args.parser.lookupOptForArg(Arguments.InputIndex(0, arg.index.pos + 1),
49 args.getSeparateValue(arg),
50 iter([]))
51 al.append(arg)
52 else:
53 al.append(arg)
54 return al
55 else:
56 return args
57
Daniel Dunbar72999172009-01-29 23:54:06 +000058 def shouldUseClangCompiler(self, action):
59 # If user requested no clang, or this isn't a "compile" phase,
60 # or this isn't a C family option, then don't use clang.
61 if (self.driver.cccNoClang or
62 not isinstance(action.phase, (Phases.PreprocessPhase,
63 Phases.CompilePhase,
64 Phases.SyntaxOnlyPhase,
65 Phases.EmitLLVMPhase,
66 Phases.PrecompilePhase)) or
67 action.inputs[0].type not in Types.cTypesSet):
68 return False
69
70 if self.driver.cccNoClangPreprocessor:
71 if isinstance(action.phase, Phases.PreprocessPhase):
72 return False
73
74 if self.driver.cccNoClangCXX:
75 if action.inputs[0].type in Types.cxxTypesSet:
76 return False
Daniel Dunbar51b15612009-02-20 01:48:01 +000077
78 # Don't use clang if this isn't one of the user specified
79 # archs to build.
80 if (self.driver.cccClangArchs and
81 self.archName not in self.driver.cccClangArchs):
82 return False
Daniel Dunbar72999172009-01-29 23:54:06 +000083
84 return True
85
Daniel Dunbar43e66e12009-02-17 00:42:05 +000086 def isMathErrnoDefault(self):
87 return True
88
Daniel Dunbar32db2c12009-02-20 07:35:04 +000089 def isUnwindTablesDefault(self):
90 # FIXME: Target hook.
91 if self.archName == 'x86_64':
92 return True
93 return False
94
Daniel Dunbar3a54cd22009-02-20 06:48:26 +000095 def getRelocationModel(self, picEnabled, picDisabled):
96 if picEnabled:
97 return 'pic'
98 return 'static'
99
Daniel Dunbarc2148562009-01-12 04:21:12 +0000100class Darwin_X86_ToolChain(ToolChain):
Daniel Dunbard47bf282009-02-20 01:36:35 +0000101 def __init__(self, driver, archName, darwinVersion, gccVersion):
102 super(Darwin_X86_ToolChain, self).__init__(driver, archName)
Daniel Dunbar2dda5412009-01-12 07:45:49 +0000103 assert isinstance(darwinVersion, tuple) and len(darwinVersion) == 3
104 assert isinstance(gccVersion, tuple) and len(gccVersion) == 3
105 self.darwinVersion = darwinVersion
106 self.gccVersion = gccVersion
107
Daniel Dunbar90c72cd2009-01-21 01:07:49 +0000108 self.clangTool = Tools.Clang_CompileTool(self)
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000109 cc = Tools.Darwin_X86_CompileTool(self)
Daniel Dunbar08dea462009-01-10 02:07:54 +0000110 self.toolMap = {
Daniel Dunbar7d494092009-01-20 00:47:24 +0000111 Phases.PreprocessPhase : Tools.Darwin_X86_PreprocessTool(self),
Daniel Dunbar90c72cd2009-01-21 01:07:49 +0000112 Phases.AnalyzePhase : self.clangTool,
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000113 Phases.SyntaxOnlyPhase : cc,
114 Phases.EmitLLVMPhase : cc,
115 Phases.CompilePhase : cc,
116 Phases.PrecompilePhase : cc,
Daniel Dunbar2dda5412009-01-12 07:45:49 +0000117 Phases.AssemblePhase : Tools.Darwin_AssembleTool(self),
118 Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self),
Daniel Dunbar302b9672009-02-20 01:30:38 +0000119 Phases.LipoPhase : Tools.LipoTool(self),
Daniel Dunbar08dea462009-01-10 02:07:54 +0000120 }
121
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000122 if archName == 'x86_64':
123 self.filePathPrefixes.append(os.path.join(self.driver.driverDir,
124 '../lib/gcc',
125 self.getToolChainDir(),
126 'x86_64'))
127 self.filePathPrefixes.append(os.path.join('/usr/lib/gcc',
128 self.getToolChainDir(),
129 'x86_64'))
Daniel Dunbarf677a602009-01-21 02:03:52 +0000130 self.filePathPrefixes.append(os.path.join(self.driver.driverDir,
131 '../lib/gcc',
132 self.getToolChainDir()))
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000133 self.filePathPrefixes.append(os.path.join('/usr/lib/gcc',
Daniel Dunbarf677a602009-01-21 02:03:52 +0000134 self.getToolChainDir()))
135
136 self.programPathPrefixes.append(os.path.join(self.driver.driverDir,
137 '../libexec/gcc',
138 self.getToolChainDir()))
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000139 self.programPathPrefixes.append(os.path.join('/usr/libexec/gcc',
140 self.getToolChainDir()))
Daniel Dunbarf677a602009-01-21 02:03:52 +0000141 self.programPathPrefixes.append(self.driver.driverDir)
142
Daniel Dunbar2dda5412009-01-12 07:45:49 +0000143 def getToolChainDir(self):
144 return 'i686-apple-darwin%d/%s' % (self.darwinVersion[0],
145 '.'.join(map(str,self.gccVersion)))
146
Daniel Dunbarbafb8f42009-01-12 18:51:02 +0000147 def getMacosxVersionMin(self):
148 major,minor,minorminor = self.darwinVersion
149 return '%d.%d.%d' % (10, major-4, minor)
150
Daniel Dunbar08dea462009-01-10 02:07:54 +0000151 def selectTool(self, action):
152 assert isinstance(action, Phases.JobAction)
Daniel Dunbar7c2f91b2009-01-14 01:03:36 +0000153
Daniel Dunbar72999172009-01-29 23:54:06 +0000154 if self.shouldUseClangCompiler(action):
155 return self.clangTool
Daniel Dunbar7c2f91b2009-01-14 01:03:36 +0000156
Daniel Dunbar08dea462009-01-10 02:07:54 +0000157 return self.toolMap[action.phase.__class__]
158
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000159 def translateArgs(self, args, arch):
160 args = super(Darwin_X86_ToolChain, self).translateArgs(args, arch)
161
162 # If arch hasn't been bound we don't need to do anything yet.
163 if not arch:
164 return args
165
Daniel Dunbar7e184602009-01-16 20:25:36 +0000166 # FIXME: We really want to get out of the tool chain level
167 # argument translation business, as it makes the driver
168 # functionality much more opaque. For now, we follow gcc
169 # closely solely for the purpose of easily achieving feature
170 # parity & testability. Once we have something that works, we
171 # should reevaluate each translation and try to push it down
172 # into tool specific logic.
173
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000174 al = Arguments.DerivedArgList(args)
175 if not args.getLastArg(args.parser.m_macosxVersionMinOption):
176 al.append(al.makeJoinedArg(self.getMacosxVersionMin(),
177 args.parser.m_macosxVersionMinOption))
178 for arg in args:
Daniel Dunbar7e184602009-01-16 20:25:36 +0000179 # Sob. These is strictly gcc compatible for the time
180 # being. Apple gcc translates options twice, which means
181 # that self-expanding options add duplicates.
182 if arg.opt is args.parser.m_kernelOption:
183 al.append(arg)
184 al.append(al.makeFlagArg(args.parser.staticOption))
185 al.append(al.makeFlagArg(args.parser.staticOption))
186 elif arg.opt is args.parser.dependencyFileOption:
187 al.append(al.makeSeparateArg(args.getValue(arg),
188 args.parser.MFOption))
189 elif arg.opt is args.parser.gfullOption:
190 al.append(al.makeFlagArg(args.parser.gOption))
191 al.append(al.makeFlagArg(args.parser.f_noEliminateUnusedDebugSymbolsOption))
192 elif arg.opt is args.parser.gusedOption:
193 al.append(al.makeFlagArg(args.parser.gOption))
194 al.append(al.makeFlagArg(args.parser.f_eliminateUnusedDebugSymbolsOption))
195 elif arg.opt is args.parser.f_appleKextOption:
196 al.append(arg)
197 al.append(al.makeFlagArg(args.parser.staticOption))
198 al.append(al.makeFlagArg(args.parser.staticOption))
199 elif arg.opt is args.parser.f_terminatedVtablesOption:
200 al.append(al.makeFlagArg(args.parser.f_appleKextOption))
201 al.append(al.makeFlagArg(args.parser.staticOption))
202 elif arg.opt is args.parser.f_indirectVirtualCallsOption:
203 al.append(al.makeFlagArg(args.parser.f_appleKextOption))
204 al.append(al.makeFlagArg(args.parser.staticOption))
Daniel Dunbar039b1d02009-02-06 19:18:58 +0000205 elif arg.opt is args.parser.sharedOption:
206 al.append(al.makeFlagArg(args.parser.dynamiclibOption))
Daniel Dunbar7e184602009-01-16 20:25:36 +0000207 elif arg.opt is args.parser.f_constantCfstringsOption:
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000208 al.append(al.makeFlagArg(args.parser.m_constantCfstringsOption))
209 elif arg.opt is args.parser.f_noConstantCfstringsOption:
210 al.append(al.makeFlagArg(args.parser.m_noConstantCfstringsOption))
211 elif arg.opt is args.parser.WnonportableCfstringsOption:
212 al.append(al.makeFlagArg(args.parser.m_warnNonportableCfstringsOption))
213 elif arg.opt is args.parser.WnoNonportableCfstringsOption:
214 al.append(al.makeFlagArg(args.parser.m_noWarnNonportableCfstringsOption))
215 elif arg.opt is args.parser.f_pascalStringsOption:
216 al.append(al.makeFlagArg(args.parser.m_pascalStringsOption))
217 elif arg.opt is args.parser.f_noPascalStringsOption:
218 al.append(al.makeFlagArg(args.parser.m_noPascalStringsOption))
219 else:
220 al.append(arg)
221
222 # FIXME: Actually, gcc always adds this, but it is filtered
223 # for duplicates somewhere. This also changes the order of
224 # things, so look it up.
225 if arch and args.getValue(arch) == 'x86_64':
226 if not args.getLastArg(args.parser.m_64Option):
227 al.append(al.makeFlagArg(args.parser.m_64Option))
228
229 if not args.getLastArg(args.parser.m_tuneOption):
230 al.append(al.makeJoinedArg('core2',
231 args.parser.m_tuneOption))
232
233 return al
234
Daniel Dunbar43e66e12009-02-17 00:42:05 +0000235 def isMathErrnoDefault(self):
236 return False
237
Daniel Dunbar3a54cd22009-02-20 06:48:26 +0000238 def getRelocationModel(self, picEnabled, picDisabled):
239 if self.archName == 'x86_64':
240 return 'pic'
241
242 if picEnabled:
243 return 'pic'
244 elif picDisabled:
245 return 'static'
246 else:
247 return 'dynamic-no-pic'
248
Daniel Dunbar08dea462009-01-10 02:07:54 +0000249class Generic_GCC_ToolChain(ToolChain):
250 """Generic_GCC_ToolChain - A tool chain using the 'gcc' command to
251 perform all subcommands; this relies on gcc translating the
252 options appropriately."""
253
Daniel Dunbard47bf282009-02-20 01:36:35 +0000254 def __init__(self, driver, archName):
255 super(Generic_GCC_ToolChain, self).__init__(driver, archName)
Daniel Dunbar302b9672009-02-20 01:30:38 +0000256 cc = Tools.GCC_CompileTool(self)
Daniel Dunbaref993d12009-01-29 06:12:22 +0000257 self.clangTool = Tools.Clang_CompileTool(self)
Daniel Dunbar08dea462009-01-10 02:07:54 +0000258 self.toolMap = {
Daniel Dunbar302b9672009-02-20 01:30:38 +0000259 Phases.PreprocessPhase : Tools.GCC_PreprocessTool(self),
Daniel Dunbaref993d12009-01-29 06:12:22 +0000260 Phases.AnalyzePhase : self.clangTool,
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000261 Phases.SyntaxOnlyPhase : cc,
262 Phases.EmitLLVMPhase : cc,
263 Phases.CompilePhase : cc,
Daniel Dunbar302b9672009-02-20 01:30:38 +0000264 Phases.PrecompilePhase : Tools.GCC_PrecompileTool(self),
265 Phases.AssemblePhase : Tools.GCC_AssembleTool(self),
266 Phases.LinkPhase : Tools.GCC_LinkTool(self),
Daniel Dunbar08dea462009-01-10 02:07:54 +0000267 }
268
269 def selectTool(self, action):
270 assert isinstance(action, Phases.JobAction)
Daniel Dunbaref993d12009-01-29 06:12:22 +0000271
Daniel Dunbar72999172009-01-29 23:54:06 +0000272 if self.shouldUseClangCompiler(action):
273 return self.clangTool
Daniel Dunbaref993d12009-01-29 06:12:22 +0000274
Daniel Dunbar08dea462009-01-10 02:07:54 +0000275 return self.toolMap[action.phase.__class__]
Daniel Dunbar3a54cd22009-02-20 06:48:26 +0000276
277class Darwin_GCC_ToolChain(Generic_GCC_ToolChain):
278 def getRelocationModel(self, picEnabled, picDisabled):
279 if picEnabled:
280 return 'pic'
281 elif picDisabled:
282 return 'static'
283 else:
284 return 'dynamic-no-pic'
285