blob: cda94083795cb00ece15ce3d842001afd59d210f [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 Dunbar3a54cd22009-02-20 06:48:26 +000089 def getRelocationModel(self, picEnabled, picDisabled):
90 if picEnabled:
91 return 'pic'
92 return 'static'
93
Daniel Dunbarc2148562009-01-12 04:21:12 +000094class Darwin_X86_ToolChain(ToolChain):
Daniel Dunbard47bf282009-02-20 01:36:35 +000095 def __init__(self, driver, archName, darwinVersion, gccVersion):
96 super(Darwin_X86_ToolChain, self).__init__(driver, archName)
Daniel Dunbar2dda5412009-01-12 07:45:49 +000097 assert isinstance(darwinVersion, tuple) and len(darwinVersion) == 3
98 assert isinstance(gccVersion, tuple) and len(gccVersion) == 3
99 self.darwinVersion = darwinVersion
100 self.gccVersion = gccVersion
101
Daniel Dunbar90c72cd2009-01-21 01:07:49 +0000102 self.clangTool = Tools.Clang_CompileTool(self)
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000103 cc = Tools.Darwin_X86_CompileTool(self)
Daniel Dunbar08dea462009-01-10 02:07:54 +0000104 self.toolMap = {
Daniel Dunbar7d494092009-01-20 00:47:24 +0000105 Phases.PreprocessPhase : Tools.Darwin_X86_PreprocessTool(self),
Daniel Dunbar90c72cd2009-01-21 01:07:49 +0000106 Phases.AnalyzePhase : self.clangTool,
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000107 Phases.SyntaxOnlyPhase : cc,
108 Phases.EmitLLVMPhase : cc,
109 Phases.CompilePhase : cc,
110 Phases.PrecompilePhase : cc,
Daniel Dunbar2dda5412009-01-12 07:45:49 +0000111 Phases.AssemblePhase : Tools.Darwin_AssembleTool(self),
112 Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self),
Daniel Dunbar302b9672009-02-20 01:30:38 +0000113 Phases.LipoPhase : Tools.LipoTool(self),
Daniel Dunbar08dea462009-01-10 02:07:54 +0000114 }
115
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000116 if archName == 'x86_64':
117 self.filePathPrefixes.append(os.path.join(self.driver.driverDir,
118 '../lib/gcc',
119 self.getToolChainDir(),
120 'x86_64'))
121 self.filePathPrefixes.append(os.path.join('/usr/lib/gcc',
122 self.getToolChainDir(),
123 'x86_64'))
Daniel Dunbarf677a602009-01-21 02:03:52 +0000124 self.filePathPrefixes.append(os.path.join(self.driver.driverDir,
125 '../lib/gcc',
126 self.getToolChainDir()))
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000127 self.filePathPrefixes.append(os.path.join('/usr/lib/gcc',
Daniel Dunbarf677a602009-01-21 02:03:52 +0000128 self.getToolChainDir()))
129
130 self.programPathPrefixes.append(os.path.join(self.driver.driverDir,
131 '../libexec/gcc',
132 self.getToolChainDir()))
Daniel Dunbare28f9e92009-01-21 17:18:19 +0000133 self.programPathPrefixes.append(os.path.join('/usr/libexec/gcc',
134 self.getToolChainDir()))
Daniel Dunbarf677a602009-01-21 02:03:52 +0000135 self.programPathPrefixes.append(self.driver.driverDir)
136
Daniel Dunbar2dda5412009-01-12 07:45:49 +0000137 def getToolChainDir(self):
138 return 'i686-apple-darwin%d/%s' % (self.darwinVersion[0],
139 '.'.join(map(str,self.gccVersion)))
140
Daniel Dunbarbafb8f42009-01-12 18:51:02 +0000141 def getMacosxVersionMin(self):
142 major,minor,minorminor = self.darwinVersion
143 return '%d.%d.%d' % (10, major-4, minor)
144
Daniel Dunbar08dea462009-01-10 02:07:54 +0000145 def selectTool(self, action):
146 assert isinstance(action, Phases.JobAction)
Daniel Dunbar7c2f91b2009-01-14 01:03:36 +0000147
Daniel Dunbar72999172009-01-29 23:54:06 +0000148 if self.shouldUseClangCompiler(action):
149 return self.clangTool
Daniel Dunbar7c2f91b2009-01-14 01:03:36 +0000150
Daniel Dunbar08dea462009-01-10 02:07:54 +0000151 return self.toolMap[action.phase.__class__]
152
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000153 def translateArgs(self, args, arch):
154 args = super(Darwin_X86_ToolChain, self).translateArgs(args, arch)
155
156 # If arch hasn't been bound we don't need to do anything yet.
157 if not arch:
158 return args
159
Daniel Dunbar7e184602009-01-16 20:25:36 +0000160 # FIXME: We really want to get out of the tool chain level
161 # argument translation business, as it makes the driver
162 # functionality much more opaque. For now, we follow gcc
163 # closely solely for the purpose of easily achieving feature
164 # parity & testability. Once we have something that works, we
165 # should reevaluate each translation and try to push it down
166 # into tool specific logic.
167
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000168 al = Arguments.DerivedArgList(args)
169 if not args.getLastArg(args.parser.m_macosxVersionMinOption):
170 al.append(al.makeJoinedArg(self.getMacosxVersionMin(),
171 args.parser.m_macosxVersionMinOption))
172 for arg in args:
Daniel Dunbar7e184602009-01-16 20:25:36 +0000173 # Sob. These is strictly gcc compatible for the time
174 # being. Apple gcc translates options twice, which means
175 # that self-expanding options add duplicates.
176 if arg.opt is args.parser.m_kernelOption:
177 al.append(arg)
178 al.append(al.makeFlagArg(args.parser.staticOption))
179 al.append(al.makeFlagArg(args.parser.staticOption))
180 elif arg.opt is args.parser.dependencyFileOption:
181 al.append(al.makeSeparateArg(args.getValue(arg),
182 args.parser.MFOption))
183 elif arg.opt is args.parser.gfullOption:
184 al.append(al.makeFlagArg(args.parser.gOption))
185 al.append(al.makeFlagArg(args.parser.f_noEliminateUnusedDebugSymbolsOption))
186 elif arg.opt is args.parser.gusedOption:
187 al.append(al.makeFlagArg(args.parser.gOption))
188 al.append(al.makeFlagArg(args.parser.f_eliminateUnusedDebugSymbolsOption))
189 elif arg.opt is args.parser.f_appleKextOption:
190 al.append(arg)
191 al.append(al.makeFlagArg(args.parser.staticOption))
192 al.append(al.makeFlagArg(args.parser.staticOption))
193 elif arg.opt is args.parser.f_terminatedVtablesOption:
194 al.append(al.makeFlagArg(args.parser.f_appleKextOption))
195 al.append(al.makeFlagArg(args.parser.staticOption))
196 elif arg.opt is args.parser.f_indirectVirtualCallsOption:
197 al.append(al.makeFlagArg(args.parser.f_appleKextOption))
198 al.append(al.makeFlagArg(args.parser.staticOption))
Daniel Dunbar039b1d02009-02-06 19:18:58 +0000199 elif arg.opt is args.parser.sharedOption:
200 al.append(al.makeFlagArg(args.parser.dynamiclibOption))
Daniel Dunbar7e184602009-01-16 20:25:36 +0000201 elif arg.opt is args.parser.f_constantCfstringsOption:
Daniel Dunbar6cb42052009-01-13 21:07:43 +0000202 al.append(al.makeFlagArg(args.parser.m_constantCfstringsOption))
203 elif arg.opt is args.parser.f_noConstantCfstringsOption:
204 al.append(al.makeFlagArg(args.parser.m_noConstantCfstringsOption))
205 elif arg.opt is args.parser.WnonportableCfstringsOption:
206 al.append(al.makeFlagArg(args.parser.m_warnNonportableCfstringsOption))
207 elif arg.opt is args.parser.WnoNonportableCfstringsOption:
208 al.append(al.makeFlagArg(args.parser.m_noWarnNonportableCfstringsOption))
209 elif arg.opt is args.parser.f_pascalStringsOption:
210 al.append(al.makeFlagArg(args.parser.m_pascalStringsOption))
211 elif arg.opt is args.parser.f_noPascalStringsOption:
212 al.append(al.makeFlagArg(args.parser.m_noPascalStringsOption))
213 else:
214 al.append(arg)
215
216 # FIXME: Actually, gcc always adds this, but it is filtered
217 # for duplicates somewhere. This also changes the order of
218 # things, so look it up.
219 if arch and args.getValue(arch) == 'x86_64':
220 if not args.getLastArg(args.parser.m_64Option):
221 al.append(al.makeFlagArg(args.parser.m_64Option))
222
223 if not args.getLastArg(args.parser.m_tuneOption):
224 al.append(al.makeJoinedArg('core2',
225 args.parser.m_tuneOption))
226
227 return al
228
Daniel Dunbar43e66e12009-02-17 00:42:05 +0000229 def isMathErrnoDefault(self):
230 return False
231
Daniel Dunbar3a54cd22009-02-20 06:48:26 +0000232 def getRelocationModel(self, picEnabled, picDisabled):
233 if self.archName == 'x86_64':
234 return 'pic'
235
236 if picEnabled:
237 return 'pic'
238 elif picDisabled:
239 return 'static'
240 else:
241 return 'dynamic-no-pic'
242
Daniel Dunbar08dea462009-01-10 02:07:54 +0000243class Generic_GCC_ToolChain(ToolChain):
244 """Generic_GCC_ToolChain - A tool chain using the 'gcc' command to
245 perform all subcommands; this relies on gcc translating the
246 options appropriately."""
247
Daniel Dunbard47bf282009-02-20 01:36:35 +0000248 def __init__(self, driver, archName):
249 super(Generic_GCC_ToolChain, self).__init__(driver, archName)
Daniel Dunbar302b9672009-02-20 01:30:38 +0000250 cc = Tools.GCC_CompileTool(self)
Daniel Dunbaref993d12009-01-29 06:12:22 +0000251 self.clangTool = Tools.Clang_CompileTool(self)
Daniel Dunbar08dea462009-01-10 02:07:54 +0000252 self.toolMap = {
Daniel Dunbar302b9672009-02-20 01:30:38 +0000253 Phases.PreprocessPhase : Tools.GCC_PreprocessTool(self),
Daniel Dunbaref993d12009-01-29 06:12:22 +0000254 Phases.AnalyzePhase : self.clangTool,
Daniel Dunbar34f60f62009-01-26 17:09:15 +0000255 Phases.SyntaxOnlyPhase : cc,
256 Phases.EmitLLVMPhase : cc,
257 Phases.CompilePhase : cc,
Daniel Dunbar302b9672009-02-20 01:30:38 +0000258 Phases.PrecompilePhase : Tools.GCC_PrecompileTool(self),
259 Phases.AssemblePhase : Tools.GCC_AssembleTool(self),
260 Phases.LinkPhase : Tools.GCC_LinkTool(self),
Daniel Dunbar08dea462009-01-10 02:07:54 +0000261 }
262
263 def selectTool(self, action):
264 assert isinstance(action, Phases.JobAction)
Daniel Dunbaref993d12009-01-29 06:12:22 +0000265
Daniel Dunbar72999172009-01-29 23:54:06 +0000266 if self.shouldUseClangCompiler(action):
267 return self.clangTool
Daniel Dunbaref993d12009-01-29 06:12:22 +0000268
Daniel Dunbar08dea462009-01-10 02:07:54 +0000269 return self.toolMap[action.phase.__class__]
Daniel Dunbar3a54cd22009-02-20 06:48:26 +0000270
271class Darwin_GCC_ToolChain(Generic_GCC_ToolChain):
272 def getRelocationModel(self, picEnabled, picDisabled):
273 if picEnabled:
274 return 'pic'
275 elif picDisabled:
276 return 'static'
277 else:
278 return 'dynamic-no-pic'
279