1 # Copyright (c) 2012 The Chromium OS Authors.
3 # See file CREDITS for list of people who contributed to this
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; either version 2 of
9 # the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 gcc: Full path to C compiler
33 path: Directory path containing C compiler
34 cross: Cross compile string, e.g. 'arm-linux-'
35 arch: Architecture of toolchain as determined from the first
36 component of the filename. E.g. arm-linux-gcc becomes arm
39 def __init__(self, fname, test, verbose=False):
40 """Create a new toolchain object.
43 fname: Filename of the gcc component
44 test: True to run the toolchain to test it
47 self.path = os.path.dirname(fname)
48 self.cross = os.path.basename(fname)[:-3]
49 pos = self.cross.find('-')
50 self.arch = self.cross[:pos] if pos != -1 else 'sandbox'
52 env = self.MakeEnvironment()
54 # As a basic sanity check, run the C compiler with --version
55 cmd = [fname, '--version']
57 result = command.RunPipe([cmd], capture=True, env=env)
58 self.ok = result.return_code == 0
60 print 'Tool chain test: ',
65 print 'Command: ', cmd
70 self.priority = self.GetPriority(fname)
72 def GetPriority(self, fname):
73 """Return the priority of the toolchain.
75 Toolchains are ranked according to their suitability by their
79 fname: Filename of toolchain
81 Priority of toolchain, 0=highest, 20=lowest.
83 priority_list = ['-elf', '-unknown-linux-gnu', '-linux', '-elf',
84 '-none-linux-gnueabi', '-uclinux', '-none-eabi',
85 '-gentoo-linux-gnu', '-linux-gnueabi', '-le-linux', '-uclinux']
86 for prio in range(len(priority_list)):
87 if priority_list[prio] in fname:
91 def MakeEnvironment(self):
92 """Returns an environment for using the toolchain.
94 Thie takes the current environment, adds CROSS_COMPILE and
95 augments PATH so that the toolchain will operate correctly.
97 env = dict(os.environ)
98 env['CROSS_COMPILE'] = self.cross
99 env['PATH'] += (':' + self.path)
104 """Manage a list of toolchains for building U-Boot
106 We select one toolchain for each architecture type
109 toolchains: Dict of Toolchain objects, keyed by architecture name
110 paths: List of paths to check for toolchains (may contain wildcards)
116 for name, value in bsettings.GetItems('toolchain'):
118 self.paths += glob.glob(value)
120 self.paths.append(value)
123 def Add(self, fname, test=True, verbose=False):
124 """Add a toolchain to our list
126 We select the given toolchain as our preferred one for its
127 architecture if it is a higher priority than the others.
130 fname: Filename of toolchain's gcc driver
131 test: True to run the toolchain to test it
133 toolchain = Toolchain(fname, test, verbose)
134 add_it = toolchain.ok
135 if toolchain.arch in self.toolchains:
136 add_it = (toolchain.priority <
137 self.toolchains[toolchain.arch].priority)
139 self.toolchains[toolchain.arch] = toolchain
141 def Scan(self, verbose):
142 """Scan for available toolchains and select the best for each arch.
144 We look for all the toolchains we can file, figure out the
145 architecture for each, and whether it works. Then we select the
146 highest priority toolchain for each arch.
149 verbose: True to print out progress information
151 if verbose: print 'Scanning for tool chains'
152 for path in self.paths:
153 if verbose: print " - scanning path '%s'" % path
154 for subdir in ['.', 'bin', 'usr/bin']:
155 dirname = os.path.join(path, subdir)
156 if verbose: print " - looking in '%s'" % dirname
157 for fname in glob.glob(dirname + '/*gcc'):
158 if verbose: print " - found '%s'" % fname
159 self.Add(fname, True, verbose)
162 """List out the selected toolchains for each architecture"""
163 print 'List of available toolchains (%d):' % len(self.toolchains)
164 if len(self.toolchains):
165 for key, value in sorted(self.toolchains.iteritems()):
166 print '%-10s: %s' % (key, value.gcc)
170 def Select(self, arch):
171 """Returns the toolchain for a given architecture
174 args: Name of architecture (e.g. 'arm', 'ppc_8xx')
177 toolchain object, or None if none found
179 for name, value in bsettings.GetItems('toolchain-alias'):
183 if not arch in self.toolchains:
184 raise ValueError, ("No tool chain found for arch '%s'" % arch)
185 return self.toolchains[arch]