| Index: build/android/gyp/javac.py
|
| diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
|
| index eb17acc4106903cb26ff05b63dbe3e0d2c30c509..65b36a54dfe643ec783f050eb2c4e7ca775d41b0 100755
|
| --- a/build/android/gyp/javac.py
|
| +++ b/build/android/gyp/javac.py
|
| @@ -12,6 +12,7 @@ import sys
|
| import textwrap
|
|
|
| from util import build_utils
|
| +from util import md5_check
|
|
|
| import jar
|
|
|
| @@ -122,10 +123,47 @@ def _ExtractClassFiles(jar_path, dest_dir, java_files):
|
| def extract_predicate(path):
|
| if not path.endswith('.class'):
|
| return False
|
| - path_without_suffix = re.sub(r'(?:\$[^/]+)?\.class$', '', path)
|
| - return not any(path_without_suffix in p for p in java_files)
|
| + path_without_suffix = re.sub(r'(?:\$|\.)[^/]+class$', '', path)
|
| + partial_java_path = path_without_suffix + '.java'
|
| + return not any(p.endswith(partial_java_path) for p in java_files)
|
|
|
| build_utils.ExtractAll(jar_path, path=dest_dir, predicate=extract_predicate)
|
| + for path in build_utils.FindInDirectory(dest_dir, '*.class'):
|
| + shutil.copystat(jar_path, path)
|
| +
|
| +
|
| +def _ConvertToJMakeArgs(javac_cmd, pdb_path):
|
| + new_args = ['bin/jmake', '-pdb', pdb_path]
|
| + if javac_cmd[0] != 'javac':
|
| + new_args.extend(('-jcexec', new_args[0]))
|
| + if md5_check.PRINT_EXPLANATIONS:
|
| + new_args.append('-Xtiming')
|
| +
|
| + do_not_prefix = ('-classpath', '-bootclasspath')
|
| + skip_next = False
|
| + for arg in javac_cmd[1:]:
|
| + if not skip_next and arg not in do_not_prefix:
|
| + arg = '-C' + arg
|
| + new_args.append(arg)
|
| + skip_next = arg in do_not_prefix
|
| +
|
| + return new_args
|
| +
|
| +
|
| +def _FilterJMakeOutput(stdout):
|
| + if md5_check.PRINT_EXPLANATIONS:
|
| + return stdout
|
| + return re.sub(r'\b(Jmake version|Writing project database).*?\n', '', stdout)
|
| +
|
| +
|
| +def _FixTempPathsInIncrementalMetadata(pdb_path, temp_dir):
|
| + # The .pdb records absolute paths. Fix up paths within /tmp (srcjars).
|
| + if os.path.exists(pdb_path):
|
| + # Although its a binary file, search/replace still seems to work fine.
|
| + with open(pdb_path) as fileobj:
|
| + pdb_data = fileobj.read()
|
| + with open(pdb_path, 'w') as fileobj:
|
| + fileobj.write(re.sub(r'/tmp/[^/]*', temp_dir, pdb_data))
|
|
|
|
|
| def _OnStaleMd5(changes, options, javac_cmd, java_files, classpath_inputs,
|
| @@ -140,35 +178,58 @@ def _OnStaleMd5(changes, options, javac_cmd, java_files, classpath_inputs,
|
| os.makedirs(classes_dir)
|
|
|
| changed_paths = None
|
| + # jmake can handle deleted files, but it's a rare case and it would
|
| + # complicate this script's logic.
|
| if options.incremental and changes.AddedOrModifiedOnly():
|
| changed_paths = set(changes.IterChangedPaths())
|
| # Do a full compile if classpath has changed.
|
| + # jmake doesn't seem to do this on its own... Might be that ijars mess up
|
| + # its change-detection logic.
|
| if any(p in changed_paths for p in classpath_inputs):
|
| changed_paths = None
|
| - else:
|
| - java_files = [p for p in java_files if p in changed_paths]
|
| - srcjars = [p for p in srcjars if p in changed_paths]
|
| +
|
| + if options.incremental:
|
| + # jmake is a compiler wrapper that figures out the minimal set of .java
|
| + # files that need to be rebuilt given a set of .java files that have
|
| + # changed.
|
| + # jmake determines what files are stale based on timestamps between .java
|
| + # and .class files. Since we use .jars, .srcjars, and md5 checks,
|
| + # timestamp info isn't accurate for this purpose. Rather than use jmake's
|
| + # programatic interface (like we eventually should), we ensure that all
|
| + # .class files are newer than their .java files, and convey to jmake which
|
| + # sources are stale by having their .class files be missing entirely
|
| + # (by not extracting them).
|
| + pdb_path = options.jar_path + '.pdb'
|
| + javac_cmd = _ConvertToJMakeArgs(javac_cmd, pdb_path)
|
| + if srcjars:
|
| + _FixTempPathsInIncrementalMetadata(pdb_path, temp_dir)
|
|
|
| if srcjars:
|
| java_dir = os.path.join(temp_dir, 'java')
|
| os.makedirs(java_dir)
|
| for srcjar in options.java_srcjars:
|
| - extract_predicate = None
|
| if changed_paths:
|
| - changed_subpaths = set(changes.IterChangedSubpaths(srcjar))
|
| - extract_predicate = lambda p: p in changed_subpaths
|
| - build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java',
|
| - predicate=extract_predicate)
|
| + changed_paths.update(changes.IterChangedSubpaths(srcjar))
|
| + build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
|
| jar_srcs = build_utils.FindInDirectory(java_dir, '*.java')
|
| - java_files.extend(_FilterJavaFiles(jar_srcs, options.javac_includes))
|
| + jar_srcs = _FilterJavaFiles(jar_srcs, options.javac_includes)
|
| + java_files.extend(jar_srcs)
|
| + if changed_paths:
|
| + # Set the mtime of all sources to 0 since we use the absense of .class
|
| + # files to tell jmake which files are stale.
|
| + for path in jar_srcs:
|
| + os.utime(path, (0, 0))
|
|
|
| if java_files:
|
| if changed_paths:
|
| - # When no files have been removed and the output jar already
|
| - # exists, reuse .class files from the existing jar.
|
| - _ExtractClassFiles(options.jar_path, classes_dir, java_files)
|
| - _ExtractClassFiles(excluded_jar_path, classes_dir, java_files)
|
| - # Add the extracted files to the classpath.
|
| + changed_java_files = [p for p in java_files if p in changed_paths]
|
| + if os.path.exists(options.jar_path):
|
| + _ExtractClassFiles(options.jar_path, classes_dir, changed_java_files)
|
| + if os.path.exists(excluded_jar_path):
|
| + _ExtractClassFiles(excluded_jar_path, classes_dir, changed_java_files)
|
| + # Add the extracted files to the classpath. This is required because
|
| + # when compiling only a subset of files, classes that haven't changed
|
| + # need to be findable.
|
| classpath_idx = javac_cmd.index('-classpath')
|
| javac_cmd[classpath_idx + 1] += ':' + classes_dir
|
|
|
| @@ -179,6 +240,7 @@ def _OnStaleMd5(changes, options, javac_cmd, java_files, classpath_inputs,
|
| build_utils.CheckOutput(
|
| cmd,
|
| print_stdout=options.chromium_code,
|
| + stdout_filter=_FilterJMakeOutput,
|
| stderr_filter=ColorJavacOutput)
|
|
|
| if options.main_class or options.manifest_entry:
|
| @@ -360,6 +422,8 @@ def main(argv):
|
| options.jar_path,
|
| options.jar_path.replace('.jar', '.excluded.jar'),
|
| ]
|
| + if options.incremental:
|
| + output_paths.append(options.jar_path + '.pdb')
|
|
|
| # An escape hatch to be able to check if incremental compiles are causing
|
| # problems.
|
|
|