| Index: build/android/gyp/dex.py
|
| diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py
|
| index 7d5257b9d39644f12e8ac8f36af52d7880919f28..59425d705955f8116f23fbceea332f933191cb6e 100755
|
| --- a/build/android/gyp/dex.py
|
| +++ b/build/android/gyp/dex.py
|
| @@ -56,6 +56,9 @@ def _ParseArgs(args):
|
| help='Exclude locals list from the dex file.')
|
| parser.add_option('--multi-dex', default=False, action='store_true',
|
| help='Create multiple dex files.')
|
| + parser.add_option('--incremental',
|
| + action='store_true',
|
| + help='Enable incremental builds when possible.')
|
| parser.add_option('--inputs', help='A list of additional input paths.')
|
| parser.add_option('--excluded-paths',
|
| help='A list of paths to exclude from the dex file.')
|
| @@ -85,21 +88,55 @@ def _ParseArgs(args):
|
| return options, paths
|
|
|
|
|
| -def _OnStaleMd5(options, dex_cmd, paths):
|
| - if options.multi_dex:
|
| - combined_main_dex_list = tempfile.NamedTemporaryFile(suffix='.txt')
|
| - combined_main_dex_list.write(
|
| - _CreateCombinedMainDexList(options.main_dex_list_paths))
|
| - combined_main_dex_list.flush()
|
| - dex_cmd.append('--main-dex-list=%s' % combined_main_dex_list.name)
|
| -
|
| - dex_cmd += paths
|
| -
|
| - build_utils.CheckOutput(dex_cmd, print_stderr=False)
|
| +def _AllSubpathsAreClassFiles(paths, changes):
|
| + for path in paths:
|
| + if any(not p.endswith('.class') for p in changes.IterChangedSubpaths(path)):
|
| + return False
|
| + return True
|
| +
|
| +
|
| +def _RunDx(changes, options, dex_cmd, paths):
|
| + with build_utils.TempDir() as classes_temp_dir:
|
| + # --multi-dex is incompatible with --incremental.
|
| + if options.multi_dex:
|
| + combined_main_dex_list = tempfile.NamedTemporaryFile(suffix='.txt')
|
| + combined_main_dex_list.write(
|
| + _CreateCombinedMainDexList(options.main_dex_list_paths))
|
| + combined_main_dex_list.flush()
|
| + dex_cmd.append('--main-dex-list=%s' % combined_main_dex_list.name)
|
| + else:
|
| + # Use --incremental when .class files are added or modified (never when
|
| + # removed).
|
| + # --incremental tells dx to merge all newly dex'ed .class files with
|
| + # what that already exist in the output dex file (existing classes are
|
| + # replaced).
|
| + if options.incremental and changes.AddedOrModifiedOnly():
|
| + changed_inputs = set(changes.IterChangedPaths())
|
| + changed_paths = [p for p in paths if p in changed_inputs]
|
| + if not changed_paths:
|
| + return
|
| + # When merging in other dex files, there's no easy way to know if
|
| + # classes were removed from them.
|
| + if _AllSubpathsAreClassFiles(changed_paths, changes):
|
| + dex_cmd.append('--incremental')
|
| + for path in changed_paths:
|
| + changed_subpaths = set(changes.IterChangedSubpaths(path))
|
| + # Not a fundamental restriction, but it's the case right now and it
|
| + # simplifies the logic to assume so.
|
| + assert changed_subpaths, 'All inputs should be zip files.'
|
| + build_utils.ExtractAll(path, path=classes_temp_dir,
|
| + predicate=lambda p: p in changed_subpaths)
|
| + paths = [classes_temp_dir]
|
| +
|
| + dex_cmd += paths
|
| + build_utils.CheckOutput(dex_cmd, print_stderr=False)
|
|
|
| if options.dex_path.endswith('.zip'):
|
| _RemoveUnwantedFilesFromZip(options.dex_path)
|
|
|
| +
|
| +def _OnStaleMd5(changes, options, dex_cmd, paths):
|
| + _RunDx(changes, options, dex_cmd, paths)
|
| build_utils.WriteJson(
|
| [os.path.relpath(p, options.output_directory) for p in paths],
|
| options.dex_path + '.inputs')
|
| @@ -143,12 +180,18 @@ def main(args):
|
| options.dex_path + '.inputs',
|
| ]
|
|
|
| + # An escape hatch to be able to check if incremental dexing is causing
|
| + # problems.
|
| + force = int(os.environ.get('DISABLE_INCREMENTAL_DX', 0))
|
| +
|
| build_utils.CallAndWriteDepfileIfStale(
|
| - lambda: _OnStaleMd5(options, dex_cmd, paths),
|
| + lambda changes: _OnStaleMd5(changes, options, dex_cmd, paths),
|
| options,
|
| input_paths=input_paths,
|
| input_strings=dex_cmd,
|
| - output_paths=output_paths)
|
| + output_paths=output_paths,
|
| + force=force,
|
| + pass_changes=True)
|
|
|
|
|
| if __name__ == '__main__':
|
|
|