Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: tools/mb/mb.py

Issue 1440173002: Update MB for the new way to run 'analyze'. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: original patch for review Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 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 """MB - the Meta-Build wrapper around GYP and GN 6 """MB - the Meta-Build wrapper around GYP and GN
7 7
8 MB is a wrapper script for GYP and GN that can be used to generate build files 8 MB is a wrapper script for GYP and GN that can be used to generate build files
9 for sets of canned configurations and analyze them. 9 for sets of canned configurations and analyze them.
10 """ 10 """
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 env['GYP_CROSSCOMPILE'] = '1' 766 env['GYP_CROSSCOMPILE'] = '1'
767 return cmd, env 767 return cmd, env
768 768
769 def RunGNAnalyze(self, vals): 769 def RunGNAnalyze(self, vals):
770 # analyze runs before 'gn gen' now, so we need to run gn gen 770 # analyze runs before 'gn gen' now, so we need to run gn gen
771 # in order to ensure that we have a build directory. 771 # in order to ensure that we have a build directory.
772 ret = self.RunGNGen(vals) 772 ret = self.RunGNGen(vals)
773 if ret: 773 if ret:
774 return ret 774 return ret
775 775
776 inp = self.ReadInputJSON(['files', 'targets']) 776 # TODO(dpranke): add 'test_targets' and 'additional_compile_targets'
777 # as required keys once the recipe has been converted over.
778 # See crbug.com/552146.
779 inp = self.ReadInputJSON(['files'])
777 if self.args.verbose: 780 if self.args.verbose:
778 self.Print() 781 self.Print()
779 self.Print('analyze input:') 782 self.Print('analyze input:')
780 self.PrintJSON(inp) 783 self.PrintJSON(inp)
781 self.Print() 784 self.Print()
782 785
786 use_new_logic = ('test_targets' in inp and
787 'additional_compile_targets' in inp)
788 if use_new_logic:
789 # TODO(crbug.com/555273) - currently GN treats targets and
790 # additional_compile_targets identically since we can't tell the
791 # difference between a target that is a group in GN and one that isn't.
792 # We should eventually fix this and treat the two types differently.
793 targets = (set(inp['test_targets']) |
794 set(inp['additional_compile_targets']))
795 else:
796 targets = set(inp['targets'])
797
783 output_path = self.args.output_path[0] 798 output_path = self.args.output_path[0]
784 799
785 # Bail out early if a GN file was modified, since 'gn refs' won't know 800 # Bail out early if a GN file was modified, since 'gn refs' won't know
786 # what to do about it. 801 # what to do about it. Also, bail out early if 'all' was asked for,
787 if any(f.endswith('.gn') or f.endswith('.gni') for f in inp['files']): 802 # since we can't deal with it yet.
788 self.WriteJSON({'status': 'Found dependency (all)'}, output_path) 803 if (any(f.endswith('.gn') or f.endswith('.gni') for f in inp['files']) or
789 return 0 804 'all' in targets):
790 805 if use_new_logic:
791 # Bail out early if 'all' was asked for, since 'gn refs' won't recognize it. 806 self.WriteJSON({
792 if 'all' in inp['targets']: 807 'status': 'Found dependency (all)',
793 self.WriteJSON({'status': 'Found dependency (all)'}, output_path) 808 'compile_targets': sorted(targets),
809 'test_targets': sorted(targets & set(inp['test_targets'])),
810 }, output_path)
811 else:
812 self.WriteJSON({'status': 'Found dependency (all)'}, output_path)
794 return 0 813 return 0
795 814
796 # This shouldn't normally happen, but could due to unusual race conditions, 815 # This shouldn't normally happen, but could due to unusual race conditions,
797 # like a try job that gets scheduled before a patch lands but runs after 816 # like a try job that gets scheduled before a patch lands but runs after
798 # the patch has landed. 817 # the patch has landed.
799 if not inp['files']: 818 if not inp['files']:
800 self.Print('Warning: No files modified in patch, bailing out early.') 819 self.Print('Warning: No files modified in patch, bailing out early.')
801 self.WriteJSON({'targets': [], 820 if use_new_logic:
802 'build_targets': [], 821 self.WriteJSON({
803 'status': 'No dependency'}, output_path) 822 'status': 'No dependency',
823 'compile_targets': [],
824 'test_targets': [],
825 }, output_path)
826 else:
827 self.WriteJSON({
828 'status': 'No dependency',
829 'targets': [],
830 'build_targets': [],
831 }, output_path)
804 return 0 832 return 0
805 833
806 ret = 0 834 ret = 0
807 response_file = self.TempFile() 835 response_file = self.TempFile()
808 response_file.write('\n'.join(inp['files']) + '\n') 836 response_file.write('\n'.join(inp['files']) + '\n')
809 response_file.close() 837 response_file.close()
810 838
811 matching_targets = [] 839 matching_targets = set()
812 try: 840 try:
813 cmd = self.GNCmd('refs', self.args.path[0]) + [ 841 cmd = self.GNCmd('refs', self.args.path[0]) + [
814 '@%s' % response_file.name, '--all', '--as=output'] 842 '@%s' % response_file.name, '--all', '--as=output']
815 ret, out, _ = self.Run(cmd, force_verbose=False) 843 ret, out, _ = self.Run(cmd, force_verbose=False)
816 if ret and not 'The input matches no targets' in out: 844 if ret and not 'The input matches no targets' in out:
817 self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out), 845 self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out),
818 output_path) 846 output_path)
819 build_dir = self.ToSrcRelPath(self.args.path[0]) + self.sep 847 build_dir = self.ToSrcRelPath(self.args.path[0]) + self.sep
820 for output in out.splitlines(): 848 for output in out.splitlines():
821 build_output = output.replace(build_dir, '') 849 build_output = output.replace(build_dir, '')
822 if build_output in inp['targets']: 850 if build_output in targets:
823 matching_targets.append(build_output) 851 matching_targets.add(build_output)
824 852
825 cmd = self.GNCmd('refs', self.args.path[0]) + [ 853 cmd = self.GNCmd('refs', self.args.path[0]) + [
826 '@%s' % response_file.name, '--all'] 854 '@%s' % response_file.name, '--all']
827 ret, out, _ = self.Run(cmd, force_verbose=False) 855 ret, out, _ = self.Run(cmd, force_verbose=False)
828 if ret and not 'The input matches no targets' in out: 856 if ret and not 'The input matches no targets' in out:
829 self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out), 857 self.WriteFailureAndRaise('gn refs returned %d: %s' % (ret, out),
830 output_path) 858 output_path)
831 for label in out.splitlines(): 859 for label in out.splitlines():
832 build_target = label[2:] 860 build_target = label[2:]
833 # We want to accept 'chrome/android:chrome_public_apk' and 861 # We want to accept 'chrome/android:chrome_public_apk' and
834 # just 'chrome_public_apk'. This may result in too many targets 862 # just 'chrome_public_apk'. This may result in too many targets
835 # getting built, but we can adjust that later if need be. 863 # getting built, but we can adjust that later if need be.
836 for input_target in inp['targets']: 864 for input_target in targets:
837 if (input_target == build_target or 865 if (input_target == build_target or
838 build_target.endswith(':' + input_target)): 866 build_target.endswith(':' + input_target)):
839 matching_targets.append(input_target) 867 matching_targets.add(input_target)
840 finally: 868 finally:
841 self.RemoveFile(response_file.name) 869 self.RemoveFile(response_file.name)
842 870
843 if matching_targets: 871 if matching_targets:
844 # TODO: it could be that a target X might depend on a target Y 872 if use_new_logic:
845 # and both would be listed in the input, but we would only need 873 self.WriteJSON({
846 # to specify target X as a build_target (whereas both X and Y are 874 'status': 'Found dependency',
847 # targets). I'm not sure if that optimization is generally worth it. 875 'compile_targets': sorted(matching_targets),
848 self.WriteJSON({'targets': sorted(set(matching_targets)), 876 'test_targets': sorted(matching_targets &
849 'build_targets': sorted(set(matching_targets)), 877 set(inp['test_targets'])),
850 'status': 'Found dependency'}, output_path) 878 }, output_path)
879 else:
880 self.WriteJSON({
881 'status': 'Found dependency',
882 'targets': sorted(matching_targets),
883 'build_targets': sorted(matching_targets),
884 }, output_path)
851 else: 885 else:
852 self.WriteJSON({'targets': [], 886 if use_new_logic:
853 'build_targets': [], 887 self.WriteJSON({
854 'status': 'No dependency'}, output_path) 888 'status': 'No dependency',
889 'compile_targets': [],
890 'test_targets': [],
891 }, output_path)
892 else:
893 self.WriteJSON({
894 'status': 'No dependency',
895 'targets': [],
896 'build_targets': [],
897 }, output_path)
855 898
856 if self.args.verbose: 899 if self.args.verbose:
857 outp = json.loads(self.ReadFile(output_path)) 900 outp = json.loads(self.ReadFile(output_path))
858 self.Print() 901 self.Print()
859 self.Print('analyze output:') 902 self.Print('analyze output:')
860 self.PrintJSON(outp) 903 self.PrintJSON(outp)
861 self.Print() 904 self.Print()
862 905
863 return 0 906 return 0
864 907
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 1090
1048 if __name__ == '__main__': 1091 if __name__ == '__main__':
1049 try: 1092 try:
1050 sys.exit(main(sys.argv[1:])) 1093 sys.exit(main(sys.argv[1:]))
1051 except MBErr as e: 1094 except MBErr as e:
1052 print(e) 1095 print(e)
1053 sys.exit(1) 1096 sys.exit(1)
1054 except KeyboardInterrupt: 1097 except KeyboardInterrupt:
1055 print("interrupted, exiting", stream=sys.stderr) 1098 print("interrupted, exiting", stream=sys.stderr)
1056 sys.exit(130) 1099 sys.exit(130)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698