From d13f9eb51ad1426f93648d3ef805d8eb22255364 Mon Sep 17 00:00:00 2001 From: "cjhopman@chromium.org" Date: Mon, 1 Apr 2013 23:12:33 +0000 Subject: [PATCH] Make the build control what library(/ies) to load At build time, we know what native libraries an apk needs to load. Instead of requiring those .apks to specify this again in code, instead generate a .java file containing a list of the libraries to load. This is done using a pattern similar to resources, content_java is built with a placeholder NativeLibraries.java (i.e. without an actual value for its libraries list). The corresponding .class file is not included in content_java.jar. Then, when building an apk we generate the "real" NativeLibraries.java (with the real String[]) and include that in the .apk. This is designed to also support the component build, where, we will have to calculate the list of libraries at build time, and sort them in dependency order (because Android's linker, for some reason, doesn't do that itself). BUG=158821 TBR=brettw@chromium.org Review URL: https://chromiumcodereview.appspot.com/12939021 git-svn-id: http://src.chromium.org/svn/trunk/src/build@191695 4ff67af0-8c30-449e-8e8b-ad334ec8d88c --- android/create_native_libraries_header.py | 52 ++++++++++++++++ android/gcc_preprocess.py | 52 ++++++++++++++++ android/java_cpp_template.gypi | 28 +++++---- android/write_ordered_libraries.py | 43 +++++++++++++ java_apk.gypi | 76 +++++++++++++++++++++++ 5 files changed, 239 insertions(+), 12 deletions(-) create mode 100755 android/create_native_libraries_header.py create mode 100755 android/gcc_preprocess.py create mode 100755 android/write_ordered_libraries.py diff --git a/android/create_native_libraries_header.py b/android/create_native_libraries_header.py new file mode 100755 index 000000000..34fea30dc --- /dev/null +++ b/android/create_native_libraries_header.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Copyright 2013 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. + +"""Writes .h file for NativeLibraries.template + +This header should contain the list of native libraries to load in the form: + = { "lib1", "lib2" } +""" + +import json +import optparse +import os +import sys + +from pylib import build_utils + + +def main(argv): + parser = optparse.OptionParser() + + parser.add_option('--output', help='Path to generated .java file') + parser.add_option('--ordered-libraries', + help='Path to json file containing list of ordered libraries') + parser.add_option('--stamp', help='Path to touch on success') + + # args should be the list of libraries in dependency order. + options, _ = parser.parse_args() + + build_utils.MakeDirectory(os.path.dirname(options.output)) + + with open(options.ordered_libraries, 'r') as libfile: + libraries = json.load(libfile) + # Generates string of the form '= { "base", "net", + # "content_shell_content_view" }' from a list of the form ["libbase.so", + # libnet.so", "libcontent_shell_content_view.so"] + libraries = ['"' + lib[3:-3] + '"' for lib in libraries] + array = '= { ' + ', '.join(libraries) + '}'; + + with open(options.output, 'w') as header: + header.write(array) + + if options.stamp: + build_utils.Touch(options.stamp) + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + + diff --git a/android/gcc_preprocess.py b/android/gcc_preprocess.py new file mode 100755 index 000000000..8839b1770 --- /dev/null +++ b/android/gcc_preprocess.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Copyright 2013 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 subprocess +import sys + +from pylib import build_utils + +def DoGcc(options): + build_utils.MakeDirectory(os.path.dirname(options.output)) + + gcc_cmd = [ + 'gcc', # invoke host gcc. + '-E', # stop after preprocessing. + '-D', 'ANDROID', # Specify ANDROID define for pre-processor. + '-x', 'c-header', # treat sources as C header files + '-P', # disable line markers, i.e. '#line 309' + '-I', options.include_path, + '-o', options.output, + options.template + ] + + build_utils.CheckCallDie(gcc_cmd) + + +def main(argv): + parser = optparse.OptionParser() + parser.add_option('--include-path', help='Include path for gcc.') + parser.add_option('--template', help='Path to template.') + parser.add_option('--output', help='Path for generated file.') + parser.add_option('--stamp', help='Path to touch on success.') + + # TODO(newt): remove this once http://crbug.com/177552 is fixed in ninja. + parser.add_option('--ignore', help='Ignored.') + + options, _ = parser.parse_args() + + DoGcc(options) + + if options.stamp: + build_utils.Touch(options.stamp) + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + + diff --git a/android/java_cpp_template.gypi b/android/java_cpp_template.gypi index c55b1002f..2b254700a 100644 --- a/android/java_cpp_template.gypi +++ b/android/java_cpp_template.gypi @@ -17,7 +17,7 @@ # 'package_name': 'org/chromium/net', # 'template_deps': ['net/base/certificate_mime_type_list.h'], # }, -# 'includes': [ '../build/android/java_constants.gypi' ], +# 'includes': [ '../build/android/java_cpp_template.gypi' ], # }, # # The 'sources' entry should only list template file. The template file @@ -31,7 +31,8 @@ { # Location where all generated Java sources will be placed. 'variables': { - 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/templates/<(package_name)' + 'include_path%': '<(DEPTH)', + 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/templates/<(package_name)', }, # Ensure that the output directory is used in the class path # when building targets that depend on this one. @@ -49,19 +50,22 @@ 'rule_name': 'generate_java_constants', 'extension': 'template', # Set template_deps as additional dependencies. - 'inputs': ['<@(template_deps)'], + 'variables': { + 'output_path': '<(output_dir)/<(RULE_INPUT_ROOT).java', + }, + 'inputs': [ + '<(DEPTH)/build/android/pylib/build_utils.py', + '<(DEPTH)/build/android/gcc_preprocess.py', + '<@(template_deps)' + ], 'outputs': [ - '<(output_dir)/<(RULE_INPUT_ROOT).java' + '<(output_path)', ], 'action': [ - 'gcc', # invoke host gcc. - '-E', # stop after preprocessing. - '-D', 'ANDROID', # Specify ANDROID define for pre-processor. - '-x', 'c-header', # treat sources as C header files - '-P', # disable line markers, i.e. '#line 309' - '-I', '<(DEPTH)', # Add project top-level to include path - '-o', '<@(_outputs)', # Specify output file - '<(RULE_INPUT_PATH)', # Specify input file + 'python', '<(DEPTH)/build/android/gcc_preprocess.py', + '--include-path=<(include_path)', + '--output=<(output_path)', + '--template=<(RULE_INPUT_PATH)', ], 'message': 'Generating Java from cpp template <(RULE_INPUT_PATH)', } diff --git a/android/write_ordered_libraries.py b/android/write_ordered_libraries.py new file mode 100755 index 000000000..e887672e2 --- /dev/null +++ b/android/write_ordered_libraries.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# +# Copyright 2013 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. + +"""Writes dependency ordered list of native libraries. + +This list of libraries is used for several steps of building an APK. +""" + +import json +import optparse +import os +import sys + +from pylib import build_utils + + +def main(argv): + parser = optparse.OptionParser() + + parser.add_option('--input-libraries', + help='A list of top-level input libraries') + parser.add_option('--output', help='Path to the generated .json file') + parser.add_option('--stamp', help='Path to touch on success') + + options, _ = parser.parse_args() + + libraries = build_utils.ParseGypList(options.input_libraries) + libraries = [os.path.basename(lib) for lib in libraries] + + with open(options.output, 'w') as outfile: + json.dump(libraries, outfile) + + if options.stamp: + build_utils.Touch(options.stamp) + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + + diff --git a/java_apk.gypi b/java_apk.gypi index f3ac97543..8d57be8ba 100644 --- a/java_apk.gypi +++ b/java_apk.gypi @@ -73,6 +73,18 @@ 'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)', 'asset_location%': '<(intermediate_dir)/assets', 'codegen_stamp': '<(intermediate_dir)/codegen.stamp', + 'compile_input_paths': [ ], + 'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json', + # TODO(cjhopman): build/ shouldn't refer to content/. The libraryloader and + # nativelibraries template should be moved out of content/ (to base/?). + # http://crbug.com/225101 + 'native_libraries_template': '<(DEPTH)/content/public/android/java/templates/NativeLibraries.template', + 'native_libraries_java_dir': '<(intermediate_dir)/native_libraries_java/', + 'native_libraries_java_file': '<(native_libraries_java_dir)/NativeLibraries.java', + 'native_libraries_java_stamp': '<(intermediate_dir)/native_libraries_java.stamp', + 'native_libraries_template_data_dir': '<(intermediate_dir)/native_libraries/', + 'native_libraries_template_data_file': '<(native_libraries_template_data_dir)/native_libraries_array.h', + 'native_libraries_template_data_stamp': '<(intermediate_dir)/native_libraries_template_data.stamp', 'compile_stamp': '<(intermediate_dir)/compile.stamp', 'jar_stamp': '<(intermediate_dir)/jar.stamp', 'obfuscate_stamp': '<(intermediate_dir)/obfuscate.stamp', @@ -134,6 +146,69 @@ 'additional_R_text_files': ['<(PRODUCT_DIR)/<(package_name)/R.txt'], }, }], + ['native_libs_paths != []', { + 'variables': { + 'compile_input_paths': [ '<(native_libraries_java_stamp)' ], + 'generated_src_dirs': [ '<(native_libraries_java_dir)' ], + }, + 'actions': [ + { + 'action_name': 'ordered_libraries_<(_target_name)', + 'message': 'Writing dependency ordered libraries for <(_target_name).', + 'inputs': [ + '<(DEPTH)/build/android/pylib/build_utils.py', + '<(DEPTH)/build/android/write_ordered_libraries.py', + '<@(native_libs_paths)', + ], + 'outputs': [ + '<(ordered_libraries_file)', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/write_ordered_libraries.py', + '--input-libraries=<(native_libs_paths)', + '--output=<(ordered_libraries_file)', + ], + }, + { + 'action_name': 'native_libraries_template_data_<(_target_name)', + 'message': 'Creating native_libraries_list.h for <(_target_name).', + 'inputs': [ + '<(DEPTH)/build/android/pylib/build_utils.py', + '<(DEPTH)/build/android/create_native_libraries_header.py', + '<(ordered_libraries_file)', + ], + 'outputs': [ + '<(native_libraries_template_data_stamp)', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/create_native_libraries_header.py', + '--ordered-libraries=<(ordered_libraries_file)', + '--output=<(native_libraries_template_data_file)', + '--stamp=<(native_libraries_template_data_stamp)', + ], + }, + { + 'action_name': 'native_libraries_<(_target_name)', + 'message': 'Creating NativeLibraries.java for <(_target_name).', + 'inputs': [ + '<(DEPTH)/build/android/pylib/build_utils.py', + '<(DEPTH)/build/android/gcc_preprocess.py', + '<(native_libraries_template_data_stamp)', + '<(native_libraries_template)', + ], + 'outputs': [ + '<(native_libraries_java_stamp)', + ], + 'action': [ + 'python', '<(DEPTH)/build/android/gcc_preprocess.py', + '--include-path=<(native_libraries_template_data_dir)', + '--output=<(native_libraries_java_file)', + '--template=<(native_libraries_template)', + '--stamp=<(native_libraries_java_stamp)', + ], + }, + ], + }], # native_libs_paths != [] ['java_strings_grd != ""', { 'variables': { 'res_grit_dir': '<(SHARED_INTERMEDIATE_DIR)/<(package_name)_apk/res_grit', @@ -223,6 +298,7 @@ '>!@(find >(java_in_dir) >(additional_src_dirs) -name "*.java")', '>@(input_jars_paths)', '<(codegen_stamp)', + '>@(compile_input_paths)', ], 'outputs': [ '<(compile_stamp)',