OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium 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 """A tool to build chrome, executed by buildbot. | 6 """A tool to build chrome, executed by buildbot. |
7 | 7 |
8 When this is run, the current directory (cwd) should be the outer build | 8 When this is run, the current directory (cwd) should be the outer build |
9 directory (e.g., chrome-release/build/). | 9 directory (e.g., chrome-release/build/). |
10 | 10 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 if (not options.solution or | 428 if (not options.solution or |
429 os.path.splitext(options.solution)[1] != '.xcodeproj'): | 429 os.path.splitext(options.solution)[1] != '.xcodeproj'): |
430 options.solution = 'all.xcodeproj' | 430 options.solution = 'all.xcodeproj' |
431 command.extend(['-project', options.solution]) | 431 command.extend(['-project', options.solution]) |
432 | 432 |
433 if options.xcode_target: | 433 if options.xcode_target: |
434 command.extend(['-target', options.xcode_target]) | 434 command.extend(['-target', options.xcode_target]) |
435 | 435 |
436 # Note: this clobbers all targets, not just Debug or Release. | 436 # Note: this clobbers all targets, not just Debug or Release. |
437 if options.clobber: | 437 if options.clobber: |
438 build_output_dir = os.path.join(os.path.dirname(options.build_dir), | 438 clobber_dir = os.path.dirname(options.target_output_dir) |
439 'xcodebuild') | 439 print('Removing %s' % clobber_dir) |
440 print('Removing %s' % build_output_dir) | |
441 # Deleting output_dir would also delete all the .ninja files. iOS builds | 440 # Deleting output_dir would also delete all the .ninja files. iOS builds |
442 # generates ninja configuration inside the xcodebuild directory to be able | 441 # generates ninja configuration inside the xcodebuild directory to be able |
443 # to run sub builds. crbug.com/138950 is tracking this issue. | 442 # to run sub builds. crbug.com/138950 is tracking this issue. |
444 # Moreover clobbering should run before runhooks (which creates | 443 # Moreover clobbering should run before runhooks (which creates |
445 # .ninja files). For now, only delete all non-.ninja files. | 444 # .ninja files). For now, only delete all non-.ninja files. |
446 # TODO(thakis): Make "clobber" a step that runs before "runhooks". Once the | 445 # TODO(thakis): Make "clobber" a step that runs before "runhooks". Once the |
447 # master has been restarted, remove all clobber handling from compile.py. | 446 # master has been restarted, remove all clobber handling from compile.py. |
448 ninja_clobber(build_output_dir) | 447 ninja_clobber(clobber_dir) |
449 | 448 |
450 common_xcode_settings(command, options, env, options.compiler) | 449 common_xcode_settings(command, options, env, options.compiler) |
451 | 450 |
452 # Add on any remaining args | 451 # Add on any remaining args |
453 command.extend(args) | 452 command.extend(args) |
454 | 453 |
455 # Set up the filter before changing directories so the raw build log can | 454 # Set up the filter before changing directories so the raw build log can |
456 # be recorded. | 455 # be recorded. |
457 # Support a local file blocking filters (for debugging). Also check the | 456 # Support a local file blocking filters (for debugging). Also check the |
458 # Xcode version to make sure it is 3.2, as that is what the filter is coded | 457 # Xcode version to make sure it is 3.2, as that is what the filter is coded |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 print 'using', compiler | 552 print 'using', compiler |
554 if compiler == 'goma': | 553 if compiler == 'goma': |
555 assert options.goma_dir | 554 assert options.goma_dir |
556 env['CC'] = 'gcc' | 555 env['CC'] = 'gcc' |
557 env['CXX'] = 'g++' | 556 env['CXX'] = 'g++' |
558 env['PATH'] = ':'.join([options.goma_dir, env['PATH']]) | 557 env['PATH'] = ':'.join([options.goma_dir, env['PATH']]) |
559 elif compiler == 'goma-clang': | 558 elif compiler == 'goma-clang': |
560 assert options.goma_dir | 559 assert options.goma_dir |
561 env['CC'] = 'clang' | 560 env['CC'] = 'clang' |
562 env['CXX'] = 'clang++' | 561 env['CXX'] = 'clang++' |
563 clang_dir = os.path.abspath(os.path.join( | 562 clang_dir = os.path.join(options.src_dir, |
564 slave_utils.SlaveBaseDir(options.build_dir), 'build', 'src', | 563 'third_party', 'llvm-build', 'Release+Asserts', 'bin') |
565 'third_party', 'llvm-build', 'Release+Asserts', 'bin')) | |
566 env['PATH'] = ':'.join([options.goma_dir, clang_dir, env['PATH']]) | 564 env['PATH'] = ':'.join([options.goma_dir, clang_dir, env['PATH']]) |
567 else: # jsonclang | 565 else: # jsonclang |
568 env['CC'] = os.path.join(SLAVE_SCRIPTS_DIR, 'chromium', 'jsonclang') | 566 env['CC'] = os.path.join(SLAVE_SCRIPTS_DIR, 'chromium', 'jsonclang') |
569 env['CXX'] = os.path.join(SLAVE_SCRIPTS_DIR, 'chromium', 'jsonclang++') | 567 env['CXX'] = os.path.join(SLAVE_SCRIPTS_DIR, 'chromium', 'jsonclang++') |
570 command.append('-r') | 568 command.append('-r') |
571 command.append('-k') | 569 command.append('-k') |
572 # 'jsonclang' assumes the clang binary is in the path. | 570 # 'jsonclang' assumes the clang binary is in the path. |
573 clang_dir = os.path.abspath(os.path.join( | 571 clang_dir = os.path.join(options.src_dir, |
574 slave_utils.SlaveBaseDir(options.build_dir), 'build', 'src', | 572 'third_party', 'llvm-build', 'Release+Asserts', 'bin') |
575 'third_party', 'llvm-build', 'Release+Asserts', 'bin')) | |
576 if options.goma_dir: | 573 if options.goma_dir: |
577 env['PATH'] = ':'.join([options.goma_dir, clang_dir, env['PATH']]) | 574 env['PATH'] = ':'.join([options.goma_dir, clang_dir, env['PATH']]) |
578 else: | 575 else: |
579 env['PATH'] = ':'.join([clang_dir, env['PATH']]) | 576 env['PATH'] = ':'.join([clang_dir, env['PATH']]) |
580 | 577 |
581 command.append('CC.host=' + env['CC']) | 578 command.append('CC.host=' + env['CC']) |
582 command.append('CXX.host=' + env['CXX']) | 579 command.append('CXX.host=' + env['CXX']) |
583 | 580 |
584 if chromium_utils.IsMac(): | 581 if chromium_utils.IsMac(): |
585 # The default process limit on 10.6 is 266 (`sysctl kern.maxprocperuid`), | 582 # The default process limit on 10.6 is 266 (`sysctl kern.maxprocperuid`), |
586 # and about 100 processes are used by the system. The webkit bindings | 583 # and about 100 processes are used by the system. The webkit bindings |
587 # generation scripts open a preprocessor child process, so building at | 584 # generation scripts open a preprocessor child process, so building at |
588 # -j100 runs into the process limit. For now, just build with -j50. | 585 # -j100 runs into the process limit. For now, just build with -j50. |
589 goma_jobs = 50 | 586 goma_jobs = 50 |
590 if options.clobber: | 587 if options.clobber: |
591 # Disable compiles on local machine. When the goma server-side object | 588 # Disable compiles on local machine. When the goma server-side object |
592 # file cache is warm, this can speed up clobber builds by up to 30%. | 589 # file cache is warm, this can speed up clobber builds by up to 30%. |
593 env['GOMA_USE_LOCAL'] = '0' | 590 env['GOMA_USE_LOCAL'] = '0' |
594 else: | 591 else: |
595 goma_jobs = 100 | 592 goma_jobs = 100 |
596 if jobs < goma_jobs: | 593 if jobs < goma_jobs: |
597 jobs = goma_jobs | 594 jobs = goma_jobs |
598 command.append('-j%d' % jobs) | 595 command.append('-j%d' % jobs) |
599 return | 596 return |
600 | 597 |
601 if compiler == 'clang': | 598 if compiler == 'clang': |
602 clang_dir = os.path.abspath(os.path.join( | 599 clang_dir = os.path.join(options.src_dir, |
603 slave_utils.SlaveBaseDir(options.build_dir), 'build', 'src', | 600 'third_party', 'llvm-build', 'Release+Asserts', 'bin') |
604 'third_party', 'llvm-build', 'Release+Asserts', 'bin')) | |
605 env['CC'] = os.path.join(clang_dir, 'clang') | 601 env['CC'] = os.path.join(clang_dir, 'clang') |
606 env['CXX'] = os.path.join(clang_dir, 'clang++') | 602 env['CXX'] = os.path.join(clang_dir, 'clang++') |
607 command.append('CC.host=' + env['CC']) | 603 command.append('CC.host=' + env['CC']) |
608 command.append('CXX.host=' + env['CXX']) | 604 command.append('CXX.host=' + env['CXX']) |
609 command.append('-r') | 605 command.append('-r') |
610 | 606 |
611 if compiler == 'tsan_gcc': | 607 if compiler == 'tsan_gcc': |
612 # See | 608 # See |
613 # http://dev.chromium.org/developers/how-tos/using-valgrind/threadsanitizer/ gcc-tsan | 609 # http://dev.chromium.org/developers/how-tos/using-valgrind/threadsanitizer/ gcc-tsan |
614 # for build instructions. | 610 # for build instructions. |
615 tsan_base = os.path.abspath(os.path.join( | 611 tsan_base = os.path.join(options.src_dir, 'third_party', 'compiler-tsan') |
616 slave_utils.SlaveBaseDir(options.build_dir), 'build', 'src', | |
617 'third_party', 'compiler-tsan')) | |
618 | 612 |
619 tsan_gcc_bin = os.path.abspath(os.path.join( | 613 tsan_gcc_bin = os.path.abspath(os.path.join( |
620 tsan_base, 'gcc-tsan', 'scripts')) | 614 tsan_base, 'gcc-tsan', 'scripts')) |
621 gcctsan_gcc_dir = os.path.abspath(os.path.join( | 615 gcctsan_gcc_dir = os.path.abspath(os.path.join( |
622 tsan_base, 'gcc-current')) | 616 tsan_base, 'gcc-current')) |
623 | 617 |
624 if not os.path.isdir(gcctsan_gcc_dir): | 618 if not os.path.isdir(gcctsan_gcc_dir): |
625 # Extract gcc from the tarball. | 619 # Extract gcc from the tarball. |
626 extract_gcc_sh = os.path.abspath(os.path.join( | 620 extract_gcc_sh = os.path.abspath(os.path.join( |
627 tsan_base, 'extract_gcc.sh')) | 621 tsan_base, 'extract_gcc.sh')) |
628 assert(os.path.exists(extract_gcc_sh)) | 622 assert(os.path.exists(extract_gcc_sh)) |
629 chromium_utils.RunCommand([extract_gcc_sh]) | 623 chromium_utils.RunCommand([extract_gcc_sh]) |
630 assert(os.path.isdir(gcctsan_gcc_dir)) | 624 assert(os.path.isdir(gcctsan_gcc_dir)) |
631 | 625 |
632 env['CC'] = os.path.join(tsan_gcc_bin, 'gcc') | 626 env['CC'] = os.path.join(tsan_gcc_bin, 'gcc') |
633 env['CXX'] = os.path.join(tsan_gcc_bin, 'g++') | 627 env['CXX'] = os.path.join(tsan_gcc_bin, 'g++') |
634 env['LD'] = os.path.join(tsan_gcc_bin, 'ld') | 628 env['LD'] = os.path.join(tsan_gcc_bin, 'ld') |
635 # GCCTSAN_GCC_DIR and GCCTSAN_GCC_VER point to the symlinks to the current | 629 # GCCTSAN_GCC_DIR and GCCTSAN_GCC_VER point to the symlinks to the current |
636 # versions of the compiler and the instrumentation plugin created by | 630 # versions of the compiler and the instrumentation plugin created by |
637 # extract_gcc.sh | 631 # extract_gcc.sh |
638 env['GCCTSAN_GCC_DIR'] = gcctsan_gcc_dir | 632 env['GCCTSAN_GCC_DIR'] = gcctsan_gcc_dir |
639 env['GCCTSAN_GCC_VER'] = 'current' | 633 env['GCCTSAN_GCC_VER'] = 'current' |
640 env['GCCTSAN_IGNORE'] = os.path.abspath(os.path.join( | 634 env['GCCTSAN_IGNORE'] = os.path.join( |
641 slave_utils.SlaveBaseDir(options.build_dir), | 635 options.src_dir, 'tools', 'valgrind', 'tsan', 'ignores.txt') |
642 'build', 'src', 'tools', 'valgrind', 'tsan', 'ignores.txt')) | |
643 env['GCCTSAN_ARGS'] = ( | 636 env['GCCTSAN_ARGS'] = ( |
644 '-DADDRESS_SANITIZER -DWTF_USE_DYNAMIC_ANNOTATIONS=1 ' | 637 '-DADDRESS_SANITIZER -DWTF_USE_DYNAMIC_ANNOTATIONS=1 ' |
645 '-DWTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1' ) | 638 '-DWTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1' ) |
646 command.append('CC=' + env['CC']) | 639 command.append('CC=' + env['CC']) |
647 command.append('CXX=' + env['CXX']) | 640 command.append('CXX=' + env['CXX']) |
648 command.append('LD=' + env['LD']) | 641 command.append('LD=' + env['LD']) |
649 command.append('-r') | 642 command.append('-r') |
650 | 643 |
651 command.append('-j%d' % jobs) | 644 command.append('-j%d' % jobs) |
652 | 645 |
653 | 646 |
654 def main_make(options, args): | 647 def main_make(options, args): |
655 """Interprets options, clobbers object files, and calls make. | 648 """Interprets options, clobbers object files, and calls make. |
656 """ | 649 """ |
657 | 650 |
658 env = EchoDict(os.environ) | 651 env = EchoDict(os.environ) |
659 goma_ready = goma_setup(options, env) | 652 goma_ready = goma_setup(options, env) |
660 if not goma_ready: | 653 if not goma_ready: |
661 assert options.compiler not in ('goma', 'goma-clang') | 654 assert options.compiler not in ('goma', 'goma-clang') |
662 assert options.goma_dir is None | 655 assert options.goma_dir is None |
663 | 656 |
664 options.build_dir = os.path.abspath(options.build_dir) | 657 options.build_dir = os.path.abspath(options.build_dir) |
665 src_dir = os.path.join(slave_utils.SlaveBaseDir(options.build_dir), 'build', | |
666 'src') | |
667 # TODO(mmoss) Temporary hack to ignore the Windows --solution flag that is | 658 # TODO(mmoss) Temporary hack to ignore the Windows --solution flag that is |
668 # passed to all builders. This can be taken out once the master scripts are | 659 # passed to all builders. This can be taken out once the master scripts are |
669 # updated to only pass platform-appropriate --solution values. | 660 # updated to only pass platform-appropriate --solution values. |
670 if options.solution and os.path.splitext(options.solution)[1] != '.Makefile': | 661 if options.solution and os.path.splitext(options.solution)[1] != '.Makefile': |
671 options.solution = None | 662 options.solution = None |
672 | 663 |
673 command = ['make'] | 664 command = ['make'] |
674 if options.solution: | 665 if options.solution: |
675 command.extend(['-f', options.solution]) | 666 command.extend(['-f', options.solution]) |
676 working_dir = options.build_dir | 667 working_dir = options.build_dir |
677 else: | 668 else: |
678 # If no solution file (i.e. sub-project *.Makefile) is specified, try to | 669 # If no solution file (i.e. sub-project *.Makefile) is specified, try to |
679 # build from <build_dir>/Makefile, or if that doesn't exist, from | 670 # build from <build_dir>/Makefile, or if that doesn't exist, from |
680 # the top-level Makefile. | 671 # the top-level Makefile. |
681 if os.path.isfile(os.path.join(options.build_dir, 'Makefile')): | 672 if os.path.isfile(os.path.join(options.build_dir, 'Makefile')): |
682 working_dir = options.build_dir | 673 working_dir = options.build_dir |
683 else: | 674 else: |
684 working_dir = src_dir | 675 working_dir = options.src_dir |
685 | 676 |
686 # Lots of test-execution scripts hard-code 'sconsbuild' as the output | 677 # Lots of test-execution scripts hard-code 'sconsbuild' as the output |
687 # directory. Accomodate them. | 678 # directory. Accomodate them. |
688 # TODO: remove when build_dir is properly parameterized in tests. | 679 # TODO: remove when build_dir is properly parameterized in tests. |
689 sconsbuild = os.path.join(working_dir, 'sconsbuild') | 680 sconsbuild = os.path.join(working_dir, 'sconsbuild') |
690 if os.path.islink(sconsbuild): | 681 if os.path.islink(sconsbuild): |
691 if os.readlink(sconsbuild) != 'out': | 682 if os.readlink(sconsbuild) != 'out': |
692 os.remove(sconsbuild) | 683 os.remove(sconsbuild) |
693 elif os.path.exists(sconsbuild): | 684 elif os.path.exists(sconsbuild): |
694 dead = sconsbuild + '.dead' | 685 dead = sconsbuild + '.dead' |
(...skipping 11 matching lines...) Expand all Loading... | |
706 | 697 |
707 # V=1 prints the actual executed command | 698 # V=1 prints the actual executed command |
708 if options.verbose: | 699 if options.verbose: |
709 command.extend(['V=1']) | 700 command.extend(['V=1']) |
710 command.extend(options.build_args + args) | 701 command.extend(options.build_args + args) |
711 | 702 |
712 # Run the build. | 703 # Run the build. |
713 env.print_overrides() | 704 env.print_overrides() |
714 result = 0 | 705 result = 0 |
715 | 706 |
716 def clobber(target): | 707 def clobber(): |
717 build_output_dir = os.path.join(working_dir, 'out', target) | 708 print('Removing %s' % options.target_output_dir) |
718 print('Removing %s' % build_output_dir) | 709 chromium_utils.RemoveDirectory(options.target_output_dir) |
719 chromium_utils.RemoveDirectory(build_output_dir) | |
720 | 710 |
721 for target in options.target.split(','): | 711 assert ',' not in options.target, ( |
722 if options.clobber: | 712 'Used to allow multiple comma-separated targets for make. This should not be' |
723 clobber(target) | 713 ' in use any more. Asserting from orbit. It\'s the only way to be sure') |
Michael Starzinger
2012/11/14 08:57:05
Yes, we (the V8 waterfall) are using this feature
| |
724 | 714 |
725 target_command = command + ['BUILDTYPE=' + target] | 715 if options.clobber: |
726 this_result = chromium_utils.RunCommand(target_command, env=env) | 716 clobber() |
727 if this_result and not options.clobber: | 717 |
728 clobber(target) | 718 target_command = command + ['BUILDTYPE=' + options.target] |
729 # Keep the first non-zero return code as overall result. | 719 result = chromium_utils.RunCommand(target_command, env=env) |
730 if this_result and not result: | 720 if result and not options.clobber: |
731 result = this_result | 721 clobber() |
732 | 722 |
733 goma_teardown(options, env) | 723 goma_teardown(options, env) |
734 | 724 |
735 return result | 725 return result |
736 | 726 |
737 | 727 |
738 def main_ninja(options, args): | 728 def main_ninja(options, args): |
739 """Interprets options, clobbers object files, and calls ninja.""" | 729 """Interprets options, clobbers object files, and calls ninja.""" |
740 | 730 |
741 # Prepare environment. | 731 # Prepare environment. |
742 env = EchoDict(os.environ) | 732 env = EchoDict(os.environ) |
743 orig_compiler = options.compiler | 733 orig_compiler = options.compiler |
744 goma_ready = goma_setup(options, env) | 734 goma_ready = goma_setup(options, env) |
745 if not goma_ready: | 735 if not goma_ready: |
746 assert options.compiler not in ('goma', 'goma-clang') | 736 assert options.compiler not in ('goma', 'goma-clang') |
747 assert options.goma_dir is None | 737 assert options.goma_dir is None |
748 | 738 |
749 # ninja is different from all the other build systems in that it requires | 739 # ninja is different from all the other build systems in that it requires |
750 # most configuration to be done at gyp time. This is why this function does | 740 # most configuration to be done at gyp time. This is why this function does |
751 # less than the other comparable functions in this file. | 741 # less than the other comparable functions in this file. |
752 src_dir = os.path.join( | 742 print 'chdir to %s' % options.src_dir |
753 slave_utils.SlaveBaseDir(os.path.abspath(options.build_dir)), | 743 os.chdir(options.src_dir) |
754 'build', | |
755 'src') | |
756 print 'chdir to %s' % src_dir | |
757 os.chdir(src_dir) | |
758 | 744 |
759 output_dir = os.path.join('out', options.target) | 745 command = ['ninja', '-C', options.target_output_dir] |
760 command = ['ninja', '-C', output_dir] | |
761 | 746 |
762 if options.clobber: | 747 if options.clobber: |
763 print('Removing %s' % output_dir) | 748 print('Removing %s' % options.target_output_dir) |
764 # Deleting output_dir would also delete all the .ninja files necessary to | 749 # Deleting output_dir would also delete all the .ninja files necessary to |
765 # build. Clobbering should run before runhooks (which creates .ninja files). | 750 # build. Clobbering should run before runhooks (which creates .ninja files). |
766 # For now, only delete all non-.ninja files. TODO(thakis): Make "clobber" a | 751 # For now, only delete all non-.ninja files. TODO(thakis): Make "clobber" a |
767 # step that runs before "runhooks". Once the master has been restarted, | 752 # step that runs before "runhooks". Once the master has been restarted, |
768 # remove all clobber handling from compile.py. | 753 # remove all clobber handling from compile.py. |
769 ninja_clobber(output_dir) | 754 ninja_clobber(options.target_output_dir) |
770 | 755 |
771 if options.verbose: | 756 if options.verbose: |
772 command.append('-v') | 757 command.append('-v') |
773 command.extend(options.build_args) | 758 command.extend(options.build_args) |
774 command.extend(args) | 759 command.extend(args) |
775 | 760 |
776 if chromium_utils.IsMac() and options.disable_aslr: | 761 if chromium_utils.IsMac() and options.disable_aslr: |
777 # Disallow dyld to randomize the load addresses of executables. | 762 # Disallow dyld to randomize the load addresses of executables. |
778 # If any of them is compiled with ASan it will hang otherwise. | 763 # If any of them is compiled with ASan it will hang otherwise. |
779 env['DYLD_NO_PIE'] = '1' | 764 env['DYLD_NO_PIE'] = '1' |
(...skipping 12 matching lines...) Expand all Loading... | |
792 # under ninja -t msvc. (PATH is just ignored. Note PATH set/used | 777 # under ninja -t msvc. (PATH is just ignored. Note PATH set/used |
793 # in compile.py doesn't include MSVC's path). | 778 # in compile.py doesn't include MSVC's path). |
794 # Hence, we'll got | 779 # Hence, we'll got |
795 # "CreateProcess failed: The system cannot find the file specified." | 780 # "CreateProcess failed: The system cannot find the file specified." |
796 # | 781 # |
797 # So, rewrite cc, cxx line to "$goma_dir/gomacc cl". | 782 # So, rewrite cc, cxx line to "$goma_dir/gomacc cl". |
798 # | 783 # |
799 # Note that, on other platform, ninja doesn't use ninja -t msvc | 784 # Note that, on other platform, ninja doesn't use ninja -t msvc |
800 # (it just simply run $cc/$cxx), so modifying PATH can work to run | 785 # (it just simply run $cc/$cxx), so modifying PATH can work to run |
801 # gomacc without this hack. | 786 # gomacc without this hack. |
802 if os.path.exists(os.path.join(output_dir, 'build.ninja.orig')): | 787 manifest = os.path.join(options.target_output_dir, 'build.ninja') |
803 os.remove(os.path.join(output_dir, 'build.ninja.orig')) | 788 orig_manifest = manifest + '.orig' |
804 os.rename(os.path.join(output_dir, 'build.ninja'), | 789 if os.path.exists(orig_manifest): |
805 os.path.join(output_dir, 'build.ninja.orig')) | 790 os.remove(orig_manifest) |
791 os.rename(manifest, orig_manifest) | |
806 cc_line_pattern = re.compile(r'(cc|cxx|cc_host|cxx_host) = (.*)') | 792 cc_line_pattern = re.compile(r'(cc|cxx|cc_host|cxx_host) = (.*)') |
807 goma_repl = '\\1 = %s \\2' % ( | 793 goma_repl = '\\1 = %s \\2' % ( |
808 os.path.join(options.goma_dir, 'gomacc.exe').replace('\\', '\\\\')) | 794 os.path.join(options.goma_dir, 'gomacc.exe').replace('\\', '\\\\')) |
809 with open(os.path.join(output_dir, 'build.ninja.orig')) as orig_build: | 795 with open(orig_manifest) as orig_build: |
810 with open(os.path.join(output_dir, 'build.ninja'), 'w') as new_build: | 796 with open(manifest, 'w') as new_build: |
811 for line in orig_build: | 797 for line in orig_build: |
812 new_build.write(cc_line_pattern.sub(goma_repl, line)) | 798 new_build.write(cc_line_pattern.sub(goma_repl, line)) |
813 | 799 |
814 # CC and CXX are set at gyp time for ninja. PATH still needs to be adjusted. | 800 # CC and CXX are set at gyp time for ninja. PATH still needs to be adjusted. |
815 print 'using', options.compiler | 801 print 'using', options.compiler |
816 if options.compiler == 'goma': | 802 if options.compiler == 'goma': |
817 env['PATH'] = os.pathsep.join([options.goma_dir, env['PATH']]) | 803 env['PATH'] = os.pathsep.join([options.goma_dir, env['PATH']]) |
818 elif options.compiler == 'goma-clang': | 804 elif options.compiler == 'goma-clang': |
819 clang_dir = os.path.abspath(os.path.join( | 805 clang_dir = os.path.abspath(os.path.join( |
820 'third_party', 'llvm-build', 'Release+Asserts', 'bin')) | 806 'third_party', 'llvm-build', 'Release+Asserts', 'bin')) |
(...skipping 28 matching lines...) Expand all Loading... | |
849 | 835 |
850 goma_teardown(options, env) | 836 goma_teardown(options, env) |
851 return result | 837 return result |
852 | 838 |
853 | 839 |
854 def main_scons(options, args): | 840 def main_scons(options, args): |
855 """Interprets options, clobbers object files, and calls scons. | 841 """Interprets options, clobbers object files, and calls scons. |
856 """ | 842 """ |
857 options.build_dir = os.path.abspath(options.build_dir) | 843 options.build_dir = os.path.abspath(options.build_dir) |
858 if options.clobber: | 844 if options.clobber: |
859 build_output_dir = os.path.join(os.path.dirname(options.build_dir), | 845 print('Removing %s' % options.target_output_dir) |
860 'sconsbuild', options.target) | 846 chromium_utils.RemoveDirectory(options.target_output_dir) |
861 print('Removing %s' % build_output_dir) | |
862 chromium_utils.RemoveDirectory(build_output_dir) | |
863 | 847 |
864 os.chdir(options.build_dir) | 848 os.chdir(options.build_dir) |
865 | 849 |
866 if sys.platform == 'win32': | 850 if sys.platform == 'win32': |
867 command = ['hammer.bat'] | 851 command = ['hammer.bat'] |
868 else: | 852 else: |
869 command = ['hammer'] | 853 command = ['hammer'] |
870 | 854 |
871 env = EchoDict(os.environ) | 855 env = EchoDict(os.environ) |
872 if sys.platform == 'linux2': | 856 if sys.platform == 'linux2': |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 else: | 925 else: |
942 tool = devenv | 926 tool = devenv |
943 if options.arch == 'x64': | 927 if options.arch == 'x64': |
944 tool_options = ['/Build', '%s|x64' % options.target] | 928 tool_options = ['/Build', '%s|x64' % options.target] |
945 else: | 929 else: |
946 tool_options = ['/Build', options.target] | 930 tool_options = ['/Build', options.target] |
947 if options.project: | 931 if options.project: |
948 tool_options.extend(['/Project', options.project]) | 932 tool_options.extend(['/Project', options.project]) |
949 | 933 |
950 options.build_dir = os.path.abspath(options.build_dir) | 934 options.build_dir = os.path.abspath(options.build_dir) |
951 build_output_dir = os.path.join(options.build_dir, options.target) | |
952 | 935 |
953 def clobber(): | 936 def clobber(): |
954 print('Removing %s' % build_output_dir) | 937 print('Removing %s' % options.target_output_dir) |
955 chromium_utils.RemoveDirectory(build_output_dir) | 938 chromium_utils.RemoveDirectory(options.target_output_dir) |
956 | 939 |
957 if options.clobber: | 940 if options.clobber: |
958 clobber() | 941 clobber() |
959 else: | 942 else: |
960 # Remove the log file so it doesn't grow without limit, | 943 # Remove the log file so it doesn't grow without limit, |
961 chromium_utils.RemoveFile(build_output_dir, 'debug.log') | 944 chromium_utils.RemoveFile(options.target_output_dir, 'debug.log') |
962 # Remove the chrome.dll version resource so it picks up the new svn | 945 # Remove the chrome.dll version resource so it picks up the new svn |
963 # revision, unless user explicitly asked not to remove it. See | 946 # revision, unless user explicitly asked not to remove it. See |
964 # Bug 1064677 for more details. | 947 # Bug 1064677 for more details. |
965 if not options.keep_version_file: | 948 if not options.keep_version_file: |
966 chromium_utils.RemoveFile(build_output_dir, 'obj', 'chrome_dll', | 949 chromium_utils.RemoveFile(options.target_output_dir, 'obj', 'chrome_dll', |
967 'chrome_dll_version.rc') | 950 'chrome_dll_version.rc') |
968 | 951 |
969 env = EchoDict(os.environ) | 952 env = EchoDict(os.environ) |
970 | 953 |
971 # no goma support yet for this build tool. | 954 # no goma support yet for this build tool. |
972 assert options.compiler != 'goma' | 955 assert options.compiler != 'goma' |
973 | 956 |
974 if options.mode == 'google_chrome' or options.mode == 'official': | 957 if options.mode == 'google_chrome' or options.mode == 'official': |
975 env['CHROMIUM_BUILD'] = '_google_chrome' | 958 env['CHROMIUM_BUILD'] = '_google_chrome' |
976 | 959 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 if known_line in line: | 1040 if known_line in line: |
1058 errors.append(line) | 1041 errors.append(line) |
1059 break | 1042 break |
1060 | 1043 |
1061 env.print_overrides() | 1044 env.print_overrides() |
1062 result = chromium_utils.RunCommand( | 1045 result = chromium_utils.RunCommand( |
1063 command, parser_func=scan, env=env, universal_newlines=True) | 1046 command, parser_func=scan, env=env, universal_newlines=True) |
1064 if errors: | 1047 if errors: |
1065 print('\n\nRetrying a clobber build because of:') | 1048 print('\n\nRetrying a clobber build because of:') |
1066 print('\n'.join((' ' + l for l in errors))) | 1049 print('\n'.join((' ' + l for l in errors))) |
1067 print('Removing %s' % build_output_dir) | 1050 print('Removing %s' % options.target_output_dir) |
1068 for _ in range(3): | 1051 for _ in range(3): |
1069 try: | 1052 try: |
1070 chromium_utils.RemoveDirectory(build_output_dir) | 1053 chromium_utils.RemoveDirectory(options.target_output_dir) |
1071 break | 1054 break |
1072 except OSError, e: | 1055 except OSError, e: |
1073 print(e) | 1056 print(e) |
1074 print('\nSleeping 15 seconds. Lovely windows file locks.') | 1057 print('\nSleeping 15 seconds. Lovely windows file locks.') |
1075 time.sleep(15) | 1058 time.sleep(15) |
1076 else: | 1059 else: |
1077 print('Failed to delete a file 3 times in a row, aborting.') | 1060 print('Failed to delete a file 3 times in a row, aborting.') |
1078 return 1 | 1061 return 1 |
1079 result = chromium_utils.RunCommand(command, env=env) | 1062 result = chromium_utils.RunCommand(command, env=env) |
1080 | 1063 |
1081 # TODO(maruel): As soon as the try server is restarted, replace with: | 1064 # TODO(maruel): As soon as the try server is restarted, replace with: |
1082 # if result and not options.clobber and options.clobber_post_fail: | 1065 # if result and not options.clobber and options.clobber_post_fail: |
1083 if result and not options.clobber: | 1066 if result and not options.clobber: |
1084 clobber() | 1067 clobber() |
1085 | 1068 |
1086 return result | 1069 return result |
1087 | 1070 |
1088 | 1071 |
1072 def landmines_triggered(build_dir): | |
1073 trigger_file = os.path.join(build_dir, '.landmines_triggered') | |
1074 if os.path.exists(trigger_file): | |
1075 print 'Setting clobber due to triggered landmines:' | |
1076 with open(trigger_file) as f: | |
1077 print f.read() | |
1078 return True | |
1079 return False | |
1080 | |
1081 | |
1082 def get_target_build_dir(build_tool, src_dir, target, is_iphone=False): | |
1083 """Keep this function in sync with src/build/landmines.py""" | |
1084 ret = None | |
1085 if build_tool == 'xcode': | |
1086 ret = os.path.join(src_dir, 'xcodebuild', | |
1087 target + ('-iphoneos' if is_iphone else '')) | |
1088 elif build_tool == 'make': | |
1089 ret = os.path.join(src_dir, 'out', target) | |
1090 elif build_tool == 'ninja': | |
1091 ret = os.path.join(src_dir, 'out', target) | |
1092 elif build_tool == 'msvs': | |
1093 ret = os.path.join(src_dir, 'build', target) | |
1094 elif build_tool == 'scons': | |
1095 ret = os.path.join(src_dir, 'sconsbuild', target) | |
1096 else: | |
1097 raise NotImplementedError() | |
Jakob Kummerow
2012/11/14 09:12:05
This gets hit by V8 Win builders: http://build.chr
| |
1098 return os.path.abspath(ret) | |
1099 | |
1100 | |
1089 def real_main(): | 1101 def real_main(): |
1090 option_parser = optparse.OptionParser() | 1102 option_parser = optparse.OptionParser() |
1091 option_parser.add_option('', '--clobber', action='store_true', default=False, | 1103 option_parser.add_option('', '--clobber', action='store_true', default=False, |
1092 help='delete the output directory before compiling') | 1104 help='delete the output directory before compiling') |
1093 option_parser.add_option('', '--clobber-post-fail', action='store_true', | 1105 option_parser.add_option('', '--clobber-post-fail', action='store_true', |
1094 default=False, | 1106 default=False, |
1095 help='delete the output directory after compiling ' | 1107 help='delete the output directory after compiling ' |
1096 'only if it failed. Do not affect ninja.') | 1108 'only if it failed. Do not affect ninja.') |
1097 option_parser.add_option('', '--keep-version-file', action='store_true', | 1109 option_parser.add_option('', '--keep-version-file', action='store_true', |
1098 default=False, | 1110 default=False, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1137 option_parser.add_option('', '--goma-dir', | 1149 option_parser.add_option('', '--goma-dir', |
1138 default=os.path.join(BUILD_DIR, 'goma'), | 1150 default=os.path.join(BUILD_DIR, 'goma'), |
1139 help='specify goma directory') | 1151 help='specify goma directory') |
1140 option_parser.add_option('--verbose', action='store_true') | 1152 option_parser.add_option('--verbose', action='store_true') |
1141 | 1153 |
1142 options, args = option_parser.parse_args() | 1154 options, args = option_parser.parse_args() |
1143 | 1155 |
1144 if options.build_tool is None: | 1156 if options.build_tool is None: |
1145 if chromium_utils.IsWindows(): | 1157 if chromium_utils.IsWindows(): |
1146 main = main_win | 1158 main = main_win |
1159 options.build_tool = 'msvs' | |
1147 elif chromium_utils.IsMac(): | 1160 elif chromium_utils.IsMac(): |
1148 main = main_xcode | 1161 main = main_xcode |
1162 options.build_tool = 'xcode' | |
1149 elif chromium_utils.IsLinux(): | 1163 elif chromium_utils.IsLinux(): |
1150 main = main_make | 1164 main = main_make |
1165 options.build_tool = 'make' | |
1151 else: | 1166 else: |
1152 print('Please specify --build-tool.') | 1167 print('Please specify --build-tool.') |
1153 return 1 | 1168 return 1 |
1154 else: | 1169 else: |
1155 build_tool_map = { | 1170 build_tool_map = { |
1156 'ib' : main_win, | 1171 'ib' : main_win, |
1157 'vs' : main_win, | 1172 'vs' : main_win, |
1158 'make' : main_make, | 1173 'make' : main_make, |
1159 'ninja' : main_ninja, | 1174 'ninja' : main_ninja, |
1160 'scons' : main_scons, | 1175 'scons' : main_scons, |
1161 'xcode' : main_xcode, | 1176 'xcode' : main_xcode, |
1162 } | 1177 } |
1163 main = build_tool_map.get(options.build_tool) | 1178 main = build_tool_map.get(options.build_tool) |
1164 if not main: | 1179 if not main: |
1165 sys.stderr.write('Unknown build tool %s.\n' % repr(options.build_tool)) | 1180 sys.stderr.write('Unknown build tool %s.\n' % repr(options.build_tool)) |
1166 return 2 | 1181 return 2 |
1167 | 1182 |
1183 options.build_dir = os.path.abspath(options.build_dir) | |
1184 options.src_dir = os.path.join(slave_utils.SlaveBaseDir( | |
1185 os.path.abspath(options.build_dir)), 'build', 'src') | |
1186 options.target_output_dir = get_target_build_dir(options.build_tool, | |
1187 options.src_dir, options.target, 'iphoneos' in args) | |
1188 options.clobber = (options.clobber or | |
1189 landmines_triggered(options.target_output_dir)) | |
1190 | |
1168 return main(options, args) | 1191 return main(options, args) |
1169 | 1192 |
1170 | 1193 |
1171 if '__main__' == __name__: | 1194 if '__main__' == __name__: |
1172 sys.exit(real_main()) | 1195 sys.exit(real_main()) |
OLD | NEW |