| #!/usr/bin/env python |
| # |
| # Copyright 2014 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 optparse |
| import os |
| import sys |
| import tempfile |
| |
| REPOSITORY_ROOT = os.path.abspath(os.path.join( |
| os.path.dirname(__file__), '..', '..', '..')) |
| |
| sys.path.append(os.path.join(REPOSITORY_ROOT, 'build/android/gyp/util')) |
| import build_utils |
| |
| JAVA_PACKAGE_PREFIX = 'org/chromium/' |
| |
| def JarSources(src_dir, src_files, jar_path): |
| # The paths of the files in the jar will be the same as they are passed in to |
| # the command. Because of this, the command should be run in |
| # options.src_dir so the .java file paths in the jar are correct. |
| jar_cwd = src_dir |
| jar_path = os.path.abspath(jar_path) |
| if os.path.exists(jar_path): |
| jar_cmd = ['jar', 'uf', jar_path] |
| else: |
| jar_cmd = ['jar', 'cf', jar_path] |
| |
| jar_cmd.extend(src_files) |
| build_utils.CheckOutput(jar_cmd, cwd=jar_cwd) |
| |
| # Uncompress source jars so that they can be combined with other sources |
| def UnzipSourceJar(jar, unzipped_jar_path): |
| if os.path.exists(jar): |
| jar_cmd = ['jar', 'xf', os.path.abspath(jar)] |
| build_utils.CheckOutput(jar_cmd, cwd=unzipped_jar_path) |
| else: |
| raise Exception('Jar file does not exist %s' % jar) |
| |
| |
| def main(): |
| parser = optparse.OptionParser() |
| build_utils.AddDepfileOption(parser) |
| parser.add_option('--src-search-dirs', action="append", |
| help='A list of directories that should be searched' |
| ' for the source files.') |
| parser.add_option('--src-files', action="append", |
| help='A list of source files to jar.') |
| parser.add_option('--src-jars', action="append", |
| help='A list of source jars to include in addition to source files.') |
| parser.add_option('--src-list-files', action="append", |
| help='A list of files that contain a list of sources,' |
| ' e.g. a list of \'.sources\' files generated by GN.') |
| parser.add_option('--jar-path', help='Jar output path.') |
| parser.add_option('--stamp', help='Path to touch on success.') |
| |
| options, _ = parser.parse_args() |
| |
| # A temporary directory to put the output of jar files. |
| unzipped_jar_path = None |
| if options.src_jars: |
| unzipped_jar_path = tempfile.mkdtemp(dir=os.path.dirname(options.jar_path)) |
| jar_list = [] |
| for gn_list in options.src_jars: |
| jar_list.extend(build_utils.ParseGnList(gn_list)) |
| |
| for jar in jar_list: |
| UnzipSourceJar(jar, unzipped_jar_path) |
| |
| src_search_dirs = [] |
| for gn_src_search_dirs in options.src_search_dirs: |
| src_search_dirs.extend(build_utils.ParseGnList(gn_src_search_dirs)) |
| |
| src_list_files = [] |
| if options.src_list_files: |
| for gn_src_list_file in options.src_list_files: |
| src_list_files.extend(build_utils.ParseGnList(gn_src_list_file)) |
| |
| src_files = [] |
| for gn_src_files in options.src_files: |
| src_files.extend(build_utils.ParseGnList(gn_src_files)) |
| |
| # Add files from --source_list_files |
| for src_list_file in src_list_files: |
| with open(src_list_file, 'r') as f: |
| src_files.extend(f.read().splitlines()) |
| |
| # Preprocess source files by removing any prefix that comes before |
| # the Java package name. |
| for i, s in enumerate(src_files): |
| prefix_position = s.find(JAVA_PACKAGE_PREFIX) |
| if prefix_position != -1: |
| src_files[i] = s[prefix_position:] |
| |
| # Create a dictionary that maps every source directory |
| # to source files that it contains. |
| dir_to_files_map = {} |
| # Initialize the map. |
| for src_search_dir in src_search_dirs: |
| dir_to_files_map[src_search_dir] = [] |
| # Fill the map. |
| for src_file in src_files: |
| number_of_file_instances = 0 |
| for src_search_dir in src_search_dirs: |
| if os.path.isfile(os.path.join(src_search_dir, src_file)): |
| number_of_file_instances += 1 |
| dir_to_files_map[src_search_dir].append(src_file) |
| if (number_of_file_instances > 1): |
| raise Exception( |
| 'There is more than one instance of file %s in %s' |
| % (src_file, src_search_dirs)) |
| if (number_of_file_instances < 1): |
| raise Exception( |
| 'Unable to find file %s in %s' % (src_file, src_search_dirs)) |
| |
| # Delete the old output file if any. |
| if os.path.isfile(options.jar_path): |
| os.remove(options.jar_path) |
| |
| # Jar the sources from every source search directory. |
| for src_search_dir in src_search_dirs: |
| if len(dir_to_files_map[src_search_dir]) > 0: |
| JarSources(src_search_dir, dir_to_files_map[src_search_dir], |
| options.jar_path) |
| else: |
| raise Exception( |
| 'Directory %s does not contain any files and can be' |
| ' removed from the list of directories to search' % src_search_dir) |
| |
| # Jar additional src jars |
| if unzipped_jar_path: |
| JarSources(unzipped_jar_path, ['.'], options.jar_path) |
| |
| if options.depfile: |
| deps = [] |
| for src_dir in src_search_dirs: |
| for root, _, filenames in os.walk(src_dir): |
| deps.extend(os.path.join(root, f) for f in filenames) |
| # Srcjar deps already captured in GN rules (no need to list them here). |
| build_utils.WriteDepfile(options.depfile, options.jar_path, deps) |
| |
| # Clean up temporary output directory. |
| if unzipped_jar_path: |
| build_utils.DeleteDirectory(unzipped_jar_path) |
| |
| if options.stamp: |
| build_utils.Touch(options.stamp) |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |
| |