OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 from optparse import OptionParser | 6 from optparse import OptionParser |
7 import os | 7 import os |
8 import subprocess | 8 import subprocess |
9 import sys | 9 import sys |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 elif sys.platform.startswith('darwin'): | 74 elif sys.platform.startswith('darwin'): |
75 self.osname = 'mac' | 75 self.osname = 'mac' |
76 else: | 76 else: |
77 ErrOut('Toolchain OS %s not supported.' % sys.platform) | 77 ErrOut('Toolchain OS %s not supported.' % sys.platform) |
78 | 78 |
79 if arch in ['x86-32', 'x86-64']: | 79 if arch in ['x86-32', 'x86-64']: |
80 self.arch = arch | 80 self.arch = arch |
81 self.mainarch = 'x86' | 81 self.mainarch = 'x86' |
82 self.subarch = arch.split('-')[1] | 82 self.subarch = arch.split('-')[1] |
83 tool_subdir = 'x86_64-nacl' | 83 tool_subdir = 'x86_64-nacl' |
| 84 self.pnacl = False |
| 85 elif arch == 'arm': |
| 86 self.arch = arch |
| 87 self.mainarch = 'arm' |
| 88 self.subarch = '' |
| 89 self.pnacl = True |
84 else: | 90 else: |
85 ErrOut('Toolchain architecture %s not supported.' % arch) | 91 ErrOut('Toolchain architecture %s not supported.' % arch) |
86 | 92 |
| 93 if arch == 'arm' and toolname == 'glibc': |
| 94 ErrOut('arm/glibc not yet supported.') |
| 95 |
87 if toolname == 'newlib': | 96 if toolname == 'newlib': |
88 toolchain = '%s_%s_newlib' % (self.osname, self.mainarch) | 97 toolchain = '%s_%s_newlib' % (self.osname, self.mainarch) |
89 self.toolname = 'newlib' | 98 self.toolname = 'newlib' |
90 elif toolname == 'glibc': | 99 elif toolname == 'glibc': |
91 toolchain = '%s_%s' % (self.osname, self.mainarch) | 100 toolchain = '%s_%s' % (self.osname, self.mainarch) |
92 self.toolname = 'glibc' | 101 self.toolname = 'glibc' |
93 else: | 102 else: |
94 ErrOut('Toolchain of type %s not supported.' % toolname) | 103 ErrOut('Toolchain of type %s not supported.' % toolname) |
95 | 104 |
96 self.root_path = options.root | 105 self.root_path = options.root |
97 self.nacl_path = os.path.join(self.root_path, 'native_client') | 106 self.nacl_path = os.path.join(self.root_path, 'native_client') |
98 | 107 |
99 project_path, project_name = os.path.split(options.name) | 108 project_path, project_name = os.path.split(options.name) |
100 self.outdir = options.objdir | 109 self.outdir = options.objdir |
101 | 110 |
102 # Set the toolchain directories | 111 # Set the toolchain directories |
103 self.toolchain = self.GenNaClPath(os.path.join('toolchain', toolchain)) | 112 if self.pnacl: |
104 self.toolbin = os.path.join(self.toolchain, tool_subdir, 'bin') | 113 pnacldir = 'pnacl_%s_x86_64' % self.osname |
105 self.toollib = os.path.join(self.toolchain, tool_subdir, 'lib'+self.subarch) | 114 self.toolchain = self.GenNaClPath(os.path.join('toolchain', |
106 self.toolinc = os.path.join(self.toolchain, tool_subdir, 'include') | 115 pnacldir, |
| 116 self.toolname)) |
| 117 self.toolbin = os.path.join(self.toolchain, 'bin') |
| 118 self.toollib = os.path.join(self.toolchain, 'lib') |
| 119 self.toolinc = os.path.join(self.toolchain, 'sysroot', 'include') |
| 120 else: |
| 121 self.toolchain = self.GenNaClPath(os.path.join('toolchain', |
| 122 toolchain)) |
| 123 self.toolbin = os.path.join(self.toolchain, tool_subdir, 'bin') |
| 124 self.toollib = os.path.join(self.toolchain, |
| 125 tool_subdir, |
| 126 'lib' + self.subarch) |
| 127 self.toolinc = os.path.join(self.toolchain, tool_subdir, 'include') |
107 | 128 |
108 self.inc_paths = ArgToList(options.incdirs) | 129 self.inc_paths = ArgToList(options.incdirs) |
109 self.lib_paths = ArgToList(options.libdirs) | 130 self.lib_paths = ArgToList(options.libdirs) |
110 | 131 |
111 self.name = options.name | 132 self.name = options.name |
112 self.BuildCompileOptions(options.compile_flags, options.defines) | 133 self.BuildCompileOptions(options.compile_flags, options.defines) |
113 self.BuildLinkOptions(options.link_flags) | 134 self.BuildLinkOptions(options.link_flags) |
114 self.BuildArchiveOptions() | 135 self.BuildArchiveOptions() |
115 self.verbose = options.verbose | 136 self.verbose = options.verbose |
116 self.suffix = options.suffix | 137 self.suffix = options.suffix |
117 self.strip = options.strip | 138 self.strip = options.strip |
118 self.empty = options.empty | 139 self.empty = options.empty |
119 self.strip_debug = options.strip_debug | 140 self.strip_debug = options.strip_debug |
120 | 141 |
121 if self.verbose: | 142 if self.verbose: |
122 print 'Compile options: %s' % self.compile_options | 143 print 'Compile options: %s' % self.compile_options |
123 print 'Linker options: %s' % self.link_options | 144 print 'Linker options: %s' % self.link_options |
124 | 145 |
125 def GenNaClPath(self, path): | 146 def GenNaClPath(self, path): |
126 """Helper which prepends path with the native client source directory.""" | 147 """Helper which prepends path with the native client source directory.""" |
127 return os.path.join(self.root_path, 'native_client', path) | 148 return os.path.join(self.root_path, 'native_client', path) |
128 | 149 |
129 def GetBinName(self, name): | 150 def GetBinName(self, name): |
130 """Helper which prepends executable with the toolchain bin directory.""" | 151 """Helper which prepends executable with the toolchain bin directory.""" |
131 return os.path.join(self.toolbin, name) | 152 return os.path.join(self.toolbin, name) |
132 | 153 |
| 154 def GetCCompiler(self): |
| 155 """Helper which returns C compiler path.""" |
| 156 if self.pnacl: |
| 157 return self.GetBinName('pnacl-clang') |
| 158 else: |
| 159 return self.GetBinName('gcc') |
| 160 |
| 161 def GetCXXCompiler(self): |
| 162 """Helper which returns C++ compiler path.""" |
| 163 if self.pnacl: |
| 164 return self.GetBinName('pnacl-clang++') |
| 165 else: |
| 166 return self.GetBinName('g++') |
| 167 |
| 168 def GetAr(self): |
| 169 """Helper which returns ar path.""" |
| 170 if self.pnacl: |
| 171 return self.GetBinName('pnacl-ar') |
| 172 else: |
| 173 return self.GetBinName('ar') |
| 174 |
| 175 def GetStrip(self): |
| 176 """Helper which returns strip path.""" |
| 177 if self.pnacl: |
| 178 return self.GetBinName('pnacl-strip') |
| 179 else: |
| 180 return self.GetBinName('strip') |
| 181 |
133 def BuildAssembleOptions(self, options): | 182 def BuildAssembleOptions(self, options): |
134 options = ArgToList(options) | 183 options = ArgToList(options) |
135 self.assemble_options = options + ['-I' + name for name in self.inc_paths] | 184 self.assemble_options = options + ['-I' + name for name in self.inc_paths] |
136 | 185 |
137 def BuildCompileOptions(self, options, defines): | 186 def BuildCompileOptions(self, options, defines): |
138 """Generates compile options, called once by __init__.""" | 187 """Generates compile options, called once by __init__.""" |
139 options = ArgToList(options) | 188 options = ArgToList(options) |
140 options += ['-D' + define for define in defines] | 189 options += ['-D' + define for define in defines] |
141 self.compile_options = options + ['-I' + name for name in self.inc_paths] | 190 self.compile_options = options + ['-I' + name for name in self.inc_paths] |
142 | 191 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 230 |
182 def CleanOutput(self, out): | 231 def CleanOutput(self, out): |
183 if os.path.isfile(out): | 232 if os.path.isfile(out): |
184 os.remove(out) | 233 os.remove(out) |
185 | 234 |
186 def Compile(self, src): | 235 def Compile(self, src): |
187 """Compile the source with pre-determined options.""" | 236 """Compile the source with pre-determined options.""" |
188 | 237 |
189 filename, ext = os.path.splitext(src) | 238 filename, ext = os.path.splitext(src) |
190 if ext == '.c' or ext == '.S': | 239 if ext == '.c' or ext == '.S': |
191 bin_name = self.GetBinName('gcc') | 240 bin_name = self.GetCCompiler() |
192 extra = ['-std=gnu99'] | 241 extra = ['-std=gnu99'] |
| 242 if self.pnacl and ext == '.S': |
| 243 extra.append('-arch') |
| 244 extra.append(self.arch) |
193 elif ext == '.cc': | 245 elif ext == '.cc': |
194 bin_name = self.GetBinName('g++') | 246 bin_name = self.GetCXXCompiler() |
195 extra = [] | 247 extra = [] |
196 else: | 248 else: |
197 if self.verbose and ext != '.h': | 249 if self.verbose and ext != '.h': |
198 print 'Skipping unknown type %s for %s.' % (ext, src) | 250 print 'Skipping unknown type %s for %s.' % (ext, src) |
199 return None | 251 return None |
200 | 252 |
201 if self.verbose: | 253 if self.verbose: |
202 print '\nCompile %s' % src | 254 print '\nCompile %s' % src |
203 | 255 |
204 out = self.GetObjectName(src) | 256 out = self.GetObjectName(src) |
205 MakeDir(os.path.dirname(out)) | 257 MakeDir(os.path.dirname(out)) |
206 self.CleanOutput(out) | 258 self.CleanOutput(out) |
207 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options | 259 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options |
208 err = self.Run(cmd_line, out) | 260 err = self.Run(cmd_line, out) |
209 if sys.platform.startswith('win') and err == 5: | 261 if sys.platform.startswith('win') and err == 5: |
210 # Try again on mystery windows failure. | 262 # Try again on mystery windows failure. |
211 err = self.Run(cmd_line, out) | 263 err = self.Run(cmd_line, out) |
212 if err: | 264 if err: |
213 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 265 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
214 return out | 266 return out |
215 | 267 |
216 def Link(self, srcs): | 268 def Link(self, srcs): |
217 """Link these objects with predetermined options and output name.""" | 269 """Link these objects with predetermined options and output name.""" |
218 out = self.name | 270 out = self.name |
219 if self.verbose: | 271 if self.verbose: |
220 print '\nLink %s' % out | 272 print '\nLink %s' % out |
221 bin_name = self.GetBinName('g++') | 273 bin_name = self.GetCXXCompiler() |
222 MakeDir(os.path.dirname(out)) | 274 MakeDir(os.path.dirname(out)) |
223 self.CleanOutput(out) | 275 self.CleanOutput(out) |
224 | 276 |
225 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 277 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
226 if not self.empty: | 278 if not self.empty: |
227 cmd_line += srcs | 279 cmd_line += srcs |
228 cmd_line += self.link_options | 280 cmd_line += self.link_options |
229 | 281 |
230 err = self.Run(cmd_line, out) | 282 err = self.Run(cmd_line, out) |
231 # TODO( Retry on windows | 283 # TODO( Retry on windows |
232 if sys.platform.startswith('win') and err == 5: | 284 if sys.platform.startswith('win') and err == 5: |
233 # Try again on mystery windows failure. | 285 # Try again on mystery windows failure. |
234 err = self.Run(cmd_line, out) | 286 err = self.Run(cmd_line, out) |
235 if err: | 287 if err: |
236 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 288 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
237 return out | 289 return out |
238 | 290 |
239 def Archive(self, srcs): | 291 def Archive(self, srcs): |
240 """Archive these objects with predetermined options and output name.""" | 292 """Archive these objects with predetermined options and output name.""" |
241 out = self.name | 293 out = self.name |
242 if self.verbose: | 294 if self.verbose: |
243 print '\nArchive %s' % out | 295 print '\nArchive %s' % out |
244 | 296 |
245 | 297 |
246 if '-r' in self.link_options: | 298 if '-r' in self.link_options: |
247 bin_name = self.GetBinName('g++') | 299 bin_name = self.GetCXXCompiler() |
248 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 300 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
249 if not self.empty: | 301 if not self.empty: |
250 cmd_line += srcs | 302 cmd_line += srcs |
251 cmd_line += self.link_options | 303 cmd_line += self.link_options |
252 else: | 304 else: |
253 bin_name = self.GetBinName('ar') | 305 bin_name = self.GetAr() |
254 cmd_line = [bin_name, '-rc', out] | 306 cmd_line = [bin_name, '-rc', out] |
255 if not self.empty: | 307 if not self.empty: |
256 cmd_line += srcs | 308 cmd_line += srcs |
257 | 309 |
258 MakeDir(os.path.dirname(out)) | 310 MakeDir(os.path.dirname(out)) |
259 self.CleanOutput(out) | 311 self.CleanOutput(out) |
260 err = self.Run(cmd_line, out) | 312 err = self.Run(cmd_line, out) |
261 if sys.platform.startswith('win') and err == 5: | 313 if sys.platform.startswith('win') and err == 5: |
262 # Try again on mystery windows failure. | 314 # Try again on mystery windows failure. |
263 err = self.Run(cmd_line, out) | 315 err = self.Run(cmd_line, out) |
264 if err: | 316 if err: |
265 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 317 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
266 return out | 318 return out |
267 | 319 |
268 def Strip(self, out): | 320 def Strip(self, out): |
269 """Strip the NEXE""" | 321 """Strip the NEXE""" |
270 if self.verbose: | 322 if self.verbose: |
271 print '\nStrip %s' % out | 323 print '\nStrip %s' % out |
272 | 324 |
273 tmp = out + '.tmp' | 325 tmp = out + '.tmp' |
274 self.CleanOutput(tmp) | 326 self.CleanOutput(tmp) |
275 os.rename(out, tmp) | 327 os.rename(out, tmp) |
276 bin_name = self.GetBinName('strip') | 328 bin_name = self.GetStrip() |
277 cmd_line = [bin_name, '--strip-debug', tmp, '-o', out] | 329 cmd_line = [bin_name, '--strip-debug', tmp, '-o', out] |
278 err = self.Run(cmd_line, out) | 330 err = self.Run(cmd_line, out) |
279 if sys.platform.startswith('win') and err == 5: | 331 if sys.platform.startswith('win') and err == 5: |
280 # Try again on mystery windows failure. | 332 # Try again on mystery windows failure. |
281 err = self.Run(cmd_line, out) | 333 err = self.Run(cmd_line, out) |
282 if err: | 334 if err: |
283 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 335 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
284 return out | 336 return out |
285 | 337 |
286 def Generate(self, srcs): | 338 def Generate(self, srcs): |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 out = build.Compile(filename) | 395 out = build.Compile(filename) |
344 if out: | 396 if out: |
345 objs.append(out) | 397 objs.append(out) |
346 # Do not link if building an object | 398 # Do not link if building an object |
347 if not options.compile_only: | 399 if not options.compile_only: |
348 build.Generate(objs) | 400 build.Generate(objs) |
349 return 0 | 401 return 0 |
350 | 402 |
351 if __name__ == '__main__': | 403 if __name__ == '__main__': |
352 sys.exit(Main(sys.argv)) | 404 sys.exit(Main(sys.argv)) |
353 | |
OLD | NEW |