1#!/usr/bin/env python 2# 3# Copyright 2014 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import argparse 8import os 9import sys 10import zipfile 11 12REPOSITORY_ROOT = os.path.abspath( 13 os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) 14 15# pylint: disable=wrong-import-position 16# pylint: disable=import-error 17sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp')) 18from util import build_utils 19import action_helpers # build_utils adds //build to sys.path. 20import zip_helpers 21# pylint: enable=import-error 22# pylint: enable=wrong-import-position 23 24JAVA_PACKAGE_PREFIX = 'org/chromium/' 25JNI_ZERO_PACKAGE_PREFIX = 'org/jni_zero/' 26 27 28def main(): 29 parser = argparse.ArgumentParser() 30 action_helpers.add_depfile_arg(parser) 31 parser.add_argument( 32 '--excluded-classes', 33 help='A list of .class file patterns to exclude from the jar.') 34 parser.add_argument( 35 '--src-search-dirs', 36 action='append', 37 help='A list of directories that should be searched' 38 ' for the source files.') 39 parser.add_argument( 40 '--src-files', action='append', help='A list of source files to jar.') 41 parser.add_argument( 42 '--src-jars', 43 action='append', 44 help='A list of source jars to include in addition to source files.') 45 parser.add_argument( 46 '--src-list-files', 47 action='append', 48 help='A list of files that contain a list of sources,' 49 ' e.g. a list of \'.sources\' files generated by GN.') 50 parser.add_argument('--jar-path', help='Jar output path.', required=True) 51 52 options = parser.parse_args() 53 54 options.src_jars = action_helpers.parse_gn_list(options.src_jars) 55 options.src_search_dirs = action_helpers.parse_gn_list( 56 options.src_search_dirs) 57 options.src_list_files = action_helpers.parse_gn_list(options.src_list_files) 58 options.src_files = action_helpers.parse_gn_list(options.src_files) 59 options.excluded_classes = action_helpers.parse_gn_list( 60 options.excluded_classes) 61 62 src_files = options.src_files 63 64 # Add files from --source_list_files 65 for src_list_file in options.src_list_files: 66 with open(src_list_file, 'r') as f: 67 src_files.extend(f.read().splitlines()) 68 69 # Preprocess source files by removing any prefix that comes before 70 # the Java package name. 71 for i, s in enumerate(src_files): 72 prefix_position = s.find(JAVA_PACKAGE_PREFIX) 73 if prefix_position == -1: 74 prefix_position = s.find(JNI_ZERO_PACKAGE_PREFIX) 75 if prefix_position != -1: 76 src_files[i] = s[prefix_position:] 77 78 excluded_classes = [ 79 f.replace('.class', '.java') for f in options.excluded_classes 80 ] 81 82 predicate = None 83 if excluded_classes: 84 predicate = lambda f: not build_utils.MatchesGlob(f, excluded_classes) 85 86 # Create a dictionary that maps every source directory 87 # to source files that it contains. 88 dir_to_files_map = {} 89 # Initialize the map. 90 for src_search_dir in options.src_search_dirs: 91 dir_to_files_map[src_search_dir] = [] 92 # Fill the map. 93 for src_file in src_files: 94 number_of_file_instances = 0 95 for src_search_dir in options.src_search_dirs: 96 target_path = os.path.join(src_search_dir, src_file) 97 if os.path.isfile(target_path): 98 number_of_file_instances += 1 99 if not predicate or predicate(src_file): 100 dir_to_files_map[src_search_dir].append(target_path) 101 if (number_of_file_instances > 1): 102 raise Exception('There is more than one instance of file %s in %s' % 103 (src_file, options.src_search_dirs)) 104 if (number_of_file_instances < 1): 105 raise Exception('Unable to find file %s in %s' % 106 (src_file, options.src_search_dirs)) 107 108 # Jar the sources from every source search directory. 109 with action_helpers.atomic_output(options.jar_path) as o, \ 110 zipfile.ZipFile(o, 'w', zipfile.ZIP_DEFLATED) as z: 111 for src_search_dir in options.src_search_dirs: 112 subpaths = dir_to_files_map[src_search_dir] 113 if subpaths: 114 zip_helpers.add_files_to_zip(subpaths, z, base_dir=src_search_dir) 115 else: 116 raise Exception( 117 'Directory %s does not contain any files and can be' 118 ' removed from the list of directories to search' % src_search_dir) 119 120 # Jar additional src jars 121 if options.src_jars: 122 zip_helpers.merge_zips(z, options.src_jars, compress=True) 123 124 if options.depfile: 125 deps = [] 126 for sources in dir_to_files_map.values(): 127 deps.extend(sources) 128 # Srcjar deps already captured in GN rules (no need to list them here). 129 action_helpers.write_depfile(options.depfile, options.jar_path, deps) 130 131 132if __name__ == '__main__': 133 sys.exit(main()) 134