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

Side by Side Diff: build/android/gyp/javac.py

Issue 1324203002: Reland of Fix javac command never caching input .md5s (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@md5-extra
Patch Set: fixed empty jars Created 5 years, 3 months 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
« no previous file with comments | « build/android/gyp/jar.py ('k') | build/android/gyp/util/build_utils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
8 import optparse 7 import optparse
9 import os 8 import os
10 import shutil 9 import shutil
11 import re 10 import re
12 import sys 11 import sys
13 import textwrap 12 import textwrap
14 13
15 from util import build_utils 14 from util import build_utils
16 from util import md5_check 15 from util import md5_check
17 16
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 return '\n'.join(map(ApplyColor, output.split('\n'))) 53 return '\n'.join(map(ApplyColor, output.split('\n')))
55 54
56 55
57 ERRORPRONE_OPTIONS = [ 56 ERRORPRONE_OPTIONS = [
58 # These crash on lots of targets. 57 # These crash on lots of targets.
59 '-Xep:ParameterPackage:OFF', 58 '-Xep:ParameterPackage:OFF',
60 '-Xep:OverridesGuiceInjectableMethod:OFF', 59 '-Xep:OverridesGuiceInjectableMethod:OFF',
61 '-Xep:OverridesJavaxInjectableMethod:OFF', 60 '-Xep:OverridesJavaxInjectableMethod:OFF',
62 ] 61 ]
63 62
64 def DoJavac(
65 bootclasspath, classpath, classes_dir, chromium_code,
66 use_errorprone_path, java_files):
67 """Runs javac.
68 63
69 Builds |java_files| with the provided |classpath| and puts the generated 64 def _FilterJavaFiles(paths, filters):
70 .class files into |classes_dir|. If |chromium_code| is true, extra lint 65 return [f for f in paths
71 checking will be enabled. 66 if not filters or build_utils.MatchesGlob(f, filters)]
72 """
73
74 jar_inputs = []
75 for path in classpath:
76 if os.path.exists(path + '.TOC'):
77 jar_inputs.append(path + '.TOC')
78 else:
79 jar_inputs.append(path)
80
81 javac_args = [
82 '-g',
83 # Chromium only allows UTF8 source files. Being explicit avoids
84 # javac pulling a default encoding from the user's environment.
85 '-encoding', 'UTF-8',
86 '-classpath', ':'.join(classpath),
87 '-d', classes_dir]
88
89 if bootclasspath:
90 javac_args.extend([
91 '-bootclasspath', ':'.join(bootclasspath),
92 '-source', '1.7',
93 '-target', '1.7',
94 ])
95
96 if chromium_code:
97 # TODO(aurimas): re-enable '-Xlint:deprecation' checks once they are fixed.
98 javac_args.extend(['-Xlint:unchecked'])
99 else:
100 # XDignore.symbol.file makes javac compile against rt.jar instead of
101 # ct.sym. This means that using a java internal package/class will not
102 # trigger a compile warning or error.
103 javac_args.extend(['-XDignore.symbol.file'])
104
105 if use_errorprone_path:
106 javac_cmd = [use_errorprone_path] + ERRORPRONE_OPTIONS
107 else:
108 javac_cmd = ['javac']
109
110 javac_cmd = javac_cmd + javac_args + java_files
111
112 def Compile():
113 build_utils.CheckOutput(
114 javac_cmd,
115 print_stdout=chromium_code,
116 stderr_filter=ColorJavacOutput)
117
118 record_path = os.path.join(classes_dir, 'javac.md5.stamp')
119 md5_check.CallAndRecordIfStale(
120 Compile,
121 record_path=record_path,
122 input_paths=java_files + jar_inputs,
123 input_strings=javac_cmd)
124 67
125 68
126 _MAX_MANIFEST_LINE_LEN = 72 69 _MAX_MANIFEST_LINE_LEN = 72
127 70
128 71
129 def CreateManifest(manifest_path, classpath, main_class=None, 72 def _CreateManifest(manifest_path, classpath, main_class=None,
130 manifest_entries=None): 73 manifest_entries=None):
131 """Creates a manifest file with the given parameters. 74 """Creates a manifest file with the given parameters.
132 75
133 This generates a manifest file that compiles with the spec found at 76 This generates a manifest file that compiles with the spec found at
134 http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifes t 77 http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifes t
135 78
136 Args: 79 Args:
137 manifest_path: The path to the manifest file that should be created. 80 manifest_path: The path to the manifest file that should be created.
138 classpath: The JAR files that should be listed on the manifest file's 81 classpath: The JAR files that should be listed on the manifest file's
139 classpath. 82 classpath.
140 main_class: If present, the class containing the main() function. 83 main_class: If present, the class containing the main() function.
(...skipping 18 matching lines...) Expand all
159 wrapper = textwrap.TextWrapper(break_long_words=True, 102 wrapper = textwrap.TextWrapper(break_long_words=True,
160 drop_whitespace=False, 103 drop_whitespace=False,
161 subsequent_indent=' ', 104 subsequent_indent=' ',
162 width=_MAX_MANIFEST_LINE_LEN - 2) 105 width=_MAX_MANIFEST_LINE_LEN - 2)
163 output = '\r\n'.join(w for l in output for w in wrapper.wrap(l)) 106 output = '\r\n'.join(w for l in output for w in wrapper.wrap(l))
164 107
165 with open(manifest_path, 'w') as f: 108 with open(manifest_path, 'w') as f:
166 f.write(output) 109 f.write(output)
167 110
168 111
169 def main(argv): 112 def _ParseOptions(argv):
170 colorama.init()
171
172 argv = build_utils.ExpandFileArgs(argv)
173
174 parser = optparse.OptionParser() 113 parser = optparse.OptionParser()
175 build_utils.AddDepfileOption(parser) 114 build_utils.AddDepfileOption(parser)
176 115
177 parser.add_option( 116 parser.add_option(
178 '--src-gendirs', 117 '--src-gendirs',
179 help='Directories containing generated java files.') 118 help='Directories containing generated java files.')
180 parser.add_option( 119 parser.add_option(
181 '--java-srcjars', 120 '--java-srcjars',
182 action='append', 121 action='append',
183 default=[], 122 default=[],
184 help='List of srcjars to include in compilation.') 123 help='List of srcjars to include in compilation.')
185 parser.add_option( 124 parser.add_option(
186 '--bootclasspath', 125 '--bootclasspath',
187 action='append', 126 action='append',
188 default=[], 127 default=[],
189 help='Boot classpath for javac. If this is specified multiple times, ' 128 help='Boot classpath for javac. If this is specified multiple times, '
190 'they will all be appended to construct the classpath.') 129 'they will all be appended to construct the classpath.')
191 parser.add_option( 130 parser.add_option(
192 '--classpath', 131 '--classpath',
193 action='append', 132 action='append',
194 help='Classpath for javac. If this is specified multiple times, they ' 133 help='Classpath for javac. If this is specified multiple times, they '
195 'will all be appended to construct the classpath.') 134 'will all be appended to construct the classpath.')
196 parser.add_option( 135 parser.add_option(
197 '--javac-includes', 136 '--javac-includes',
137 default='',
198 help='A list of file patterns. If provided, only java files that match' 138 help='A list of file patterns. If provided, only java files that match'
199 'one of the patterns will be compiled.') 139 'one of the patterns will be compiled.')
200 parser.add_option( 140 parser.add_option(
201 '--jar-excluded-classes', 141 '--jar-excluded-classes',
202 default='', 142 default='',
203 help='List of .class file patterns to exclude from the jar.') 143 help='List of .class file patterns to exclude from the jar.')
204 144
205 parser.add_option( 145 parser.add_option(
206 '--chromium-code', 146 '--chromium-code',
207 type='int', 147 type='int',
208 help='Whether code being compiled should be built with stricter ' 148 help='Whether code being compiled should be built with stricter '
209 'warnings for chromium code.') 149 'warnings for chromium code.')
210 150
211 parser.add_option( 151 parser.add_option(
212 '--use-errorprone-path', 152 '--use-errorprone-path',
213 help='Use the Errorprone compiler at this path.') 153 help='Use the Errorprone compiler at this path.')
214 154
215 parser.add_option(
216 '--classes-dir',
217 help='Directory for compiled .class files.')
218 parser.add_option('--jar-path', help='Jar output path.') 155 parser.add_option('--jar-path', help='Jar output path.')
219 parser.add_option( 156 parser.add_option(
220 '--main-class', 157 '--main-class',
221 help='The class containing the main method.') 158 help='The class containing the main method.')
222 parser.add_option( 159 parser.add_option(
223 '--manifest-entry', 160 '--manifest-entry',
224 action='append', 161 action='append',
225 help='Key:value pairs to add to the .jar manifest.') 162 help='Key:value pairs to add to the .jar manifest.')
226 163
227 parser.add_option('--stamp', help='Path to touch on success.') 164 parser.add_option('--stamp', help='Path to touch on success.')
228 165
229 options, args = parser.parse_args(argv) 166 options, args = parser.parse_args(argv)
230 167 build_utils.CheckOptions(options, parser, required=('jar_path',))
231 if options.main_class and not options.jar_path:
232 parser.error('--main-class requires --jar-path')
233 168
234 bootclasspath = [] 169 bootclasspath = []
235 for arg in options.bootclasspath: 170 for arg in options.bootclasspath:
236 bootclasspath += build_utils.ParseGypList(arg) 171 bootclasspath += build_utils.ParseGypList(arg)
172 options.bootclasspath = bootclasspath
237 173
238 classpath = [] 174 classpath = []
239 for arg in options.classpath: 175 for arg in options.classpath:
240 classpath += build_utils.ParseGypList(arg) 176 classpath += build_utils.ParseGypList(arg)
177 options.classpath = classpath
241 178
242 java_srcjars = [] 179 java_srcjars = []
243 for arg in options.java_srcjars: 180 for arg in options.java_srcjars:
244 java_srcjars += build_utils.ParseGypList(arg) 181 java_srcjars += build_utils.ParseGypList(arg)
182 options.java_srcjars = java_srcjars
245 183
246 java_files = args
247 if options.src_gendirs: 184 if options.src_gendirs:
248 src_gendirs = build_utils.ParseGypList(options.src_gendirs) 185 options.src_gendirs = build_utils.ParseGypList(options.src_gendirs)
249 java_files += build_utils.FindInDirectories(src_gendirs, '*.java')
250 186
251 input_files = bootclasspath + classpath + java_srcjars + java_files 187 options.javac_includes = build_utils.ParseGypList(options.javac_includes)
252 with build_utils.TempDir() as temp_dir: 188 options.jar_excluded_classes = (
253 classes_dir = os.path.join(temp_dir, 'classes') 189 build_utils.ParseGypList(options.jar_excluded_classes))
254 os.makedirs(classes_dir) 190 return options, args
255 if java_srcjars:
256 java_dir = os.path.join(temp_dir, 'java')
257 os.makedirs(java_dir)
258 for srcjar in java_srcjars:
259 build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
260 java_files += build_utils.FindInDirectory(java_dir, '*.java')
261 191
262 if options.javac_includes:
263 javac_includes = build_utils.ParseGypList(options.javac_includes)
264 filtered_java_files = []
265 for f in java_files:
266 for include in javac_includes:
267 if fnmatch.fnmatch(f, include):
268 filtered_java_files.append(f)
269 break
270 java_files = filtered_java_files
271 192
272 if len(java_files) != 0: 193 def main(argv):
273 DoJavac( 194 colorama.init()
274 bootclasspath,
275 classpath,
276 classes_dir,
277 options.chromium_code,
278 options.use_errorprone_path,
279 java_files)
280 195
281 if options.jar_path: 196 argv = build_utils.ExpandFileArgs(argv)
197 options, java_files = _ParseOptions(argv)
198
199 if options.src_gendirs:
200 java_files += build_utils.FindInDirectories(options.src_gendirs, '*.java')
201
202 java_files = _FilterJavaFiles(java_files, options.javac_includes)
203
204 javac_args = [
205 '-g',
206 # Chromium only allows UTF8 source files. Being explicit avoids
207 # javac pulling a default encoding from the user's environment.
208 '-encoding', 'UTF-8',
209 '-classpath', ':'.join(options.classpath),
210 ]
211
212 if options.bootclasspath:
213 javac_args.extend([
214 '-bootclasspath', ':'.join(options.bootclasspath),
215 '-source', '1.7',
216 '-target', '1.7',
217 ])
218
219 if options.chromium_code:
220 # TODO(aurimas): re-enable '-Xlint:deprecation' checks once they are fixed.
221 javac_args.extend(['-Xlint:unchecked'])
222 else:
223 # XDignore.symbol.file makes javac compile against rt.jar instead of
224 # ct.sym. This means that using a java internal package/class will not
225 # trigger a compile warning or error.
226 javac_args.extend(['-XDignore.symbol.file'])
227
228 javac_cmd = ['javac']
229 if options.use_errorprone_path:
230 javac_cmd = [options.use_errorprone_path] + ERRORPRONE_OPTIONS
231
232 # Compute the list of paths that when changed, we need to rebuild.
233 input_paths = options.bootclasspath + options.java_srcjars + java_files
234 for path in options.classpath:
235 if os.path.exists(path + '.TOC'):
236 input_paths.append(path + '.TOC')
237 else:
238 input_paths.append(path)
239 python_deps = build_utils.GetPythonDependencies()
240
241 def OnStaleMd5():
242 with build_utils.TempDir() as temp_dir:
243 if options.java_srcjars:
244 java_dir = os.path.join(temp_dir, 'java')
245 os.makedirs(java_dir)
246 for srcjar in options.java_srcjars:
247 build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
248 jar_srcs = build_utils.FindInDirectory(java_dir, '*.java')
249 java_files.extend(_FilterJavaFiles(jar_srcs, options.javac_includes))
250
251 classes_dir = os.path.join(temp_dir, 'classes')
252 os.makedirs(classes_dir)
253
254 if java_files:
255 # Don't include the output directory in the initial set of args since it
256 # being in a temp dir makes it unstable (breaks md5 stamping).
257 cmd = javac_cmd + javac_args + ['-d', classes_dir] + java_files
258
259 build_utils.CheckOutput(
260 cmd,
261 print_stdout=options.chromium_code,
262 stderr_filter=ColorJavacOutput)
263
282 if options.main_class or options.manifest_entry: 264 if options.main_class or options.manifest_entry:
265 entries = []
283 if options.manifest_entry: 266 if options.manifest_entry:
284 entries = map(lambda e: e.split(":"), options.manifest_entry) 267 entries = [e.split(':') for e in options.manifest_entry]
285 else:
286 entries = []
287 manifest_file = os.path.join(temp_dir, 'manifest') 268 manifest_file = os.path.join(temp_dir, 'manifest')
288 CreateManifest(manifest_file, classpath, options.main_class, entries) 269 _CreateManifest(manifest_file, options.classpath, options.main_class,
270 entries)
289 else: 271 else:
290 manifest_file = None 272 manifest_file = None
291 jar.JarDirectory(classes_dir, 273 jar.JarDirectory(classes_dir,
292 build_utils.ParseGypList(options.jar_excluded_classes), 274 options.jar_excluded_classes,
293 options.jar_path, 275 options.jar_path,
294 manifest_file=manifest_file) 276 manifest_file=manifest_file)
295 277
296 if options.classes_dir: 278 if options.stamp:
297 # Delete the old classes directory. This ensures that all .class files in 279 build_utils.Touch(options.stamp)
298 # the output are actually from the input .java files. For example, if a
299 # .java file is deleted or an inner class is removed, the classes
300 # directory should not contain the corresponding old .class file after
301 # running this action.
302 build_utils.DeleteDirectory(options.classes_dir)
303 shutil.copytree(classes_dir, options.classes_dir)
304 280
305 if options.depfile: 281 if options.depfile:
306 build_utils.WriteDepfile( 282 build_utils.WriteDepfile(options.depfile, input_paths + python_deps)
307 options.depfile,
308 input_files + build_utils.GetPythonDependencies())
309 283
310 if options.stamp: 284
311 build_utils.Touch(options.stamp) 285 # List python deps in input_strings rather than input_paths since the contents
286 # of them does not change what gets written to the depsfile.
287 md5_check.CallAndRecordIfStale(
288 OnStaleMd5,
289 record_path=options.jar_path + '.javac.md5.stamp',
290 input_paths=input_paths,
291 input_strings=javac_cmd + javac_args + python_deps,
292 force=not os.path.exists(options.jar_path))
293
312 294
313 295
314 if __name__ == '__main__': 296 if __name__ == '__main__':
315 sys.exit(main(sys.argv[1:])) 297 sys.exit(main(sys.argv[1:]))
316 298
317 299
OLDNEW
« no previous file with comments | « build/android/gyp/jar.py ('k') | build/android/gyp/util/build_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698