#!/usr/bin/env python # # Copyright 2014 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import os import sys import zipfile REPOSITORY_ROOT = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) # pylint: disable=wrong-import-position # pylint: disable=import-error sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) from util import build_utils import action_helpers # build_utils adds //build to sys.path. import zip_helpers # pylint: enable=import-error # pylint: enable=wrong-import-position JAVA_PACKAGE_PREFIX = 'org/chromium/' JNI_ZERO_PACKAGE_PREFIX = 'org/jni_zero/' def main(): parser = argparse.ArgumentParser() action_helpers.add_depfile_arg(parser) parser.add_argument( '--excluded-classes', help='A list of .class file patterns to exclude from the jar.') parser.add_argument( '--src-search-dirs', action='append', help='A list of directories that should be searched' ' for the source files.') parser.add_argument( '--src-files', action='append', help='A list of source files to jar.') parser.add_argument( '--src-jars', action='append', help='A list of source jars to include in addition to source files.') parser.add_argument( '--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_argument('--jar-path', help='Jar output path.', required=True) options = parser.parse_args() options.src_jars = action_helpers.parse_gn_list(options.src_jars) options.src_search_dirs = action_helpers.parse_gn_list( options.src_search_dirs) options.src_list_files = action_helpers.parse_gn_list(options.src_list_files) options.src_files = action_helpers.parse_gn_list(options.src_files) options.excluded_classes = action_helpers.parse_gn_list( options.excluded_classes) src_files = options.src_files # Add files from --source_list_files for src_list_file in options.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: prefix_position = s.find(JNI_ZERO_PACKAGE_PREFIX) if prefix_position != -1: src_files[i] = s[prefix_position:] excluded_classes = [ f.replace('.class', '.java') for f in options.excluded_classes ] predicate = None if excluded_classes: predicate = lambda f: not build_utils.MatchesGlob(f, excluded_classes) # 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 options.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 options.src_search_dirs: target_path = os.path.join(src_search_dir, src_file) if os.path.isfile(target_path): number_of_file_instances += 1 if not predicate or predicate(src_file): dir_to_files_map[src_search_dir].append(target_path) if (number_of_file_instances > 1): raise Exception('There is more than one instance of file %s in %s' % (src_file, options.src_search_dirs)) if (number_of_file_instances < 1): raise Exception('Unable to find file %s in %s' % (src_file, options.src_search_dirs)) # Jar the sources from every source search directory. with action_helpers.atomic_output(options.jar_path) as o, \ zipfile.ZipFile(o, 'w', zipfile.ZIP_DEFLATED) as z: for src_search_dir in options.src_search_dirs: subpaths = dir_to_files_map[src_search_dir] if subpaths: zip_helpers.add_files_to_zip(subpaths, z, base_dir=src_search_dir) 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 options.src_jars: zip_helpers.merge_zips(z, options.src_jars, compress=True) if options.depfile: deps = [] for sources in dir_to_files_map.values(): deps.extend(sources) # Srcjar deps already captured in GN rules (no need to list them here). action_helpers.write_depfile(options.depfile, options.jar_path, deps) if __name__ == '__main__': sys.exit(main())