| 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 import tempfile | 10 import tempfile |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 return self.GetBinName('g++') | 200 return self.GetBinName('g++') |
| 201 | 201 |
| 202 def GetAr(self): | 202 def GetAr(self): |
| 203 """Helper which returns ar path.""" | 203 """Helper which returns ar path.""" |
| 204 return self.GetBinName('ar') | 204 return self.GetBinName('ar') |
| 205 | 205 |
| 206 def GetStrip(self): | 206 def GetStrip(self): |
| 207 """Helper which returns strip path.""" | 207 """Helper which returns strip path.""" |
| 208 return self.GetBinName('strip') | 208 return self.GetBinName('strip') |
| 209 | 209 |
| 210 def GetObjCopy(self): |
| 211 """Helper which returns objcopy path.""" |
| 212 return self.GetBinName('objcopy') |
| 213 |
| 210 def GetPnaclFinalize(self): | 214 def GetPnaclFinalize(self): |
| 211 """Helper which returns pnacl-finalize path.""" | 215 """Helper which returns pnacl-finalize path.""" |
| 212 assert self.is_pnacl_toolchain | 216 assert self.is_pnacl_toolchain |
| 213 return self.GetBinName('finalize') | 217 return self.GetBinName('finalize') |
| 214 | 218 |
| 215 def BuildAssembleOptions(self, options): | 219 def BuildAssembleOptions(self, options): |
| 216 options = ArgToList(options) | 220 options = ArgToList(options) |
| 217 self.assemble_options = options + ['-I' + name for name in self.inc_paths] | 221 self.assemble_options = options + ['-I' + name for name in self.inc_paths] |
| 218 | 222 |
| 223 def DebugName(self): |
| 224 return self.name + '.debug' |
| 225 |
| 226 def UntaggedName(self): |
| 227 return self.name + '.untagged' |
| 228 |
| 229 def LinkOutputName(self): |
| 230 if (self.is_pnacl_toolchain and self.finalize_pexe or |
| 231 self.strip_all or self.strip_debug): |
| 232 return self.DebugName() |
| 233 else: |
| 234 return self.name |
| 235 |
| 236 def ArchiveOutputName(self): |
| 237 if self.strip_debug: |
| 238 return self.DebugName() |
| 239 else: |
| 240 return self.name |
| 241 |
| 242 def StripOutputName(self): |
| 243 return self.name |
| 244 |
| 245 def TranslateOutputName(self): |
| 246 return self.name |
| 247 |
| 248 def Soname(self): |
| 249 return self.name |
| 250 |
| 219 def BuildCompileOptions(self, options, define_list): | 251 def BuildCompileOptions(self, options, define_list): |
| 220 """Generates compile options, called once by __init__.""" | 252 """Generates compile options, called once by __init__.""" |
| 221 options = ArgToList(options) | 253 options = ArgToList(options) |
| 222 # We want to shared gyp 'defines' with other targets, but not | 254 # We want to shared gyp 'defines' with other targets, but not |
| 223 # ones that are host system dependent. Filtering them out. | 255 # ones that are host system dependent. Filtering them out. |
| 224 # This really should be better. | 256 # This really should be better. |
| 225 # See: http://code.google.com/p/nativeclient/issues/detail?id=2936 | 257 # See: http://code.google.com/p/nativeclient/issues/detail?id=2936 |
| 226 define_list = [define for define in define_list | 258 define_list = [define for define in define_list |
| 227 if not (define.startswith('NACL_TARGET_ARCH=') or | 259 if not (define.startswith('NACL_TARGET_ARCH=') or |
| 228 define.startswith('NACL_TARGET_SUBARCH=') or | 260 define.startswith('NACL_TARGET_SUBARCH=') or |
| 229 define.startswith('NACL_WINDOWS=') or | 261 define.startswith('NACL_WINDOWS=') or |
| 230 define.startswith('NACL_OSX=') or | 262 define.startswith('NACL_OSX=') or |
| 231 define.startswith('NACL_LINUX=') or | 263 define.startswith('NACL_LINUX=') or |
| 232 define == 'COMPONENT_BUILD' or | 264 define == 'COMPONENT_BUILD' or |
| 233 'WIN32' in define or | 265 'WIN32' in define or |
| 234 'WINDOWS' in define or | 266 'WINDOWS' in define or |
| 235 'WINVER' in define)] | 267 'WINVER' in define)] |
| 236 define_list.extend(['NACL_WINDOWS=0', | 268 define_list.extend(['NACL_WINDOWS=0', |
| 237 'NACL_OSX=0', | 269 'NACL_OSX=0', |
| 238 'NACL_LINUX=0']) | 270 'NACL_LINUX=0']) |
| 239 options += ['-D' + define for define in define_list] | 271 options += ['-D' + define for define in define_list] |
| 240 self.compile_options = options + ['-I' + name for name in self.inc_paths] | 272 self.compile_options = options + ['-I' + name for name in self.inc_paths] |
| 241 | 273 |
| 242 def BuildLinkOptions(self, options): | 274 def BuildLinkOptions(self, options): |
| 243 """Generates link options, called once by __init__.""" | 275 """Generates link options, called once by __init__.""" |
| 244 options = ArgToList(options) | 276 options = ArgToList(options) |
| 245 if self.outtype == 'nso': | 277 if self.outtype == 'nso': |
| 246 options += ['-Wl,-rpath-link,' + name for name in self.lib_paths] | 278 options += ['-Wl,-rpath-link,' + name for name in self.lib_paths] |
| 247 options += ['-shared'] | 279 options += ['-shared'] |
| 248 options += ['-Wl,-soname,' + os.path.basename(self.name)] | 280 options += ['-Wl,-soname,' + os.path.basename(self.Soname())] |
| 249 self.link_options = options + ['-L' + name for name in self.lib_paths] | 281 self.link_options = options + ['-L' + name for name in self.lib_paths] |
| 250 | 282 |
| 251 def BuildArchiveOptions(self): | 283 def BuildArchiveOptions(self): |
| 252 """Generates link options, called once by __init__.""" | 284 """Generates link options, called once by __init__.""" |
| 253 self.archive_options = [] | 285 self.archive_options = [] |
| 254 | 286 |
| 255 def Log(self, msg): | 287 def Log(self, msg): |
| 256 if self.verbose: | 288 if self.verbose: |
| 257 print str(msg) | 289 print str(msg) |
| 258 | 290 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 if err: | 455 if err: |
| 424 self.CleanOutput(outd) | 456 self.CleanOutput(outd) |
| 425 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 457 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 426 elif self.NeedsRebuild(outd, out, src, True): | 458 elif self.NeedsRebuild(outd, out, src, True): |
| 427 ErrOut('\nFailed to compile %s to %s with deps %s and cmdline:\t%s' % | 459 ErrOut('\nFailed to compile %s to %s with deps %s and cmdline:\t%s' % |
| 428 (src, out, outd, ' '.join(cmd_line))) | 460 (src, out, outd, ' '.join(cmd_line))) |
| 429 return out | 461 return out |
| 430 | 462 |
| 431 def Link(self, srcs): | 463 def Link(self, srcs): |
| 432 """Link these objects with predetermined options and output name.""" | 464 """Link these objects with predetermined options and output name.""" |
| 433 out = self.name | 465 out = self.LinkOutputName() |
| 434 self.Log('\nLink %s' % out) | 466 self.Log('\nLink %s' % out) |
| 435 bin_name = self.GetCXXCompiler() | 467 bin_name = self.GetCXXCompiler() |
| 436 MakeDir(os.path.dirname(out)) | 468 MakeDir(os.path.dirname(out)) |
| 437 self.CleanOutput(out) | 469 self.CleanOutput(out) |
| 438 | 470 |
| 439 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 471 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
| 440 if not self.empty: | 472 if not self.empty: |
| 441 cmd_line += srcs | 473 cmd_line += srcs |
| 442 cmd_line += self.link_options | 474 cmd_line += self.link_options |
| 443 | 475 |
| 444 err = self.RunWithRetry(cmd_line, out) | 476 err = self.RunWithRetry(cmd_line, out) |
| 445 if err: | 477 if err: |
| 446 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 478 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 447 return out | 479 return out |
| 448 | 480 |
| 449 # For now, only support translating a pexe, and not .o file(s) | 481 # For now, only support translating a pexe, and not .o file(s) |
| 450 def Translate(self, src): | 482 def Translate(self, src): |
| 451 """Translate a pexe to a nexe.""" | 483 """Translate a pexe to a nexe.""" |
| 452 out = self.name | 484 out = self.TranslateOutputName() |
| 453 self.Log('\nTranslate %s' % out) | 485 self.Log('\nTranslate %s' % out) |
| 454 bin_name = self.GetBinName('translate') | 486 bin_name = self.GetBinName('translate') |
| 455 cmd_line = [bin_name, '-arch', self.arch, src, '-o', out] | 487 cmd_line = [bin_name, '-arch', self.arch, src, '-o', out] |
| 456 cmd_line += self.link_options | 488 cmd_line += self.link_options |
| 457 | 489 |
| 458 err = self.RunWithRetry(cmd_line, out) | 490 err = self.RunWithRetry(cmd_line, out) |
| 459 if err: | 491 if err: |
| 460 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 492 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 461 return out | 493 return out |
| 462 | 494 |
| 463 def Archive(self, srcs): | 495 def Archive(self, srcs): |
| 464 """Archive these objects with predetermined options and output name.""" | 496 """Archive these objects with predetermined options and output name.""" |
| 465 out = self.name | 497 out = self.ArchiveOutputName() |
| 466 self.Log('\nArchive %s' % out) | 498 self.Log('\nArchive %s' % out) |
| 467 | 499 |
| 468 if '-r' in self.link_options: | 500 if '-r' in self.link_options: |
| 469 bin_name = self.GetCXXCompiler() | 501 bin_name = self.GetCXXCompiler() |
| 470 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] | 502 cmd_line = [bin_name, '-o', out, '-Wl,--as-needed'] |
| 471 if not self.empty: | 503 if not self.empty: |
| 472 cmd_line += srcs | 504 cmd_line += srcs |
| 473 cmd_line += self.link_options | 505 cmd_line += self.link_options |
| 474 else: | 506 else: |
| 475 bin_name = self.GetAr() | 507 bin_name = self.GetAr() |
| 476 cmd_line = [bin_name, '-rc', out] | 508 cmd_line = [bin_name, '-rc', out] |
| 477 if not self.empty: | 509 if not self.empty: |
| 478 cmd_line += srcs | 510 cmd_line += srcs |
| 479 | 511 |
| 480 MakeDir(os.path.dirname(out)) | 512 MakeDir(os.path.dirname(out)) |
| 481 self.CleanOutput(out) | 513 self.CleanOutput(out) |
| 482 err = self.RunWithRetry(cmd_line, out) | 514 err = self.RunWithRetry(cmd_line, out) |
| 483 if err: | 515 if err: |
| 484 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 516 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 485 return out | 517 return out |
| 486 | 518 |
| 487 def Strip(self, out): | 519 def Strip(self, src): |
| 488 """Strip the NEXE""" | 520 """Strip the NEXE""" |
| 489 self.Log('\nStrip %s' % out) | 521 self.Log('\nStrip %s' % src) |
| 490 | 522 |
| 491 tmp = out + '.tmp' | 523 out = self.StripOutputName() |
| 492 self.CleanOutput(tmp) | 524 pre_debug_tagging = self.UntaggedName() |
| 493 os.rename(out, tmp) | 525 self.CleanOutput(out) |
| 494 bin_name = self.GetStrip() | 526 self.CleanOutput(pre_debug_tagging) |
| 527 |
| 528 # Strip from foo.debug to foo.untagged. |
| 529 strip_name = self.GetStrip() |
| 495 strip_option = '--strip-all' if self.strip_all else '--strip-debug' | 530 strip_option = '--strip-all' if self.strip_all else '--strip-debug' |
| 496 cmd_line = [bin_name, strip_option, tmp, '-o', out] | 531 cmd_line = [strip_name, strip_option, src, '-o', pre_debug_tagging] |
| 532 err = self.RunWithRetry(cmd_line, pre_debug_tagging) |
| 533 if err: |
| 534 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 535 |
| 536 # Tag with a debug link to foo.debug copying from foo.untagged to foo. |
| 537 objcopy_name = self.GetObjCopy() |
| 538 cmd_line = [objcopy_name, '--add-gnu-debuglink', src, |
| 539 pre_debug_tagging, out] |
| 497 err = self.RunWithRetry(cmd_line, out) | 540 err = self.RunWithRetry(cmd_line, out) |
| 498 if err: | 541 if err: |
| 499 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 542 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 543 |
| 544 # Drop the untagged intermediate. |
| 545 self.CleanOutput(pre_debug_tagging) |
| 546 |
| 500 return out | 547 return out |
| 501 | 548 |
| 502 def Finalize(self, out): | 549 def Finalize(self, src): |
| 503 """Finalize the PEXE""" | 550 """Finalize the PEXE""" |
| 504 self.Log('\nFinalize %s' % out) | 551 self.Log('\nFinalize %s' % src) |
| 505 | 552 |
| 506 tmp = out + '.nonfinal' | 553 out = self.StripOutputName() |
| 507 self.CleanOutput(tmp) | 554 self.CleanOutput(out) |
| 508 os.rename(out, tmp) | |
| 509 bin_name = self.GetPnaclFinalize() | 555 bin_name = self.GetPnaclFinalize() |
| 510 cmd_line = [bin_name, tmp, '-o', out] | 556 cmd_line = [bin_name, src, '-o', out] |
| 511 err = self.RunWithRetry(cmd_line, out) | 557 err = self.RunWithRetry(cmd_line, out) |
| 512 if err: | 558 if err: |
| 513 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) | 559 ErrOut('\nFAILED with %d: %s\n\n' % (err, ' '.join(cmd_line))) |
| 514 return out | 560 return out |
| 515 | 561 |
| 516 def Generate(self, srcs): | 562 def Generate(self, srcs): |
| 517 """Generate final output file. | 563 """Generate final output file. |
| 518 | 564 |
| 519 Link or Archive the final output file, from the compiled sources. | 565 Link or Archive the final output file, from the compiled sources. |
| 520 """ | 566 """ |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 out = build.Compile(filename) | 657 out = build.Compile(filename) |
| 612 if out: | 658 if out: |
| 613 objs.append(out) | 659 objs.append(out) |
| 614 # Do not link if building an object | 660 # Do not link if building an object |
| 615 if not options.compile_only: | 661 if not options.compile_only: |
| 616 build.Generate(objs) | 662 build.Generate(objs) |
| 617 return 0 | 663 return 0 |
| 618 | 664 |
| 619 if __name__ == '__main__': | 665 if __name__ == '__main__': |
| 620 sys.exit(Main(sys.argv)) | 666 sys.exit(Main(sys.argv)) |
| OLD | NEW |