OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2013 The Chromium Authors. All rights reserved. | 3 # Copyright 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 import fnmatch | 7 import fnmatch |
8 import optparse | 8 import optparse |
9 import os | 9 import os |
| 10 import shutil |
10 import re | 11 import re |
11 import sys | 12 import sys |
12 | 13 |
13 from util import build_utils | 14 from util import build_utils |
14 from util import md5_check | 15 from util import md5_check |
15 | 16 |
| 17 import jar |
| 18 |
16 sys.path.append(build_utils.COLORAMA_ROOT) | 19 sys.path.append(build_utils.COLORAMA_ROOT) |
17 import colorama | 20 import colorama |
18 | 21 |
19 | 22 |
20 def ColorJavacOutput(output): | 23 def ColorJavacOutput(output): |
21 fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)' | 24 fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)' |
22 warning_re = re.compile( | 25 warning_re = re.compile( |
23 fileline_prefix + r'(?P<full_message> warning: (?P<message>.*))$') | 26 fileline_prefix + r'(?P<full_message> warning: (?P<message>.*))$') |
24 error_re = re.compile( | 27 error_re = re.compile( |
25 fileline_prefix + r'(?P<full_message> (?P<message>.*))$') | 28 fileline_prefix + r'(?P<full_message> (?P<message>.*))$') |
(...skipping 16 matching lines...) Expand all Loading... |
42 if warning_re.match(line): | 45 if warning_re.match(line): |
43 line = Colorize(line, warning_re, warning_color) | 46 line = Colorize(line, warning_re, warning_color) |
44 elif error_re.match(line): | 47 elif error_re.match(line): |
45 line = Colorize(line, error_re, error_color) | 48 line = Colorize(line, error_re, error_color) |
46 elif marker_re.match(line): | 49 elif marker_re.match(line): |
47 line = Colorize(line, marker_re, marker_color) | 50 line = Colorize(line, marker_re, marker_color) |
48 return line | 51 return line |
49 | 52 |
50 return '\n'.join(map(ApplyColor, output.split('\n'))) | 53 return '\n'.join(map(ApplyColor, output.split('\n'))) |
51 | 54 |
52 | 55 def DoJavac( |
53 def DoJavac(options, args): | 56 classpath, javac_includes, classes_dir, chromium_code, java_files): |
54 output_dir = options.output_dir | 57 if javac_includes: |
55 | 58 javac_includes = build_utils.ParseGypList(javac_includes) |
56 src_gendirs = build_utils.ParseGypList(options.src_gendirs) | |
57 java_files = args + build_utils.FindInDirectories(src_gendirs, '*.java') | |
58 if options.javac_includes: | |
59 javac_includes = build_utils.ParseGypList(options.javac_includes) | |
60 filtered_java_files = [] | 59 filtered_java_files = [] |
61 for f in java_files: | 60 for f in java_files: |
62 for include in javac_includes: | 61 for include in javac_includes: |
63 if fnmatch.fnmatch(f, include): | 62 if fnmatch.fnmatch(f, include): |
64 filtered_java_files.append(f) | 63 filtered_java_files.append(f) |
65 break | 64 break |
66 java_files = filtered_java_files | 65 java_files = filtered_java_files |
67 | 66 |
68 # Compiling guava with certain orderings of input files causes a compiler | 67 # Compiling guava with certain orderings of input files causes a compiler |
69 # crash... Sorted order works, so use that. | 68 # crash... Sorted order works, so use that. |
70 # See https://code.google.com/p/guava-libraries/issues/detail?id=950 | 69 # See https://code.google.com/p/guava-libraries/issues/detail?id=950 |
71 java_files.sort() | 70 java_files.sort() |
72 classpath = build_utils.ParseGypList(options.classpath) | 71 classpath = build_utils.ParseGypList(classpath) |
73 | 72 |
74 jar_inputs = [] | 73 jar_inputs = [] |
75 for path in classpath: | 74 for path in classpath: |
76 if os.path.exists(path + '.TOC'): | 75 if os.path.exists(path + '.TOC'): |
77 jar_inputs.append(path + '.TOC') | 76 jar_inputs.append(path + '.TOC') |
78 else: | 77 else: |
79 jar_inputs.append(path) | 78 jar_inputs.append(path) |
80 | 79 |
81 javac_args = [ | 80 javac_args = [ |
82 '-g', | 81 '-g', |
83 '-source', '1.5', | 82 '-source', '1.5', |
84 '-target', '1.5', | 83 '-target', '1.5', |
85 '-classpath', ':'.join(classpath), | 84 '-classpath', ':'.join(classpath), |
86 '-d', output_dir] | 85 '-d', classes_dir] |
87 if options.chromium_code: | 86 if chromium_code: |
88 javac_args.extend(['-Xlint:unchecked', '-Xlint:deprecation']) | 87 javac_args.extend(['-Xlint:unchecked', '-Xlint:deprecation']) |
89 else: | 88 else: |
90 # XDignore.symbol.file makes javac compile against rt.jar instead of | 89 # XDignore.symbol.file makes javac compile against rt.jar instead of |
91 # ct.sym. This means that using a java internal package/class will not | 90 # ct.sym. This means that using a java internal package/class will not |
92 # trigger a compile warning or error. | 91 # trigger a compile warning or error. |
93 javac_args.extend(['-XDignore.symbol.file']) | 92 javac_args.extend(['-XDignore.symbol.file']) |
94 | 93 |
95 javac_cmd = ['javac'] + javac_args + java_files | 94 javac_cmd = ['javac'] + javac_args + java_files |
96 | 95 |
97 def Compile(): | 96 def Compile(): |
98 # Delete the classes directory. This ensures that all .class files in the | |
99 # output are actually from the input .java files. For example, if a .java | |
100 # file is deleted or an inner class is removed, the classes directory should | |
101 # not contain the corresponding old .class file after running this action. | |
102 build_utils.DeleteDirectory(output_dir) | |
103 build_utils.MakeDirectory(output_dir) | |
104 build_utils.CheckOutput( | 97 build_utils.CheckOutput( |
105 javac_cmd, | 98 javac_cmd, |
106 print_stdout=options.chromium_code, | 99 print_stdout=chromium_code, |
107 stderr_filter=ColorJavacOutput) | 100 stderr_filter=ColorJavacOutput) |
108 | 101 |
109 | 102 record_path = os.path.join(classes_dir, 'javac.md5.stamp') |
110 record_path = '%s/javac.md5.stamp' % options.output_dir | |
111 md5_check.CallAndRecordIfStale( | 103 md5_check.CallAndRecordIfStale( |
112 Compile, | 104 Compile, |
113 record_path=record_path, | 105 record_path=record_path, |
114 input_paths=java_files + jar_inputs, | 106 input_paths=java_files + jar_inputs, |
115 input_strings=javac_cmd) | 107 input_strings=javac_cmd) |
116 | 108 |
117 | 109 |
118 def main(): | 110 def main(): |
119 colorama.init() | 111 colorama.init() |
120 | 112 |
121 parser = optparse.OptionParser() | 113 parser = optparse.OptionParser() |
122 parser.add_option('--src-gendirs', | 114 parser.add_option( |
| 115 '--src-gendirs', |
123 help='Directories containing generated java files.') | 116 help='Directories containing generated java files.') |
124 parser.add_option('--javac-includes', | 117 parser.add_option('--classpath', help='Classpath for javac.') |
| 118 parser.add_option( |
| 119 '--javac-includes', |
125 help='A list of file patterns. If provided, only java files that match' + | 120 help='A list of file patterns. If provided, only java files that match' + |
126 'one of the patterns will be compiled.') | 121 'one of the patterns will be compiled.') |
127 parser.add_option('--classpath', help='Classpath for javac.') | 122 parser.add_option( |
128 parser.add_option('--output-dir', help='Directory for javac output.') | 123 '--jar-excluded-classes', |
| 124 help='List of .class file patterns to exclude from the jar.') |
| 125 |
| 126 parser.add_option( |
| 127 '--chromium-code', |
| 128 type='int', |
| 129 help='Whether code being compiled should be built with stricter ' |
| 130 'warnings for chromium code.') |
| 131 |
| 132 parser.add_option( |
| 133 '--classes-dir', |
| 134 help='Directory for compiled .class files.') |
| 135 parser.add_option('--jar-path', help='Jar output path.') |
| 136 |
129 parser.add_option('--stamp', help='Path to touch on success.') | 137 parser.add_option('--stamp', help='Path to touch on success.') |
130 parser.add_option('--chromium-code', type='int', help='Whether code being ' | |
131 'compiled should be built with stricter warnings for ' | |
132 'chromium code.') | |
133 | 138 |
134 options, args = parser.parse_args() | 139 options, args = parser.parse_args() |
135 | 140 |
136 DoJavac(options, args) | 141 java_files = args |
| 142 if options.src_gendirs: |
| 143 src_gendirs = build_utils.ParseGypList(options.src_gendirs) |
| 144 java_files += build_utils.FindInDirectories(src_gendirs, '*.java') |
| 145 |
| 146 with build_utils.TempDir() as classes_dir: |
| 147 DoJavac( |
| 148 options.classpath, |
| 149 options.javac_includes, |
| 150 classes_dir, |
| 151 options.chromium_code, |
| 152 java_files) |
| 153 |
| 154 if options.jar_path: |
| 155 jar.JarDirectory(classes_dir, |
| 156 build_utils.ParseGypList(options.jar_excluded_classes), |
| 157 options.jar_path) |
| 158 |
| 159 if options.classes_dir: |
| 160 # Delete the old classes directory. This ensures that all .class files in |
| 161 # the output are actually from the input .java files. For example, if a |
| 162 # .java file is deleted or an inner class is removed, the classes |
| 163 # directory should not contain the corresponding old .class file after |
| 164 # running this action. |
| 165 build_utils.DeleteDirectory(options.classes_dir) |
| 166 shutil.copytree(classes_dir, options.classes_dir) |
137 | 167 |
138 if options.stamp: | 168 if options.stamp: |
139 build_utils.Touch(options.stamp) | 169 build_utils.Touch(options.stamp) |
140 | 170 |
141 | 171 |
142 if __name__ == '__main__': | 172 if __name__ == '__main__': |
143 sys.exit(main()) | 173 sys.exit(main()) |
144 | 174 |
145 | 175 |
OLD | NEW |