Turn Chrome Shell's AndroidManifest into a jinja2 template.
This turns Chrome Shell's AndroidManifest.xml into a template which gets processed at build time to produce the final AndroidManifest.xml that's used to build the APK. BUG=163751 NOTRY=true Review URL: https://codereview.chromium.org/657443002 Cr-Original-Commit-Position: refs/heads/master@{#300409} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: d5366cb1ad27e6bf1ae659f374a9b9dd3186761d
This commit is contained in:
Родитель
995134623c
Коммит
4d9ecaf9dd
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2014 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.
|
||||||
|
|
||||||
|
"""Renders one or more template files using the Jinja template engine."""
|
||||||
|
|
||||||
|
import optparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from util import build_utils
|
||||||
|
|
||||||
|
# Import jinja2 from third_party/jinja2
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../third_party'))
|
||||||
|
import jinja2 # pylint: disable=F0401
|
||||||
|
|
||||||
|
|
||||||
|
def ProcessFile(input_filename, output_filename, variables):
|
||||||
|
with open(input_filename, 'r') as input_file:
|
||||||
|
input_ = input_file.read()
|
||||||
|
env = jinja2.Environment(undefined=jinja2.StrictUndefined)
|
||||||
|
template = env.from_string(input_)
|
||||||
|
template.filename = os.path.abspath(input_filename)
|
||||||
|
output = template.render(variables)
|
||||||
|
with open(output_filename, 'w') as output_file:
|
||||||
|
output_file.write(output)
|
||||||
|
|
||||||
|
|
||||||
|
def ProcessFiles(input_filenames, inputs_base_dir, outputs_zip, variables):
|
||||||
|
with build_utils.TempDir() as temp_dir:
|
||||||
|
for input_filename in input_filenames:
|
||||||
|
relpath = os.path.relpath(os.path.abspath(input_filename),
|
||||||
|
os.path.abspath(inputs_base_dir))
|
||||||
|
if relpath.startswith(os.pardir):
|
||||||
|
raise Exception('input file %s is not contained in inputs base dir %s'
|
||||||
|
% input_filename, inputs_base_dir)
|
||||||
|
|
||||||
|
output_filename = os.path.join(temp_dir, relpath)
|
||||||
|
parent_dir = os.path.dirname(output_filename)
|
||||||
|
build_utils.MakeDirectory(parent_dir)
|
||||||
|
ProcessFile(input_filename, output_filename, variables)
|
||||||
|
|
||||||
|
build_utils.ZipDir(outputs_zip, temp_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
build_utils.AddDepfileOption(parser)
|
||||||
|
parser.add_option('--inputs', help='The template files to process.')
|
||||||
|
parser.add_option('--output', help='The output file to generate. Valid '
|
||||||
|
'only if there is a single input.')
|
||||||
|
parser.add_option('--outputs-zip', help='A zip file containing the processed '
|
||||||
|
'templates. Required if there are multiple inputs.')
|
||||||
|
parser.add_option('--inputs-base-dir', help='A common ancestor directory of '
|
||||||
|
'the inputs. Each output\'s path in the output zip will '
|
||||||
|
'match the relative path from INPUTS_BASE_DIR to the '
|
||||||
|
'input. Required if --output-zip is given.')
|
||||||
|
parser.add_option('--variables', help='Variables to be made available in the '
|
||||||
|
'template processing environment, as a GYP list (e.g. '
|
||||||
|
'--variables "channel=beta mstone=39")', default='')
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
build_utils.CheckOptions(options, parser, required=['inputs'])
|
||||||
|
inputs = build_utils.ParseGypList(options.inputs)
|
||||||
|
|
||||||
|
if (options.output is None) == (options.outputs_zip is None):
|
||||||
|
parser.error('Exactly one of --output and --output-zip must be given')
|
||||||
|
if options.output and len(inputs) != 1:
|
||||||
|
parser.error('--output cannot be used with multiple inputs')
|
||||||
|
if options.outputs_zip and not options.inputs_base_dir:
|
||||||
|
parser.error('--inputs-base-dir must be given when --output-zip is used')
|
||||||
|
if args:
|
||||||
|
parser.error('No positional arguments should be given.')
|
||||||
|
|
||||||
|
variables = {}
|
||||||
|
for v in build_utils.ParseGypList(options.variables):
|
||||||
|
if '=' not in v:
|
||||||
|
parser.error('--variables argument must contain "=": ' + v)
|
||||||
|
name, _, value = v.partition('=')
|
||||||
|
variables[name] = value
|
||||||
|
|
||||||
|
if options.output:
|
||||||
|
ProcessFile(inputs[0], options.output, variables)
|
||||||
|
else:
|
||||||
|
ProcessFiles(inputs, options.inputs_base_dir, options.outputs_zip,
|
||||||
|
variables)
|
||||||
|
|
||||||
|
if options.depfile:
|
||||||
|
deps = inputs + build_utils.GetPythonDependencies()
|
||||||
|
build_utils.WriteDepfile(options.depfile, deps)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,83 @@
|
||||||
|
# Copyright 2014 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.
|
||||||
|
|
||||||
|
# This file is meant to be included into a target to process one or more
|
||||||
|
# Jinja templates.
|
||||||
|
#
|
||||||
|
# To process a single template file, create a gyp target with the following
|
||||||
|
# form:
|
||||||
|
# {
|
||||||
|
# 'target_name': 'chrome_shell_manifest',
|
||||||
|
# 'type': 'none',
|
||||||
|
# 'variables': {
|
||||||
|
# 'jinja_inputs': ['android/shell/java/AndroidManifest.xml'],
|
||||||
|
# 'jinja_output': '<(SHARED_INTERMEDIATE_DIR)/chrome_shell_manifest/AndroidManifest.xml',
|
||||||
|
# 'jinja_variables': ['app_name=ChromeShell'],
|
||||||
|
# },
|
||||||
|
# 'includes': [ '../build/android/jinja_template.gypi' ],
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
# To process multiple template files and package the results into a zip file,
|
||||||
|
# create a gyp target with the following form:
|
||||||
|
# {
|
||||||
|
# 'target_name': 'chrome_template_resources',
|
||||||
|
# 'type': 'none',
|
||||||
|
# 'variables': {
|
||||||
|
# 'jinja_inputs_base_dir': 'android/shell/java/res_template',
|
||||||
|
# 'jinja_inputs': [
|
||||||
|
# '<(jinja_inputs_base_dir)/xml/searchable.xml',
|
||||||
|
# '<(jinja_inputs_base_dir)/xml/syncadapter.xml',
|
||||||
|
# ],
|
||||||
|
# 'jinja_outputs_zip': '<(PRODUCT_DIR)/res.java/<(_target_name).zip',
|
||||||
|
# 'jinja_variables': ['app_name=ChromeShell'],
|
||||||
|
# },
|
||||||
|
# 'includes': [ '../build/android/jinja_template.gypi' ],
|
||||||
|
# },
|
||||||
|
#
|
||||||
|
|
||||||
|
{
|
||||||
|
'actions': [
|
||||||
|
{
|
||||||
|
'action_name': '<(_target_name)_jinja_template',
|
||||||
|
'message': 'processing jinja template',
|
||||||
|
'variables': {
|
||||||
|
'jinja_output%': '',
|
||||||
|
'jinja_outputs_zip%': '',
|
||||||
|
'jinja_inputs_base_dir%': '',
|
||||||
|
'jinja_variables%': [],
|
||||||
|
'jinja_args': [],
|
||||||
|
},
|
||||||
|
'inputs': [
|
||||||
|
'<(DEPTH)/build/android/gyp/util/build_utils.py',
|
||||||
|
'<(DEPTH)/build/android/gyp/jinja_template.py',
|
||||||
|
'<@(jinja_inputs)',
|
||||||
|
],
|
||||||
|
'conditions': [
|
||||||
|
['jinja_output != ""', {
|
||||||
|
'outputs': [ '<(jinja_output)' ],
|
||||||
|
'variables': {
|
||||||
|
'jinja_args': ['--output', '<(jinja_output)'],
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
['jinja_outputs_zip != ""', {
|
||||||
|
'outputs': [ '<(jinja_outputs_zip)' ],
|
||||||
|
'variables': {
|
||||||
|
'jinja_args': ['--outputs-zip', '<(jinja_outputs_zip)'],
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
['jinja_inputs_base_dir != ""', {
|
||||||
|
'variables': {
|
||||||
|
'jinja_args': ['--inputs-base-dir', '<(jinja_inputs_base_dir)'],
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
'action': [
|
||||||
|
'python', '<(DEPTH)/build/android/gyp/jinja_template.py',
|
||||||
|
'--inputs', '<(jinja_inputs)',
|
||||||
|
'--variables', '<(jinja_variables)',
|
||||||
|
'<@(jinja_args)',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -147,6 +147,10 @@
|
||||||
|
|
||||||
'target_subarch%': '',
|
'target_subarch%': '',
|
||||||
|
|
||||||
|
# The channel to build on Android: stable, beta, dev, canary, or
|
||||||
|
# default. "default" should be used on non-official builds.
|
||||||
|
'android_channel%': 'default',
|
||||||
|
|
||||||
# This is set when building the Android WebView inside the Android
|
# This is set when building the Android WebView inside the Android
|
||||||
# build system, using the 'android' gyp backend. The WebView code is
|
# build system, using the 'android' gyp backend. The WebView code is
|
||||||
# still built when this is unset, but builds using the normal chromium
|
# still built when this is unset, but builds using the normal chromium
|
||||||
|
@ -285,6 +289,7 @@
|
||||||
'use_openssl_certs%': '<(use_openssl_certs)',
|
'use_openssl_certs%': '<(use_openssl_certs)',
|
||||||
'enable_viewport%': '<(enable_viewport)',
|
'enable_viewport%': '<(enable_viewport)',
|
||||||
'enable_hidpi%': '<(enable_hidpi)',
|
'enable_hidpi%': '<(enable_hidpi)',
|
||||||
|
'android_channel%': '<(android_channel)',
|
||||||
'android_webview_build%': '<(android_webview_build)',
|
'android_webview_build%': '<(android_webview_build)',
|
||||||
'android_webview_telemetry_build%': '<(android_webview_telemetry_build)',
|
'android_webview_telemetry_build%': '<(android_webview_telemetry_build)',
|
||||||
'use_goma%': '<(use_goma)',
|
'use_goma%': '<(use_goma)',
|
||||||
|
@ -1155,6 +1160,7 @@
|
||||||
'wix_path%': '<(wix_path)',
|
'wix_path%': '<(wix_path)',
|
||||||
'use_libjpeg_turbo%': '<(use_libjpeg_turbo)',
|
'use_libjpeg_turbo%': '<(use_libjpeg_turbo)',
|
||||||
'use_system_libjpeg%': '<(use_system_libjpeg)',
|
'use_system_libjpeg%': '<(use_system_libjpeg)',
|
||||||
|
'android_channel%': '<(android_channel)',
|
||||||
'android_webview_build%': '<(android_webview_build)',
|
'android_webview_build%': '<(android_webview_build)',
|
||||||
'android_webview_telemetry_build%': '<(android_webview_telemetry_build)',
|
'android_webview_telemetry_build%': '<(android_webview_telemetry_build)',
|
||||||
'icu_use_data_file_flag%': '<(icu_use_data_file_flag)',
|
'icu_use_data_file_flag%': '<(icu_use_data_file_flag)',
|
||||||
|
|
|
@ -343,6 +343,112 @@ template("java_cpp_enum") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Declare a target for processing a Jinja template.
|
||||||
|
#
|
||||||
|
# Variables
|
||||||
|
# input: The template file to be processed.
|
||||||
|
# output: Where to save the result.
|
||||||
|
# variables: (Optional) A list of variables to make available to the template
|
||||||
|
# processing environment, e.g. ["name=foo", "color=red"].
|
||||||
|
#
|
||||||
|
# Example
|
||||||
|
# jinja_template("chrome_shell_manifest") {
|
||||||
|
# input = "shell/java/AndroidManifest.xml"
|
||||||
|
# output = "$target_gen_dir/AndroidManifest.xml"
|
||||||
|
# }
|
||||||
|
template("jinja_template") {
|
||||||
|
if (defined(invoker.testonly)) { testonly = invoker.testonly }
|
||||||
|
|
||||||
|
assert(defined(invoker.input))
|
||||||
|
assert(defined(invoker.output))
|
||||||
|
|
||||||
|
action(target_name) {
|
||||||
|
sources = [invoker.input]
|
||||||
|
script = "//build/android/gyp/jinja_template.py"
|
||||||
|
depfile = "$target_gen_dir/$target_name.d"
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
depfile,
|
||||||
|
invoker.output,
|
||||||
|
]
|
||||||
|
|
||||||
|
args = [
|
||||||
|
"--inputs", rebase_path(invoker.input, root_build_dir),
|
||||||
|
"--output", rebase_path(invoker.output, root_build_dir),
|
||||||
|
"--depfile", rebase_path(depfile, root_build_dir),
|
||||||
|
]
|
||||||
|
if (defined(invoker.variables)) {
|
||||||
|
variables = invoker.variables
|
||||||
|
args += ["--variables=${variables}" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Declare a target for processing Android resources as Jinja templates.
|
||||||
|
#
|
||||||
|
# This takes an Android resource directory where each resource is a Jinja
|
||||||
|
# template, processes each template, then packages the results in a zip file
|
||||||
|
# which can be consumed by an android resources, library, or apk target.
|
||||||
|
#
|
||||||
|
# If this target is included in the deps of an android resources/library/apk,
|
||||||
|
# the resources will be included with that target.
|
||||||
|
#
|
||||||
|
# Variables
|
||||||
|
# resources: The list of resources files to process.
|
||||||
|
# res_dir: The resource directory containing the resources.
|
||||||
|
# variables: (Optional) A list of variables to make available to the template
|
||||||
|
# processing environment, e.g. ["name=foo", "color=red"].
|
||||||
|
#
|
||||||
|
# Example
|
||||||
|
# jinja_template_resources("chrome_shell_template_resources") {
|
||||||
|
# res_dir = "shell/res_template"
|
||||||
|
# resources = ["shell/res_template/xml/syncable.xml"]
|
||||||
|
# variables = ["color=red"]
|
||||||
|
# }
|
||||||
|
template("jinja_template_resources") {
|
||||||
|
if (defined(invoker.testonly)) { testonly = invoker.testonly }
|
||||||
|
|
||||||
|
assert(defined(invoker.resources))
|
||||||
|
assert(defined(invoker.res_dir))
|
||||||
|
|
||||||
|
_base_path = "$target_gen_dir/$target_name"
|
||||||
|
_resources_zip = _base_path + ".resources.zip"
|
||||||
|
_build_config = _base_path + ".build_config"
|
||||||
|
|
||||||
|
write_build_config("${target_name}__build_config") {
|
||||||
|
type = "android_resources"
|
||||||
|
}
|
||||||
|
|
||||||
|
action("${target_name}__template") {
|
||||||
|
sources = invoker.resources
|
||||||
|
script = "//build/android/gyp/jinja_template.py"
|
||||||
|
depfile = "$target_gen_dir/$target_name.d"
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
depfile,
|
||||||
|
_resources_zip,
|
||||||
|
]
|
||||||
|
|
||||||
|
rebased_resources = rebase_path(invoker.resources, root_build_dir)
|
||||||
|
args = [
|
||||||
|
"--inputs=${rebased_resources}",
|
||||||
|
"--inputs-base-dir", rebase_path(invoker.res_dir, root_build_dir),
|
||||||
|
"--outputs-zip", rebase_path(_resources_zip, root_build_dir),
|
||||||
|
"--depfile", rebase_path(depfile, root_build_dir),
|
||||||
|
]
|
||||||
|
if (defined(invoker.variables)) {
|
||||||
|
variables = invoker.variables
|
||||||
|
args += ["--variables=${variables}" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group(target_name) {
|
||||||
|
deps = [
|
||||||
|
":${target_name}__build_config",
|
||||||
|
":${target_name}__template",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Declare an Android resources target
|
# Declare an Android resources target
|
||||||
#
|
#
|
||||||
|
@ -688,6 +794,7 @@ template("android_java_prebuilt") {
|
||||||
|
|
||||||
group(target_name) {
|
group(target_name) {
|
||||||
deps = [
|
deps = [
|
||||||
|
":${target_name}__build_config",
|
||||||
":${target_name}__dex",
|
":${target_name}__dex",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче