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 pnacldir = 'pnacl_' + self.osname + '_x86_64' |
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 |
133 def BuildAssembleOptions(self, options): | 175 def BuildAssembleOptions(self, options): |
134 options = ArgToList(options) | 176 options = ArgToList(options) |
135 self.assemble_options = options + ['-I' + name for name in self.inc_paths] | 177 self.assemble_options = options + ['-I' + name for name in self.inc_paths] |
136 | 178 |
137 def BuildCompileOptions(self, options, defines): | 179 def BuildCompileOptions(self, options, defines): |
138 """Generates compile options, called once by __init__.""" | 180 """Generates compile options, called once by __init__.""" |
139 options = ArgToList(options) | 181 options = ArgToList(options) |
140 options += ['-D' + define for define in defines] | 182 options += ['-D' + define for define in defines] |
141 self.compile_options = options + ['-I' + name for name in self.inc_paths] | 183 self.compile_options = options + ['-I' + name for name in self.inc_paths] |
142 | 184 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 223 |
182 def CleanOutput(self, out): | 224 def CleanOutput(self, out): |
183 if os.path.isfile(out): | 225 if os.path.isfile(out): |
184 os.remove(out) | 226 os.remove(out) |
185 | 227 |
186 def Compile(self, src): | 228 def Compile(self, src): |
187 """Compile the source with pre-determined options.""" | 229 """Compile the source with pre-determined options.""" |
188 | 230 |
189 filename, ext = os.path.splitext(src) | 231 filename, ext = os.path.splitext(src) |
190 if ext == '.c' or ext == '.S': | 232 if ext == '.c' or ext == '.S': |
191 bin_name = self.GetBinName('gcc') | 233 bin_name = self.GetCCompiler() |
192 extra = ['-std=gnu99'] | 234 extra = ['-std=gnu99'] |
| 235 if self.pnacl and ext == '.S': |
| 236 extra.append('-arch') |
| 237 extra.append(self.arch) |
193 elif ext == '.cc': | 238 elif ext == '.cc': |
194 bin_name = self.GetBinName('g++') | 239 bin_name = self.GetCXXCompiler() |
195 extra = [] | 240 extra = [] |
196 else: | 241 else: |
197 if self.verbose and ext != '.h': | 242 if self.verbose and ext != '.h': |
198 print 'Skipping unknown type %s for %s.' % (ext, src) | 243 print 'Skipping unknown type %s for %s.' % (ext, src) |
199 return None | 244 return None |
200 | 245 |
201 if self.verbose: | 246 if self.verbose: |
202 print '\nCompile %s' % src | 247 print '\nCompile %s' % src |
203 | 248 |
204 out = self.GetObjectName(src) | 249 out = self.GetObjectName(src) |
205 MakeDir(os.path.dirname(out)) | 250 MakeDir(os.path.dirname(out)) |
206 self.CleanOutput(out) | 251 self.CleanOutput(out) |
207 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options | 252 cmd_line = [bin_name, '-c', src, '-o', out] + extra + self.compile_options |
208 err = self.Run(cmd_line, out) | 253 err = self.Run(cmd_line, out) |
209 if sys.platform.startswith('win') and err == 5: | 254 if sys.platform.startswith('win') and err == 5: |
210 # Try again on mystery windows failure. | 255 # Try again on mystery windows failure. |
211 err = self.Run(cmd_line, out) | 256 err = self.Run(cmd_line, out) |
212 if err: | 257 if err: |
213 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 258 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
214 return out | 259 return out |
215 | 260 |
216 def Link(self, srcs): | 261 def Link(self, srcs): |
217 """Link these objects with predetermined options and output name.""" | 262 """Link these objects with predetermined options and output name.""" |
218 out = self.name | 263 out = self.name |
219 if self.verbose: | 264 if self.verbose: |
220 print '\nLink %s' % out | 265 print '\nLink %s' % out |
221 bin_name = self.GetBinName('g++') | 266 bin_name = self.GetCXXCompiler() |
222 MakeDir(os.path.dirname(out)) | 267 MakeDir(os.path.dirname(out)) |
223 self.CleanOutput(out) | 268 self.CleanOutput(out) |
224 | 269 |
225 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 270 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
226 if not self.empty: | 271 if not self.empty: |
227 cmd_line += srcs | 272 cmd_line += srcs |
228 cmd_line += self.link_options | 273 cmd_line += self.link_options |
229 | 274 |
230 err = self.Run(cmd_line, out) | 275 err = self.Run(cmd_line, out) |
231 # TODO( Retry on windows | 276 # TODO( Retry on windows |
232 if sys.platform.startswith('win') and err == 5: | 277 if sys.platform.startswith('win') and err == 5: |
233 # Try again on mystery windows failure. | 278 # Try again on mystery windows failure. |
234 err = self.Run(cmd_line, out) | 279 err = self.Run(cmd_line, out) |
235 if err: | 280 if err: |
236 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 281 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
237 return out | 282 return out |
238 | 283 |
239 def Archive(self, srcs): | 284 def Archive(self, srcs): |
240 """Archive these objects with predetermined options and output name.""" | 285 """Archive these objects with predetermined options and output name.""" |
241 out = self.name | 286 out = self.name |
242 if self.verbose: | 287 if self.verbose: |
243 print '\nArchive %s' % out | 288 print '\nArchive %s' % out |
244 | 289 |
245 | 290 |
246 if '-r' in self.link_options: | 291 if '-r' in self.link_options: |
247 bin_name = self.GetBinName('g++') | 292 bin_name = self.GetCXXCompiler() |
248 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 293 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
249 if not self.empty: | 294 if not self.empty: |
250 cmd_line += srcs | 295 cmd_line += srcs |
251 cmd_line += self.link_options | 296 cmd_line += self.link_options |
252 else: | 297 else: |
253 bin_name = self.GetBinName('ar') | 298 bin_name = self.GetAr() |
254 cmd_line = [bin_name, '-rc', out] | 299 cmd_line = [bin_name, '-rc', out] |
255 if not self.empty: | 300 if not self.empty: |
256 cmd_line += srcs | 301 cmd_line += srcs |
257 | 302 |
258 MakeDir(os.path.dirname(out)) | 303 MakeDir(os.path.dirname(out)) |
259 self.CleanOutput(out) | 304 self.CleanOutput(out) |
260 err = self.Run(cmd_line, out) | 305 err = self.Run(cmd_line, out) |
261 if sys.platform.startswith('win') and err == 5: | 306 if sys.platform.startswith('win') and err == 5: |
262 # Try again on mystery windows failure. | 307 # Try again on mystery windows failure. |
263 err = self.Run(cmd_line, out) | 308 err = self.Run(cmd_line, out) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 out = build.Compile(filename) | 388 out = build.Compile(filename) |
344 if out: | 389 if out: |
345 objs.append(out) | 390 objs.append(out) |
346 # Do not link if building an object | 391 # Do not link if building an object |
347 if not options.compile_only: | 392 if not options.compile_only: |
348 build.Generate(objs) | 393 build.Generate(objs) |
349 return 0 | 394 return 0 |
350 | 395 |
351 if __name__ == '__main__': | 396 if __name__ == '__main__': |
352 sys.exit(Main(sys.argv)) | 397 sys.exit(Main(sys.argv)) |
353 | |
OLD | NEW |