Chromium Code Reviews| Index: build/android/gyp/javac.py |
| diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py |
| index deb90c5de64e03fb28c562146625da3865833df7..5632db19cda042bb74e4ad3dc51c69ac46ac707d 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,49 @@ 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): |
| + compiler = javac_cmd[0] |
| + new_args = ['-C' + arg for arg in javac_cmd] |
|
Yaron
2015/09/30 02:19:25
I feel like these lines would be a little clearer
agrieve
2015/10/01 16:26:11
Done.
|
| + if compiler != 'javac': |
| + new_args.extend(('-jcexec', new_args[0])) |
| + new_args[0] = 'bin/jmake' |
| + new_args.extend(('-pdb', pdb_path)) |
| + if md5_check.PRINT_EXPLANATIONS: |
| + new_args.append('-Xtiming') |
| + |
| + def revert_arg(index): |
| + new_args[index] = javac_cmd[index] |
| + new_args[index + 1] = javac_cmd[index + 1] |
| + |
| + # Unprefix classpath args. |
|
Yaron
2015/09/30 02:19:25
Yuck :(
agrieve
2015/10/01 16:26:11
Done.
|
| + revert_arg(javac_cmd.index('-classpath')) |
| + if '-bootclasspath' in javac_cmd: |
| + revert_arg(javac_cmd.index('-bootclasspath')) |
| + 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 witin /tmp (srcjars). |
|
Yaron
2015/09/30 02:19:25
within
agrieve
2015/10/01 16:26:11
Done.
agrieve
2015/10/01 16:26:11
Done.
|
| + if os.path.exists(pdb_path): |
| + with open(pdb_path) as fileobj: |
|
Yaron
2015/09/30 02:19:25
use fileinput.input: http://stackoverflow.com/ques
agrieve
2015/10/01 16:26:11
It's a binary file. Added a comment.
|
| + 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 +180,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. |
|
Yaron
2015/09/30 02:19:25
how does this impact non-incremental builds which
agrieve
2015/10/01 16:26:11
It won't be hit since changed_paths == None for no
|
| + 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 +242,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: |
| @@ -361,6 +425,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. |