cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / build / android / gyp / javac.py
blob97ecb7bdc5d2f0e259dd5fb97f2b779ea6f1d70b
1 #!/usr/bin/env python
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
5 # found in the LICENSE file.
7 import optparse
8 import os
9 import shutil
10 import re
11 import sys
12 import textwrap
14 from util import build_utils
15 from util import md5_check
17 import jar
19 sys.path.append(build_utils.COLORAMA_ROOT)
20 import colorama
23 def ColorJavacOutput(output):
24 fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)'
25 warning_re = re.compile(
26 fileline_prefix + r'(?P<full_message> warning: (?P<message>.*))$')
27 error_re = re.compile(
28 fileline_prefix + r'(?P<full_message> (?P<message>.*))$')
29 marker_re = re.compile(r'\s*(?P<marker>\^)\s*$')
31 warning_color = ['full_message', colorama.Fore.YELLOW + colorama.Style.DIM]
32 error_color = ['full_message', colorama.Fore.MAGENTA + colorama.Style.BRIGHT]
33 marker_color = ['marker', colorama.Fore.BLUE + colorama.Style.BRIGHT]
35 def Colorize(line, regex, color):
36 match = regex.match(line)
37 start = match.start(color[0])
38 end = match.end(color[0])
39 return (line[:start]
40 + color[1] + line[start:end]
41 + colorama.Fore.RESET + colorama.Style.RESET_ALL
42 + line[end:])
44 def ApplyColor(line):
45 if warning_re.match(line):
46 line = Colorize(line, warning_re, warning_color)
47 elif error_re.match(line):
48 line = Colorize(line, error_re, error_color)
49 elif marker_re.match(line):
50 line = Colorize(line, marker_re, marker_color)
51 return line
53 return '\n'.join(map(ApplyColor, output.split('\n')))
56 ERRORPRONE_OPTIONS = [
57 # These crash on lots of targets.
58 '-Xep:ParameterPackage:OFF',
59 '-Xep:OverridesGuiceInjectableMethod:OFF',
60 '-Xep:OverridesJavaxInjectableMethod:OFF',
64 def _FilterJavaFiles(paths, filters):
65 return [f for f in paths
66 if not filters or build_utils.MatchesGlob(f, filters)]
69 _MAX_MANIFEST_LINE_LEN = 72
72 def _CreateManifest(manifest_path, classpath, main_class=None,
73 manifest_entries=None):
74 """Creates a manifest file with the given parameters.
76 This generates a manifest file that compiles with the spec found at
77 http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifest
79 Args:
80 manifest_path: The path to the manifest file that should be created.
81 classpath: The JAR files that should be listed on the manifest file's
82 classpath.
83 main_class: If present, the class containing the main() function.
84 manifest_entries: If present, a list of (key, value) pairs to add to
85 the manifest.
87 """
88 output = ['Manifest-Version: 1.0']
89 if main_class:
90 output.append('Main-Class: %s' % main_class)
91 if manifest_entries:
92 for k, v in manifest_entries:
93 output.append('%s: %s' % (k, v))
94 if classpath:
95 sanitized_paths = []
96 for path in classpath:
97 sanitized_paths.append(os.path.basename(path.strip('"')))
98 output.append('Class-Path: %s' % ' '.join(sanitized_paths))
99 output.append('Created-By: ')
100 output.append('')
102 wrapper = textwrap.TextWrapper(break_long_words=True,
103 drop_whitespace=False,
104 subsequent_indent=' ',
105 width=_MAX_MANIFEST_LINE_LEN - 2)
106 output = '\r\n'.join(w for l in output for w in wrapper.wrap(l))
108 with open(manifest_path, 'w') as f:
109 f.write(output)
112 def _ParseOptions(argv):
113 parser = optparse.OptionParser()
114 build_utils.AddDepfileOption(parser)
116 parser.add_option(
117 '--src-gendirs',
118 help='Directories containing generated java files.')
119 parser.add_option(
120 '--java-srcjars',
121 action='append',
122 default=[],
123 help='List of srcjars to include in compilation.')
124 parser.add_option(
125 '--bootclasspath',
126 action='append',
127 default=[],
128 help='Boot classpath for javac. If this is specified multiple times, '
129 'they will all be appended to construct the classpath.')
130 parser.add_option(
131 '--classpath',
132 action='append',
133 help='Classpath for javac. If this is specified multiple times, they '
134 'will all be appended to construct the classpath.')
135 parser.add_option(
136 '--use-ijars',
137 action='store_true',
138 help='Whether to use interface jars (.interface.jar) when compiling')
139 parser.add_option(
140 '--javac-includes',
141 default='',
142 help='A list of file patterns. If provided, only java files that match'
143 'one of the patterns will be compiled.')
144 parser.add_option(
145 '--jar-excluded-classes',
146 default='',
147 help='List of .class file patterns to exclude from the jar.')
149 parser.add_option(
150 '--chromium-code',
151 type='int',
152 help='Whether code being compiled should be built with stricter '
153 'warnings for chromium code.')
155 parser.add_option(
156 '--use-errorprone-path',
157 help='Use the Errorprone compiler at this path.')
159 parser.add_option('--jar-path', help='Jar output path.')
160 parser.add_option(
161 '--main-class',
162 help='The class containing the main method.')
163 parser.add_option(
164 '--manifest-entry',
165 action='append',
166 help='Key:value pairs to add to the .jar manifest.')
168 parser.add_option('--stamp', help='Path to touch on success.')
170 options, args = parser.parse_args(argv)
171 build_utils.CheckOptions(options, parser, required=('jar_path',))
173 bootclasspath = []
174 for arg in options.bootclasspath:
175 bootclasspath += build_utils.ParseGypList(arg)
176 options.bootclasspath = bootclasspath
178 classpath = []
179 for arg in options.classpath:
180 classpath += build_utils.ParseGypList(arg)
181 options.classpath = classpath
183 java_srcjars = []
184 for arg in options.java_srcjars:
185 java_srcjars += build_utils.ParseGypList(arg)
186 options.java_srcjars = java_srcjars
188 if options.src_gendirs:
189 options.src_gendirs = build_utils.ParseGypList(options.src_gendirs)
191 options.javac_includes = build_utils.ParseGypList(options.javac_includes)
192 options.jar_excluded_classes = (
193 build_utils.ParseGypList(options.jar_excluded_classes))
194 return options, args
197 def main(argv):
198 colorama.init()
200 argv = build_utils.ExpandFileArgs(argv)
201 options, java_files = _ParseOptions(argv)
203 if options.src_gendirs:
204 java_files += build_utils.FindInDirectories(options.src_gendirs, '*.java')
206 java_files = _FilterJavaFiles(java_files, options.javac_includes)
208 runtime_classpath = options.classpath
209 compile_classpath = runtime_classpath
210 if options.use_ijars:
211 ijar_re = re.compile(r'\.jar$')
212 compile_classpath = (
213 [ijar_re.sub('.interface.jar', p) for p in runtime_classpath])
215 javac_args = [
216 '-g',
217 # Chromium only allows UTF8 source files. Being explicit avoids
218 # javac pulling a default encoding from the user's environment.
219 '-encoding', 'UTF-8',
220 '-classpath', ':'.join(compile_classpath),
223 if options.bootclasspath:
224 javac_args.extend([
225 '-bootclasspath', ':'.join(options.bootclasspath),
226 '-source', '1.7',
227 '-target', '1.7',
230 if options.chromium_code:
231 # TODO(aurimas): re-enable '-Xlint:deprecation' checks once they are fixed.
232 javac_args.extend(['-Xlint:unchecked'])
233 else:
234 # XDignore.symbol.file makes javac compile against rt.jar instead of
235 # ct.sym. This means that using a java internal package/class will not
236 # trigger a compile warning or error.
237 javac_args.extend(['-XDignore.symbol.file'])
239 javac_cmd = ['javac']
240 if options.use_errorprone_path:
241 javac_cmd = [options.use_errorprone_path] + ERRORPRONE_OPTIONS
243 # Compute the list of paths that when changed, we need to rebuild.
244 input_paths = options.bootclasspath + options.java_srcjars + java_files
245 # TODO(agrieve): Remove this .TOC heuristic once GYP is no more.
246 if not options.use_ijars:
247 for path in compile_classpath:
248 if os.path.exists(path + '.TOC'):
249 input_paths.append(path + '.TOC')
250 else:
251 input_paths.append(path)
252 python_deps = build_utils.GetPythonDependencies()
254 def OnStaleMd5():
255 with build_utils.TempDir() as temp_dir:
256 if options.java_srcjars:
257 java_dir = os.path.join(temp_dir, 'java')
258 os.makedirs(java_dir)
259 for srcjar in options.java_srcjars:
260 build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
261 jar_srcs = build_utils.FindInDirectory(java_dir, '*.java')
262 java_files.extend(_FilterJavaFiles(jar_srcs, options.javac_includes))
264 classes_dir = os.path.join(temp_dir, 'classes')
265 os.makedirs(classes_dir)
267 if java_files:
268 # Don't include the output directory in the initial set of args since it
269 # being in a temp dir makes it unstable (breaks md5 stamping).
270 cmd = javac_cmd + javac_args + ['-d', classes_dir] + java_files
272 build_utils.CheckOutput(
273 cmd,
274 print_stdout=options.chromium_code,
275 stderr_filter=ColorJavacOutput)
277 if options.main_class or options.manifest_entry:
278 entries = []
279 if options.manifest_entry:
280 entries = [e.split(':') for e in options.manifest_entry]
281 manifest_file = os.path.join(temp_dir, 'manifest')
282 _CreateManifest(manifest_file, runtime_classpath, options.main_class,
283 entries)
284 else:
285 manifest_file = None
286 jar.JarDirectory(classes_dir,
287 options.jar_excluded_classes,
288 options.jar_path,
289 manifest_file=manifest_file)
291 if options.stamp:
292 build_utils.Touch(options.stamp)
294 if options.depfile:
295 build_utils.WriteDepfile(options.depfile, input_paths + python_deps)
298 # List python deps in input_strings rather than input_paths since the contents
299 # of them does not change what gets written to the depsfile.
300 md5_check.CallAndRecordIfStale(
301 OnStaleMd5,
302 record_path=options.jar_path + '.javac.md5.stamp',
303 input_paths=input_paths,
304 input_strings=javac_cmd + javac_args + python_deps,
305 force=not os.path.exists(options.jar_path))
309 if __name__ == '__main__':
310 sys.exit(main(sys.argv[1:]))