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