OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2011 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 = 0 |
| 85 elif arch == 'arm': |
| 86 self.arch = arch |
| 87 self.mainarch = 'arm' |
| 88 self.subarch = '' |
| 89 self.pnacl = 1 |
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.' % toolname) |
| 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 self.toolchain = self.GenNaClPath(os.path.join('toolchain', |
105 self.toollib = os.path.join(self.toolchain, tool_subdir, 'lib'+self.subarch) | 114 'pnacl_linux_x86_64', |
106 self.toolinc = os.path.join(self.toolchain, tool_subdir, 'include') | 115 self.toolname)) |
| 116 self.toolbin = os.path.join(self.toolchain, 'bin') |
| 117 self.toollib = os.path.join(self.toolchain, 'lib') |
| 118 self.toolinc = os.path.join(self.toolchain, 'sysroot', 'include') |
| 119 else: |
| 120 self.toolchain = self.GenNaClPath(os.path.join('toolchain', |
| 121 toolchain)) |
| 122 self.toolbin = os.path.join(self.toolchain, tool_subdir, 'bin') |
| 123 self.toollib = os.path.join(self.toolchain, |
| 124 tool_subdir, |
| 125 'lib'+self.subarch) |
| 126 self.toolinc = os.path.join(self.toolchain, tool_subdir, 'include') |
107 | 127 |
108 self.inc_paths = ArgToList(options.incdirs) | 128 self.inc_paths = ArgToList(options.incdirs) |
109 self.lib_paths = ArgToList(options.libdirs) | 129 self.lib_paths = ArgToList(options.libdirs) |
110 | 130 |
111 self.name = options.name | 131 self.name = options.name |
112 self.BuildCompileOptions(options.compile_flags, options.defines) | 132 self.BuildCompileOptions(options.compile_flags, options.defines) |
113 self.BuildLinkOptions(options.link_flags) | 133 self.BuildLinkOptions(options.link_flags) |
114 self.BuildArchiveOptions() | 134 self.BuildArchiveOptions() |
115 self.verbose = options.verbose | 135 self.verbose = options.verbose |
116 self.suffix = options.suffix | 136 self.suffix = options.suffix |
117 self.strip = options.strip | 137 self.strip = options.strip |
118 self.empty = options.empty | 138 self.empty = options.empty |
119 self.strip_debug = options.strip_debug | 139 self.strip_debug = options.strip_debug |
120 | 140 |
121 if self.verbose: | 141 if self.verbose: |
122 print 'Compile options: %s' % self.compile_options | 142 print 'Compile options: %s' % self.compile_options |
123 print 'Linker options: %s' % self.link_options | 143 print 'Linker options: %s' % self.link_options |
124 | 144 |
125 def GenNaClPath(self, path): | 145 def GenNaClPath(self, path): |
126 """Helper which prepends path with the native client source directory.""" | 146 """Helper which prepends path with the native client source directory.""" |
127 return os.path.join(self.root_path, 'native_client', path) | 147 return os.path.join(self.root_path, 'native_client', path) |
128 | 148 |
129 def GetBinName(self, name): | 149 def GetBinName(self, name): |
130 """Helper which prepends executable with the toolchain bin directory.""" | 150 """Helper which prepends executable with the toolchain bin directory.""" |
131 return os.path.join(self.toolbin, name) | 151 return os.path.join(self.toolbin, name) |
132 | 152 |
| 153 def GetCCompiler(self): |
| 154 """Helper which returns C compiler path.""" |
| 155 if self.pnacl: |
| 156 return self.GetBinName("pnacl-clang") |
| 157 else: |
| 158 return self.GetBinName("gcc") |
| 159 |
| 160 def GetCXXCompiler(self): |
| 161 """Helper which returns C++ compiler path.""" |
| 162 if self.pnacl: |
| 163 return self.GetBinName("pnacl-clang++") |
| 164 else: |
| 165 return self.GetBinName("g++") |
| 166 |
| 167 def GetAr(self): |
| 168 """Helper which returns ar path.""" |
| 169 if self.pnacl: |
| 170 return self.GetBinName("pnacl-ar") |
| 171 else: |
| 172 return self.GetBinName("ar") |
| 173 |
133 def BuildAssembleOptions(self, options): | 174 def BuildAssembleOptions(self, options): |
134 options = ArgToList(options) | 175 options = ArgToList(options) |
135 self.assemble_options = options + ['-I' + name for name in self.inc_paths] | 176 self.assemble_options = options + ['-I' + name for name in self.inc_paths] |
136 | 177 |
137 def BuildCompileOptions(self, options, defines): | 178 def BuildCompileOptions(self, options, defines): |
138 """Generates compile options, called once by __init__.""" | 179 """Generates compile options, called once by __init__.""" |
139 options = ArgToList(options) | 180 options = ArgToList(options) |
140 options += ['-D' + define for define in defines] | 181 options += ['-D' + define for define in defines] |
141 self.compile_options = options + ['-I' + name for name in self.inc_paths] | 182 self.compile_options = options + ['-I' + name for name in self.inc_paths] |
142 | 183 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 222 |
182 def CleanOutput(self, out): | 223 def CleanOutput(self, out): |
183 if os.path.isfile(out): | 224 if os.path.isfile(out): |
184 os.remove(out) | 225 os.remove(out) |
185 | 226 |
186 def Compile(self, src): | 227 def Compile(self, src): |
187 """Compile the source with pre-determined options.""" | 228 """Compile the source with pre-determined options.""" |
188 | 229 |
189 filename, ext = os.path.splitext(src) | 230 filename, ext = os.path.splitext(src) |
190 if ext == '.c' or ext == '.S': | 231 if ext == '.c' or ext == '.S': |
191 bin_name = self.GetBinName('gcc') | 232 bin_name = self.GetCCompiler() |
192 extra = ['-std=gnu99'] | 233 extra = ['-std=gnu99'] |
| 234 if self.pnacl and ext == '.S': |
| 235 extra.append('-arch') |
| 236 extra.append(self.arch) |
193 elif ext == '.cc': | 237 elif ext == '.cc': |
194 bin_name = self.GetBinName('g++') | 238 bin_name = self.GetCXXCompiler() |
195 extra = [] | 239 extra = [] |
196 else: | 240 else: |
197 if self.verbose and ext != '.h': | 241 if self.verbose and ext != '.h': |
198 print 'Skipping unknown type %s for %s.' % (ext, src) | 242 print 'Skipping unknown type %s for %s.' % (ext, src) |
199 return None | 243 return None |
200 | 244 |
201 if self.verbose: | 245 if self.verbose: |
202 print '\nCompile %s' % src | 246 print '\nCompile %s' % src |
203 | 247 |
204 out = self.GetObjectName(src) | 248 out = self.GetObjectName(src) |
205 MakeDir(os.path.dirname(out)) | 249 MakeDir(os.path.dirname(out)) |
206 self.CleanOutput(out) | 250 self.CleanOutput(out) |
207 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options | 251 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options |
208 err = self.Run(cmd_line, out) | 252 err = self.Run(cmd_line, out) |
209 if sys.platform.startswith('win') and err == 5: | 253 if sys.platform.startswith('win') and err == 5: |
210 # Try again on mystery windows failure. | 254 # Try again on mystery windows failure. |
211 err = self.Run(cmd_line, out) | 255 err = self.Run(cmd_line, out) |
212 if err: | 256 if err: |
213 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 257 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
214 return out | 258 return out |
215 | 259 |
216 def Link(self, srcs): | 260 def Link(self, srcs): |
217 """Link these objects with predetermined options and output name.""" | 261 """Link these objects with predetermined options and output name.""" |
218 out = self.name | 262 out = self.name |
219 if self.verbose: | 263 if self.verbose: |
220 print '\nLink %s' % out | 264 print '\nLink %s' % out |
221 bin_name = self.GetBinName('g++') | 265 bin_name = self.GetCXXCompiler() |
222 MakeDir(os.path.dirname(out)) | 266 MakeDir(os.path.dirname(out)) |
223 self.CleanOutput(out) | 267 self.CleanOutput(out) |
224 | 268 |
225 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 269 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
226 if not self.empty: | 270 if not self.empty: |
227 cmd_line += srcs | 271 cmd_line += srcs |
228 cmd_line += self.link_options | 272 cmd_line += self.link_options |
229 | 273 |
230 err = self.Run(cmd_line, out) | 274 err = self.Run(cmd_line, out) |
231 # TODO( Retry on windows | 275 # TODO( Retry on windows |
232 if sys.platform.startswith('win') and err == 5: | 276 if sys.platform.startswith('win') and err == 5: |
233 # Try again on mystery windows failure. | 277 # Try again on mystery windows failure. |
234 err = self.Run(cmd_line, out) | 278 err = self.Run(cmd_line, out) |
235 if err: | 279 if err: |
236 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 280 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
237 return out | 281 return out |
238 | 282 |
239 def Archive(self, srcs): | 283 def Archive(self, srcs): |
240 """Archive these objects with predetermined options and output name.""" | 284 """Archive these objects with predetermined options and output name.""" |
241 out = self.name | 285 out = self.name |
242 if self.verbose: | 286 if self.verbose: |
243 print '\nArchive %s' % out | 287 print '\nArchive %s' % out |
244 | 288 |
245 | 289 |
246 if '-r' in self.link_options: | 290 if '-r' in self.link_options: |
247 bin_name = self.GetBinName('g++') | 291 bin_name = self.GetCXXCompiler() |
248 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 292 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
249 if not self.empty: | 293 if not self.empty: |
250 cmd_line += srcs | 294 cmd_line += srcs |
251 cmd_line += self.link_options | 295 cmd_line += self.link_options |
252 else: | 296 else: |
253 bin_name = self.GetBinName('ar') | 297 bin_name = self.GetAr() |
254 cmd_line = [bin_name, '-rc', out] | 298 cmd_line = [bin_name, '-rc', out] |
255 if not self.empty: | 299 if not self.empty: |
256 cmd_line += srcs | 300 cmd_line += srcs |
257 | 301 |
258 MakeDir(os.path.dirname(out)) | 302 MakeDir(os.path.dirname(out)) |
259 self.CleanOutput(out) | 303 self.CleanOutput(out) |
260 err = self.Run(cmd_line, out) | 304 err = self.Run(cmd_line, out) |
261 if sys.platform.startswith('win') and err == 5: | 305 if sys.platform.startswith('win') and err == 5: |
262 # Try again on mystery windows failure. | 306 # Try again on mystery windows failure. |
263 err = self.Run(cmd_line, out) | 307 err = self.Run(cmd_line, out) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 out = build.Compile(filename) | 387 out = build.Compile(filename) |
344 if out: | 388 if out: |
345 objs.append(out) | 389 objs.append(out) |
346 # Do not link if building an object | 390 # Do not link if building an object |
347 if not options.compile_only: | 391 if not options.compile_only: |
348 build.Generate(objs) | 392 build.Generate(objs) |
349 return 0 | 393 return 0 |
350 | 394 |
351 if __name__ == '__main__': | 395 if __name__ == '__main__': |
352 sys.exit(Main(sys.argv)) | 396 sys.exit(Main(sys.argv)) |
353 | |
OLD | NEW |