diff options
Diffstat (limited to 'third_party/libwebrtc/build/android/gyp/compile_java.py')
-rwxr-xr-x | third_party/libwebrtc/build/android/gyp/compile_java.py | 787 |
1 files changed, 787 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/android/gyp/compile_java.py b/third_party/libwebrtc/build/android/gyp/compile_java.py new file mode 100755 index 0000000000..b11665e2a7 --- /dev/null +++ b/third_party/libwebrtc/build/android/gyp/compile_java.py @@ -0,0 +1,787 @@ +#!/usr/bin/env python3 +# +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import functools +import logging +import multiprocessing +import optparse +import os +import re +import shutil +import sys +import time +import zipfile + +import javac_output_processor +from util import build_utils +from util import md5_check +from util import jar_info_utils +from util import server_utils + +_JAVAC_EXTRACTOR = os.path.join(build_utils.DIR_SOURCE_ROOT, 'third_party', + 'android_prebuilts', 'build_tools', 'common', + 'framework', 'javac_extractor.jar') + +# Add a check here to cause the suggested fix to be applied while compiling. +# Use this when trying to enable more checks. +ERRORPRONE_CHECKS_TO_APPLY = [] + +# Full list of checks: https://errorprone.info/bugpatterns +ERRORPRONE_WARNINGS_TO_DISABLE = [ + # The following are super useful, but existing issues need to be fixed first + # before they can start failing the build on new errors. + 'InvalidParam', + 'InvalidLink', + 'InvalidInlineTag', + 'EmptyBlockTag', + 'PublicConstructorForAbstractClass', + 'InvalidBlockTag', + 'StaticAssignmentInConstructor', + 'MutablePublicArray', + 'UnescapedEntity', + 'NonCanonicalType', + 'AlmostJavadoc', + # The following are added for errorprone update: https://crbug.com/1216032 + 'InlineMeSuggester', + 'DoNotClaimAnnotations', + 'JavaUtilDate', + 'IdentityHashMapUsage', + 'UnnecessaryMethodReference', + 'LongFloatConversion', + 'CharacterGetNumericValue', + 'ErroneousThreadPoolConstructorChecker', + 'StaticMockMember', + 'MissingSuperCall', + 'ToStringReturnsNull', + # TODO(crbug.com/834807): Follow steps in bug + 'DoubleBraceInitialization', + # TODO(crbug.com/834790): Follow steps in bug. + 'CatchAndPrintStackTrace', + # TODO(crbug.com/801210): Follow steps in bug. + 'SynchronizeOnNonFinalField', + # TODO(crbug.com/802073): Follow steps in bug. + 'TypeParameterUnusedInFormals', + # TODO(crbug.com/803484): Follow steps in bug. + 'CatchFail', + # TODO(crbug.com/803485): Follow steps in bug. + 'JUnitAmbiguousTestClass', + # Android platform default is always UTF-8. + # https://developer.android.com/reference/java/nio/charset/Charset.html#defaultCharset() + 'DefaultCharset', + # Low priority since there are lots of tags that don't fit this check. + 'UnrecognisedJavadocTag', + # Low priority since the alternatives still work. + 'JdkObsolete', + # We don't use that many lambdas. + 'FunctionalInterfaceClash', + # There are lots of times when we just want to post a task. + 'FutureReturnValueIgnored', + # Nice to be explicit about operators, but not necessary. + 'OperatorPrecedence', + # Just false positives in our code. + 'ThreadJoinLoop', + # Low priority corner cases with String.split. + # Linking Guava and using Splitter was rejected + # in the https://chromium-review.googlesource.com/c/chromium/src/+/871630. + 'StringSplitter', + # Preferred to use another method since it propagates exceptions better. + 'ClassNewInstance', + # Nice to have static inner classes but not necessary. + 'ClassCanBeStatic', + # Explicit is better than implicit. + 'FloatCast', + # Results in false positives. + 'ThreadLocalUsage', + # Also just false positives. + 'Finally', + # False positives for Chromium. + 'FragmentNotInstantiable', + # Low priority to fix. + 'HidingField', + # Low priority. + 'IntLongMath', + # Low priority. + 'BadComparable', + # Low priority. + 'EqualsHashCode', + # Nice to fix but low priority. + 'TypeParameterShadowing', + # Good to have immutable enums, also low priority. + 'ImmutableEnumChecker', + # False positives for testing. + 'InputStreamSlowMultibyteRead', + # Nice to have better primitives. + 'BoxedPrimitiveConstructor', + # Not necessary for tests. + 'OverrideThrowableToString', + # Nice to have better type safety. + 'CollectionToArraySafeParameter', + # Makes logcat debugging more difficult, and does not provide obvious + # benefits in the Chromium codebase. + 'ObjectToString', + # Triggers on private methods that are @CalledByNative. + 'UnusedMethod', + # Triggers on generated R.java files. + 'UnusedVariable', + # Not that useful. + 'UnsafeReflectiveConstructionCast', + # Not that useful. + 'MixedMutabilityReturnType', + # Nice to have. + 'EqualsGetClass', + # A lot of false-positives from CharSequence.equals(). + 'UndefinedEquals', + # Nice to have. + 'ExtendingJUnitAssert', + # Nice to have. + 'SystemExitOutsideMain', + # Nice to have. + 'TypeParameterNaming', + # Nice to have. + 'UnusedException', + # Nice to have. + 'UngroupedOverloads', + # Nice to have. + 'FunctionalInterfaceClash', + # Nice to have. + 'InconsistentOverloads', + # Dagger generated code triggers this. + 'SameNameButDifferent', + # Nice to have. + 'UnnecessaryLambda', + # Nice to have. + 'UnnecessaryAnonymousClass', + # Nice to have. + 'LiteProtoToString', + # Nice to have. + 'MissingSummary', + # Nice to have. + 'ReturnFromVoid', + # Nice to have. + 'EmptyCatch', + # Nice to have. + 'BadImport', + # Nice to have. + 'UseCorrectAssertInTests', + # Nice to have. + 'InlineFormatString', + # Nice to have. + 'DefaultPackage', + # Must be off since we are now passing in annotation processor generated + # code as a source jar (deduplicating work with turbine). + 'RefersToDaggerCodegen', + # We already have presubmit checks for this. Not necessary to warn on + # every build. + 'RemoveUnusedImports', + # We do not care about unnecessary parenthesis enough to check for them. + 'UnnecessaryParentheses', +] + +# Full list of checks: https://errorprone.info/bugpatterns +# Only those marked as "experimental" need to be listed here in order to be +# enabled. +ERRORPRONE_WARNINGS_TO_ENABLE = [ + 'BinderIdentityRestoredDangerously', + 'EmptyIf', + 'EqualsBrokenForNull', + 'InvalidThrows', + 'LongLiteralLowerCaseSuffix', + 'MultiVariableDeclaration', + 'RedundantOverride', + 'StaticQualifiedUsingExpression', + 'StringEquality', + 'TimeUnitMismatch', + 'UnnecessaryStaticImport', + 'UseBinds', + 'WildcardImport', +] + + +def ProcessJavacOutput(output, target_name): + # These warnings cannot be suppressed even for third party code. Deprecation + # warnings especially do not help since we must support older android version. + deprecated_re = re.compile( + r'(Note: .* uses? or overrides? a deprecated API.)$') + unchecked_re = re.compile( + r'(Note: .* uses? unchecked or unsafe operations.)$') + recompile_re = re.compile(r'(Note: Recompile with -Xlint:.* for details.)$') + + activity_re = re.compile(r'^(?P<prefix>\s*location: )class Activity$') + + def ApplyFilters(line): + return not (deprecated_re.match(line) or unchecked_re.match(line) + or recompile_re.match(line)) + + def Elaborate(line): + if activity_re.match(line): + prefix = ' ' * activity_re.match(line).end('prefix') + return '{}\n{}Expecting a FragmentActivity? See {}'.format( + line, prefix, 'docs/ui/android/bytecode_rewriting.md') + return line + + output = build_utils.FilterReflectiveAccessJavaWarnings(output) + + lines = (l for l in output.split('\n') if ApplyFilters(l)) + lines = (Elaborate(l) for l in lines) + + output_processor = javac_output_processor.JavacOutputProcessor(target_name) + lines = output_processor.Process(lines) + + return '\n'.join(lines) + + +def _ParsePackageAndClassNames(java_file): + package_name = '' + class_names = [] + with open(java_file) as f: + for l in f: + # Strip unindented comments. + # Considers a leading * as a continuation of a multi-line comment (our + # linter doesn't enforce a space before it like there should be). + l = re.sub(r'^(?://.*|/?\*.*?(?:\*/\s*|$))', '', l) + + m = re.match(r'package\s+(.*?);', l) + if m and not package_name: + package_name = m.group(1) + + # Not exactly a proper parser, but works for sources that Chrome uses. + # In order to not match nested classes, it just checks for lack of indent. + m = re.match(r'(?:\S.*?)?(?:class|@?interface|enum)\s+(.+?)\b', l) + if m: + class_names.append(m.group(1)) + return package_name, class_names + + +def _ProcessJavaFileForInfo(java_file): + package_name, class_names = _ParsePackageAndClassNames(java_file) + return java_file, package_name, class_names + + +class _InfoFileContext(object): + """Manages the creation of the class->source file .info file.""" + + def __init__(self, chromium_code, excluded_globs): + self._chromium_code = chromium_code + self._excluded_globs = excluded_globs + # Map of .java path -> .srcjar/nested/path.java. + self._srcjar_files = {} + # List of generators from pool.imap_unordered(). + self._results = [] + # Lazily created multiprocessing.Pool. + self._pool = None + + def AddSrcJarSources(self, srcjar_path, extracted_paths, parent_dir): + for path in extracted_paths: + # We want the path inside the srcjar so the viewer can have a tree + # structure. + self._srcjar_files[path] = '{}/{}'.format( + srcjar_path, os.path.relpath(path, parent_dir)) + + def SubmitFiles(self, java_files): + if self._pool is None: + # Restrict to just one process to not slow down compiling. Compiling + # is always slower. + self._pool = multiprocessing.Pool(1) + logging.info('Submitting %d files for info', len(java_files)) + self._results.append( + self._pool.imap_unordered( + _ProcessJavaFileForInfo, java_files, chunksize=1000)) + + def _CheckPathMatchesClassName(self, java_file, package_name, class_name): + parts = package_name.split('.') + [class_name + '.java'] + expected_path_suffix = os.path.sep.join(parts) + if not java_file.endswith(expected_path_suffix): + raise Exception(('Java package+class name do not match its path.\n' + 'Actual path: %s\nExpected path: %s') % + (java_file, expected_path_suffix)) + + def _ProcessInfo(self, java_file, package_name, class_names, source): + for class_name in class_names: + yield '{}.{}'.format(package_name, class_name) + # Skip aidl srcjars since they don't indent code correctly. + if '_aidl.srcjar' in source: + continue + assert not self._chromium_code or len(class_names) == 1, ( + 'Chromium java files must only have one class: {}'.format(source)) + if self._chromium_code: + # This check is not necessary but nice to check this somewhere. + self._CheckPathMatchesClassName(java_file, package_name, class_names[0]) + + def _ShouldIncludeInJarInfo(self, fully_qualified_name): + name_as_class_glob = fully_qualified_name.replace('.', '/') + '.class' + return not build_utils.MatchesGlob(name_as_class_glob, self._excluded_globs) + + def _Collect(self): + if self._pool is None: + return {} + ret = {} + for result in self._results: + for java_file, package_name, class_names in result: + source = self._srcjar_files.get(java_file, java_file) + for fully_qualified_name in self._ProcessInfo(java_file, package_name, + class_names, source): + if self._ShouldIncludeInJarInfo(fully_qualified_name): + ret[fully_qualified_name] = java_file + self._pool.terminate() + return ret + + def __del__(self): + # Work around for Python 2.x bug with multiprocessing and daemon threads: + # https://bugs.python.org/issue4106 + if self._pool is not None: + logging.info('Joining multiprocessing.Pool') + self._pool.terminate() + self._pool.join() + logging.info('Done.') + + def Commit(self, output_path): + """Writes a .jar.info file. + + Maps fully qualified names for classes to either the java file that they + are defined in or the path of the srcjar that they came from. + """ + logging.info('Collecting info file entries') + entries = self._Collect() + + logging.info('Writing info file: %s', output_path) + with build_utils.AtomicOutput(output_path, mode='wb') as f: + jar_info_utils.WriteJarInfoFile(f, entries, self._srcjar_files) + logging.info('Completed info file: %s', output_path) + + +def _CreateJarFile(jar_path, service_provider_configuration_dir, + additional_jar_files, classes_dir): + logging.info('Start creating jar file: %s', jar_path) + with build_utils.AtomicOutput(jar_path) as f: + with zipfile.ZipFile(f.name, 'w') as z: + build_utils.ZipDir(z, classes_dir) + if service_provider_configuration_dir: + config_files = build_utils.FindInDirectory( + service_provider_configuration_dir) + for config_file in config_files: + zip_path = os.path.relpath(config_file, + service_provider_configuration_dir) + build_utils.AddToZipHermetic(z, zip_path, src_path=config_file) + + if additional_jar_files: + for src_path, zip_path in additional_jar_files: + build_utils.AddToZipHermetic(z, zip_path, src_path=src_path) + logging.info('Completed jar file: %s', jar_path) + + +def _OnStaleMd5(changes, options, javac_cmd, javac_args, java_files): + logging.info('Starting _OnStaleMd5') + if options.enable_kythe_annotations: + # Kythe requires those env variables to be set and compile_java.py does the + # same + if not os.environ.get('KYTHE_ROOT_DIRECTORY') or \ + not os.environ.get('KYTHE_OUTPUT_DIRECTORY'): + raise Exception('--enable-kythe-annotations requires ' + 'KYTHE_ROOT_DIRECTORY and KYTHE_OUTPUT_DIRECTORY ' + 'environment variables to be set.') + javac_extractor_cmd = build_utils.JavaCmd() + [ + '-jar', + _JAVAC_EXTRACTOR, + ] + try: + # _RunCompiler()'s partial javac implementation does not support + # generating outputs in $KYTHE_OUTPUT_DIRECTORY. + _RunCompiler(changes, + options, + javac_extractor_cmd + javac_args, + java_files, + options.jar_path + '.javac_extractor', + enable_partial_javac=False) + except build_utils.CalledProcessError as e: + # Having no index for particular target is better than failing entire + # codesearch. Log and error and move on. + logging.error('Could not generate kzip: %s', e) + + intermediates_out_dir = None + jar_info_path = None + if not options.enable_errorprone: + # Delete any stale files in the generated directory. The purpose of + # options.generated_dir is for codesearch. + shutil.rmtree(options.generated_dir, True) + intermediates_out_dir = options.generated_dir + + jar_info_path = options.jar_path + '.info' + + # Compiles with Error Prone take twice as long to run as pure javac. Thus GN + # rules run both in parallel, with Error Prone only used for checks. + _RunCompiler(changes, + options, + javac_cmd + javac_args, + java_files, + options.jar_path, + jar_info_path=jar_info_path, + intermediates_out_dir=intermediates_out_dir, + enable_partial_javac=True) + logging.info('Completed all steps in _OnStaleMd5') + + +def _RunCompiler(changes, + options, + javac_cmd, + java_files, + jar_path, + jar_info_path=None, + intermediates_out_dir=None, + enable_partial_javac=False): + """Runs java compiler. + + Args: + changes: md5_check.Changes object. + options: Object with command line flags. + javac_cmd: Command to execute. + java_files: List of java files passed from command line. + jar_path: Path of output jar file. + jar_info_path: Path of the .info file to generate. + If None, .info file will not be generated. + intermediates_out_dir: Directory for saving intermediate outputs. + If None a temporary directory is used. + enable_partial_javac: Enables compiling only Java files which have changed + in the special case that no method signatures have changed. This is + useful for large GN targets. + Not supported if compiling generates outputs other than |jar_path| and + |jar_info_path|. + """ + logging.info('Starting _RunCompiler') + + java_files = java_files.copy() + java_srcjars = options.java_srcjars + save_info_file = jar_info_path is not None + + # Use jar_path's directory to ensure paths are relative (needed for goma). + temp_dir = jar_path + '.staging' + shutil.rmtree(temp_dir, True) + os.makedirs(temp_dir) + try: + classes_dir = os.path.join(temp_dir, 'classes') + service_provider_configuration = os.path.join( + temp_dir, 'service_provider_configuration') + + if java_files: + os.makedirs(classes_dir) + + if enable_partial_javac: + all_changed_paths_are_java = all( + [p.endswith(".java") for p in changes.IterChangedPaths()]) + if (all_changed_paths_are_java and not changes.HasStringChanges() + and os.path.exists(jar_path) + and (jar_info_path is None or os.path.exists(jar_info_path))): + # Log message is used by tests to determine whether partial javac + # optimization was used. + logging.info('Using partial javac optimization for %s compile' % + (jar_path)) + + # Header jar corresponding to |java_files| did not change. + # As a build speed optimization (crbug.com/1170778), re-compile only + # java files which have changed. Re-use old jar .info file. + java_files = list(changes.IterChangedPaths()) + java_srcjars = None + + # Reuse old .info file. + save_info_file = False + + build_utils.ExtractAll(jar_path, classes_dir) + + if save_info_file: + info_file_context = _InfoFileContext(options.chromium_code, + options.jar_info_exclude_globs) + + if intermediates_out_dir is None: + input_srcjars_dir = os.path.join(temp_dir, 'input_srcjars') + else: + input_srcjars_dir = os.path.join(intermediates_out_dir, 'input_srcjars') + + if java_srcjars: + logging.info('Extracting srcjars to %s', input_srcjars_dir) + build_utils.MakeDirectory(input_srcjars_dir) + for srcjar in options.java_srcjars: + extracted_files = build_utils.ExtractAll( + srcjar, no_clobber=True, path=input_srcjars_dir, pattern='*.java') + java_files.extend(extracted_files) + if save_info_file: + info_file_context.AddSrcJarSources(srcjar, extracted_files, + input_srcjars_dir) + logging.info('Done extracting srcjars') + + if options.header_jar: + logging.info('Extracting service provider configs') + # Extract META-INF/services/* so that it can be copied into the output + # .jar + build_utils.ExtractAll(options.header_jar, + no_clobber=True, + path=service_provider_configuration, + pattern='META-INF/services/*') + logging.info('Done extracting service provider configs') + + if save_info_file and java_files: + info_file_context.SubmitFiles(java_files) + + if java_files: + # Don't include the output directory in the initial set of args since it + # being in a temp dir makes it unstable (breaks md5 stamping). + cmd = list(javac_cmd) + cmd += ['-d', classes_dir] + + if options.classpath: + cmd += ['-classpath', ':'.join(options.classpath)] + + # Pass source paths as response files to avoid extremely long command + # lines that are tedius to debug. + java_files_rsp_path = os.path.join(temp_dir, 'files_list.txt') + with open(java_files_rsp_path, 'w') as f: + f.write(' '.join(java_files)) + cmd += ['@' + java_files_rsp_path] + + process_javac_output_partial = functools.partial( + ProcessJavacOutput, target_name=options.target_name) + + logging.debug('Build command %s', cmd) + start = time.time() + build_utils.CheckOutput(cmd, + print_stdout=options.chromium_code, + stdout_filter=process_javac_output_partial, + stderr_filter=process_javac_output_partial, + fail_on_output=options.warnings_as_errors) + end = time.time() - start + logging.info('Java compilation took %ss', end) + + _CreateJarFile(jar_path, service_provider_configuration, + options.additional_jar_files, classes_dir) + + if save_info_file: + info_file_context.Commit(jar_info_path) + + logging.info('Completed all steps in _RunCompiler') + finally: + shutil.rmtree(temp_dir) + + +def _ParseOptions(argv): + parser = optparse.OptionParser() + build_utils.AddDepfileOption(parser) + + parser.add_option('--target-name', help='Fully qualified GN target name.') + parser.add_option('--skip-build-server', + action='store_true', + help='Avoid using the build server.') + parser.add_option( + '--java-srcjars', + action='append', + default=[], + help='List of srcjars to include in compilation.') + parser.add_option( + '--generated-dir', + help='Subdirectory within target_gen_dir to place extracted srcjars and ' + 'annotation processor output for codesearch to find.') + parser.add_option( + '--bootclasspath', + action='append', + default=[], + help='Boot classpath for javac. If this is specified multiple times, ' + 'they will all be appended to construct the classpath.') + parser.add_option( + '--java-version', + help='Java language version to use in -source and -target args to javac.') + parser.add_option('--classpath', action='append', help='Classpath to use.') + parser.add_option( + '--processorpath', + action='append', + help='GN list of jars that comprise the classpath used for Annotation ' + 'Processors.') + parser.add_option( + '--processor-arg', + dest='processor_args', + action='append', + help='key=value arguments for the annotation processors.') + parser.add_option( + '--additional-jar-file', + dest='additional_jar_files', + action='append', + help='Additional files to package into jar. By default, only Java .class ' + 'files are packaged into the jar. Files should be specified in ' + 'format <filename>:<path to be placed in jar>.') + parser.add_option( + '--jar-info-exclude-globs', + help='GN list of exclude globs to filter from generated .info files.') + parser.add_option( + '--chromium-code', + type='int', + help='Whether code being compiled should be built with stricter ' + 'warnings for chromium code.') + parser.add_option( + '--gomacc-path', help='When set, prefix javac command with gomacc') + parser.add_option( + '--errorprone-path', help='Use the Errorprone compiler at this path.') + parser.add_option( + '--enable-errorprone', + action='store_true', + help='Enable errorprone checks') + parser.add_option( + '--warnings-as-errors', + action='store_true', + help='Treat all warnings as errors.') + parser.add_option('--jar-path', help='Jar output path.') + parser.add_option( + '--javac-arg', + action='append', + default=[], + help='Additional arguments to pass to javac.') + parser.add_option( + '--enable-kythe-annotations', + action='store_true', + help='Enable generation of Kythe kzip, used for codesearch. Ensure ' + 'proper environment variables are set before using this flag.') + parser.add_option( + '--header-jar', + help='This is the header jar for the current target that contains ' + 'META-INF/services/* files to be included in the output jar.') + + options, args = parser.parse_args(argv) + build_utils.CheckOptions(options, parser, required=('jar_path', )) + + options.bootclasspath = build_utils.ParseGnList(options.bootclasspath) + options.classpath = build_utils.ParseGnList(options.classpath) + options.processorpath = build_utils.ParseGnList(options.processorpath) + options.java_srcjars = build_utils.ParseGnList(options.java_srcjars) + options.jar_info_exclude_globs = build_utils.ParseGnList( + options.jar_info_exclude_globs) + + additional_jar_files = [] + for arg in options.additional_jar_files or []: + filepath, jar_filepath = arg.split(':') + additional_jar_files.append((filepath, jar_filepath)) + options.additional_jar_files = additional_jar_files + + java_files = [] + for arg in args: + # Interpret a path prefixed with @ as a file containing a list of sources. + if arg.startswith('@'): + java_files.extend(build_utils.ReadSourcesList(arg[1:])) + else: + java_files.append(arg) + + return options, java_files + + +def main(argv): + build_utils.InitLogging('JAVAC_DEBUG') + argv = build_utils.ExpandFileArgs(argv) + options, java_files = _ParseOptions(argv) + + # Only use the build server for errorprone runs. + if (options.enable_errorprone and not options.skip_build_server + and server_utils.MaybeRunCommand(name=options.target_name, + argv=sys.argv, + stamp_file=options.jar_path)): + return + + javac_cmd = [] + if options.gomacc_path: + javac_cmd.append(options.gomacc_path) + javac_cmd.append(build_utils.JAVAC_PATH) + + javac_args = [ + '-g', + # Chromium only allows UTF8 source files. Being explicit avoids + # javac pulling a default encoding from the user's environment. + '-encoding', + 'UTF-8', + # Prevent compiler from compiling .java files not listed as inputs. + # See: http://blog.ltgt.net/most-build-tools-misuse-javac/ + '-sourcepath', + ':', + ] + + if options.enable_errorprone: + # All errorprone args are passed space-separated in a single arg. + errorprone_flags = ['-Xplugin:ErrorProne'] + # Make everything a warning so that when treat_warnings_as_errors is false, + # they do not fail the build. + errorprone_flags += ['-XepAllErrorsAsWarnings'] + # Don't check generated files. + errorprone_flags += ['-XepDisableWarningsInGeneratedCode'] + errorprone_flags.extend('-Xep:{}:OFF'.format(x) + for x in ERRORPRONE_WARNINGS_TO_DISABLE) + errorprone_flags.extend('-Xep:{}:WARN'.format(x) + for x in ERRORPRONE_WARNINGS_TO_ENABLE) + + if ERRORPRONE_CHECKS_TO_APPLY: + errorprone_flags += [ + '-XepPatchLocation:IN_PLACE', + '-XepPatchChecks:,' + ','.join(ERRORPRONE_CHECKS_TO_APPLY) + ] + + javac_args += ['-XDcompilePolicy=simple', ' '.join(errorprone_flags)] + + # This flag quits errorprone after checks and before code generation, since + # we do not need errorprone outputs, this speeds up errorprone by 4 seconds + # for chrome_java. + if not ERRORPRONE_CHECKS_TO_APPLY: + javac_args += ['-XDshould-stop.ifNoError=FLOW'] + + if options.java_version: + javac_args.extend([ + '-source', + options.java_version, + '-target', + options.java_version, + ]) + if options.java_version == '1.8': + # Android's boot jar doesn't contain all java 8 classes. + options.bootclasspath.append(build_utils.RT_JAR_PATH) + + # This effectively disables all annotation processors, even including + # annotation processors in service provider configuration files named + # META-INF/. See the following link for reference: + # https://docs.oracle.com/en/java/javase/11/tools/javac.html + javac_args.extend(['-proc:none']) + + if options.bootclasspath: + javac_args.extend(['-bootclasspath', ':'.join(options.bootclasspath)]) + + if options.processorpath: + javac_args.extend(['-processorpath', ':'.join(options.processorpath)]) + if options.processor_args: + for arg in options.processor_args: + javac_args.extend(['-A%s' % arg]) + + javac_args.extend(options.javac_arg) + + classpath_inputs = ( + options.bootclasspath + options.classpath + options.processorpath) + + depfile_deps = classpath_inputs + # Files that are already inputs in GN should go in input_paths. + input_paths = depfile_deps + options.java_srcjars + java_files + if options.header_jar: + input_paths.append(options.header_jar) + input_paths += [x[0] for x in options.additional_jar_files] + + output_paths = [options.jar_path] + if not options.enable_errorprone: + output_paths += [options.jar_path + '.info'] + + input_strings = javac_cmd + javac_args + options.classpath + java_files + [ + options.warnings_as_errors, options.jar_info_exclude_globs + ] + + # Use md5_check for |pass_changes| feature. + md5_check.CallAndWriteDepfileIfStale(lambda changes: _OnStaleMd5( + changes, options, javac_cmd, javac_args, java_files), + options, + depfile_deps=depfile_deps, + input_paths=input_paths, + input_strings=input_strings, + output_paths=output_paths, + pass_changes=True) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) |