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
This commit is contained in:
cjhopman@chromium.org 2013-04-01 23:12:33 +00:00
Родитель dea2e4d49c
Коммит d13f9eb51a
5 изменённых файлов: 239 добавлений и 12 удалений

Просмотреть файл

@ -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))

52
android/gcc_preprocess.py Executable file
Просмотреть файл

@ -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))

Просмотреть файл

@ -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)',
}

Просмотреть файл

@ -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))

Просмотреть файл

@ -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)',