blob: 1cb55fa2cfe705bdebdeb39b0fd368d71689bd60 [file] [log] [blame]
Daniel Dunbar11672ec2009-01-13 18:51:26 +00001import Arguments
Daniel Dunbar43124722009-01-10 02:07:54 +00002import Phases
3import Tools
4
5###
6
7class ToolChain(object):
8 """ToolChain - Provide mappings of Actions to Tools."""
9
10 def __init__(self, driver):
11 self.driver = driver
12
13 def selectTool(self, action):
14 """selectTool - Return a Tool instance to use for handling
15 some particular action."""
16 abstract
17
Daniel Dunbar11672ec2009-01-13 18:51:26 +000018 def translateArgs(self, args, arch):
19 """translateArgs - Callback to allow argument translation for
20 an entire toolchain."""
21
22 # FIXME: Would be nice to move arch handling out of generic
23 # code.
24 if arch:
25 archName = args.getValue(arch)
26 al = Arguments.DerivedArgList(args)
27 for arg in args.args:
28 if arg.opt is args.parser.archOption:
29 if arg is arch:
30 al.append(arg)
31 elif arg.opt is args.parser.XarchOption:
32 if args.getJoinedValue(arg) == archName:
33 # FIXME: Fix this.
34 arg = args.parser.lookupOptForArg(Arguments.InputIndex(0, arg.index.pos + 1),
35 args.getSeparateValue(arg),
36 iter([]))
37 al.append(arg)
38 else:
39 al.append(arg)
40 return al
41 else:
42 return args
43
Daniel Dunbar9c257c32009-01-12 04:21:12 +000044class Darwin_X86_ToolChain(ToolChain):
45 def __init__(self, driver, darwinVersion, gccVersion):
46 super(Darwin_X86_ToolChain, self).__init__(driver)
Daniel Dunbar9cb22532009-01-12 07:45:49 +000047 assert isinstance(darwinVersion, tuple) and len(darwinVersion) == 3
48 assert isinstance(gccVersion, tuple) and len(gccVersion) == 3
49 self.darwinVersion = darwinVersion
50 self.gccVersion = gccVersion
51
Daniel Dunbar43124722009-01-10 02:07:54 +000052 self.toolMap = {
53 Phases.PreprocessPhase : Tools.GCC_PreprocessTool(),
Daniel Dunbar11672ec2009-01-13 18:51:26 +000054 Phases.CompilePhase : Tools.Darwin_X86_CompileTool(self),
Daniel Dunbar43124722009-01-10 02:07:54 +000055 Phases.PrecompilePhase : Tools.GCC_PrecompileTool(),
Daniel Dunbar9cb22532009-01-12 07:45:49 +000056 Phases.AssemblePhase : Tools.Darwin_AssembleTool(self),
57 Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self),
Daniel Dunbar43124722009-01-10 02:07:54 +000058 Phases.LipoPhase : Tools.LipoTool(),
59 }
60
Daniel Dunbar9cb22532009-01-12 07:45:49 +000061 def getToolChainDir(self):
62 return 'i686-apple-darwin%d/%s' % (self.darwinVersion[0],
63 '.'.join(map(str,self.gccVersion)))
64
65 def getProgramPath(self, name):
66 # FIXME: Implement proper search.
67 return '/usr/libexec/gcc/%s/%s' % (self.getToolChainDir(), name)
68
Daniel Dunbardff9f502009-01-12 18:51:02 +000069 def getMacosxVersionMin(self):
70 major,minor,minorminor = self.darwinVersion
71 return '%d.%d.%d' % (10, major-4, minor)
72
Daniel Dunbar43124722009-01-10 02:07:54 +000073 def selectTool(self, action):
74 assert isinstance(action, Phases.JobAction)
75 return self.toolMap[action.phase.__class__]
76
Daniel Dunbar25d4a8f2009-01-13 21:07:43 +000077 def translateArgs(self, args, arch):
78 args = super(Darwin_X86_ToolChain, self).translateArgs(args, arch)
79
80 # If arch hasn't been bound we don't need to do anything yet.
81 if not arch:
82 return args
83
84 al = Arguments.DerivedArgList(args)
85 if not args.getLastArg(args.parser.m_macosxVersionMinOption):
86 al.append(al.makeJoinedArg(self.getMacosxVersionMin(),
87 args.parser.m_macosxVersionMinOption))
88 for arg in args:
89 if arg.opt is args.parser.f_constantCfstringsOption:
90 al.append(al.makeFlagArg(args.parser.m_constantCfstringsOption))
91 elif arg.opt is args.parser.f_noConstantCfstringsOption:
92 al.append(al.makeFlagArg(args.parser.m_noConstantCfstringsOption))
93 elif arg.opt is args.parser.WnonportableCfstringsOption:
94 al.append(al.makeFlagArg(args.parser.m_warnNonportableCfstringsOption))
95 elif arg.opt is args.parser.WnoNonportableCfstringsOption:
96 al.append(al.makeFlagArg(args.parser.m_noWarnNonportableCfstringsOption))
97 elif arg.opt is args.parser.f_pascalStringsOption:
98 al.append(al.makeFlagArg(args.parser.m_pascalStringsOption))
99 elif arg.opt is args.parser.f_noPascalStringsOption:
100 al.append(al.makeFlagArg(args.parser.m_noPascalStringsOption))
101 else:
102 al.append(arg)
103
104 # FIXME: Actually, gcc always adds this, but it is filtered
105 # for duplicates somewhere. This also changes the order of
106 # things, so look it up.
107 if arch and args.getValue(arch) == 'x86_64':
108 if not args.getLastArg(args.parser.m_64Option):
109 al.append(al.makeFlagArg(args.parser.m_64Option))
110
111 if not args.getLastArg(args.parser.m_tuneOption):
112 al.append(al.makeJoinedArg('core2',
113 args.parser.m_tuneOption))
114
115 return al
116
Daniel Dunbar43124722009-01-10 02:07:54 +0000117class Generic_GCC_ToolChain(ToolChain):
118 """Generic_GCC_ToolChain - A tool chain using the 'gcc' command to
119 perform all subcommands; this relies on gcc translating the
120 options appropriately."""
121
122 def __init__(self, driver):
123 super(Generic_GCC_ToolChain, self).__init__(driver)
124 self.toolMap = {
125 Phases.PreprocessPhase : Tools.GCC_PreprocessTool(),
126 Phases.CompilePhase : Tools.GCC_CompileTool(),
127 Phases.PrecompilePhase : Tools.GCC_PrecompileTool(),
128 Phases.AssemblePhase : Tools.GCC_AssembleTool(),
129 Phases.LinkPhase : Tools.GCC_LinkTool(),
130 }
131
132 def selectTool(self, action):
133 assert isinstance(action, Phases.JobAction)
134 return self.toolMap[action.phase.__class__]