summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authorcjhopman@chromium.org <cjhopman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-16 00:11:03 +0000
committercjhopman@chromium.org <cjhopman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-16 00:11:03 +0000
commit26046b5fe46738a9c214a64862831e9417f27850 (patch)
tree54071de6ea72c3d5652eff37ff38f2c0483de5df /build
parentcbba05a61cec41f996321156e14d2a0ec306451e (diff)
downloadchromium_src-26046b5fe46738a9c214a64862831e9417f27850.zip
chromium_src-26046b5fe46738a9c214a64862831e9417f27850.tar.gz
chromium_src-26046b5fe46738a9c214a64862831e9417f27850.tar.bz2
[Android][gn] Add android resources templates
This adds support for android resources to gn. Two new templates are introduced: java_string_grd: This is like gyp's build/java_strings_grd.gypi. It runs grit and generates Android strings.xml files and then zips them together. android_resources: This is the target for android resources. It is mostly a wrapper around process_resources.py. This is *not part* of android_library (like it is in gyp). Making these two things separate is more like facebook's BUCK and google's internal build rules (and gyp's java.gypi and java_apk.gypi have gotten way too big and complicated). Changes to the actual build scripts are very minor except for the added support for andoid_resources to write_build_config.py. Building resources requires getting all the transitive resource dependencies, and so this reuses the simple sorted transitive dependency thing from write_ordered_libraries.py. TBR=rch@chromium.org BUG=359249 Review URL: https://codereview.chromium.org/361633002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283293 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'build')
-rwxr-xr-xbuild/android/gyp/find.py27
-rwxr-xr-xbuild/android/gyp/javac.py13
-rwxr-xr-xbuild/android/gyp/process_resources.py102
-rw-r--r--build/android/gyp/util/build_utils.py48
-rwxr-xr-xbuild/android/gyp/write_build_config.py92
-rwxr-xr-xbuild/android/gyp/write_ordered_libraries.py45
-rw-r--r--build/config/android/config.gni7
-rw-r--r--build/config/android/internal_rules.gni86
-rw-r--r--build/config/android/rules.gni148
-rw-r--r--build/secondary/tools/grit/grit_rule.gni35
10 files changed, 493 insertions, 110 deletions
diff --git a/build/android/gyp/find.py b/build/android/gyp/find.py
new file mode 100755
index 0000000..07132c7
--- /dev/null
+++ b/build/android/gyp/find.py
@@ -0,0 +1,27 @@
+#!/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.
+
+"""Finds files in directories.
+"""
+
+import fnmatch
+import optparse
+import os
+import sys
+
+
+def main(argv):
+ parser = optparse.OptionParser()
+ parser.add_option('--pattern', default='*', help='File pattern to match.')
+ options, directories = parser.parse_args(argv)
+
+ for d in directories:
+ for root, _, filenames in os.walk(d):
+ for f in fnmatch.filter(filenames, options.pattern):
+ print os.path.join(root, f)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
index ec2f22a..9dabf70 100755
--- a/build/android/gyp/javac.py
+++ b/build/android/gyp/javac.py
@@ -119,6 +119,8 @@ def main(argv):
help='Directories containing generated java files.')
parser.add_option(
'--java-srcjars',
+ action='append',
+ default=[],
help='List of srcjars to include in compilation.')
parser.add_option(
'--classpath',
@@ -153,18 +155,23 @@ def main(argv):
for arg in options.classpath:
classpath += build_utils.ParseGypList(arg)
+ java_srcjars = []
+ for arg in options.java_srcjars:
+ java_srcjars += build_utils.ParseGypList(arg)
+
java_files = args
if options.src_gendirs:
src_gendirs = build_utils.ParseGypList(options.src_gendirs)
java_files += build_utils.FindInDirectories(src_gendirs, '*.java')
+ input_files = classpath + java_srcjars + java_files
with build_utils.TempDir() as temp_dir:
classes_dir = os.path.join(temp_dir, 'classes')
os.makedirs(classes_dir)
- if options.java_srcjars:
+ if java_srcjars:
java_dir = os.path.join(temp_dir, 'java')
os.makedirs(java_dir)
- for srcjar in build_utils.ParseGypList(options.java_srcjars):
+ for srcjar in java_srcjars:
build_utils.ExtractAll(srcjar, path=java_dir)
java_files += build_utils.FindInDirectory(java_dir, '*.java')
@@ -201,7 +208,7 @@ def main(argv):
if options.depfile:
build_utils.WriteDepfile(
options.depfile,
- classpath + build_utils.GetPythonDependencies())
+ input_files + build_utils.GetPythonDependencies())
if options.stamp:
build_utils.Touch(options.stamp)
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py
index ec19f59..f368d0d 100755
--- a/build/android/gyp/process_resources.py
+++ b/build/android/gyp/process_resources.py
@@ -13,19 +13,22 @@ This will crunch images and generate v14 compatible resources
import optparse
import os
import re
+import shutil
+import sys
import zipfile
import generate_v14_compatible_resources
from util import build_utils
-def ParseArgs():
+def ParseArgs(args):
"""Parses command line options.
Returns:
An options object as from optparse.OptionsParser.parse_args()
"""
parser = optparse.OptionParser()
+ build_utils.AddDepfileOption(parser)
parser.add_option('--android-sdk', help='path to the Android SDK folder')
parser.add_option('--android-sdk-tools',
@@ -40,10 +43,14 @@ def ParseArgs():
parser.add_option('--dependencies-res-zips',
help='Resources from dependents.')
- parser.add_option('--R-dir', help='directory to hold generated R.java')
parser.add_option('--resource-zip-out',
help='Path for output zipped resources.')
+ parser.add_option('--R-dir',
+ help='directory to hold generated R.java.')
+ parser.add_option('--srcjar-out',
+ help='Path to srcjar to contain generated R.java.')
+
parser.add_option('--proguard-file',
help='Path to proguard.txt generated file')
@@ -65,7 +72,7 @@ def ParseArgs():
parser.add_option('--stamp', help='File to touch on success')
- (options, args) = parser.parse_args()
+ (options, args) = parser.parse_args(args)
if args:
parser.error('No positional arguments should be given.')
@@ -78,10 +85,12 @@ def ParseArgs():
'dependencies_res_zips',
'resource_dirs',
'resource_zip_out',
- 'R_dir',
)
build_utils.CheckOptions(options, parser, required=required_options)
+ if (options.R_dir is None) == (options.srcjar_out is None):
+ raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.')
+
return options
@@ -109,10 +118,6 @@ def CreateExtraRJavaFiles(
# affect how the code in this .apk target could refer to the resources.
-
-
-
-
def DidCrunchFail(returncode, stderr):
"""Determines whether aapt crunch failed from its return code and output.
@@ -129,13 +134,30 @@ def DidCrunchFail(returncode, stderr):
return False
+def ZipResources(resource_dirs, zip_path):
+ # Python zipfile does not provide a way to replace a file (it just writes
+ # another file with the same name). So, first collect all the files to put
+ # in the zip (with proper overriding), and then zip them.
+ files_to_zip = dict()
+ for d in resource_dirs:
+ for root, _, files in os.walk(d):
+ for f in files:
+ archive_path = os.path.join(os.path.relpath(root, d), f)
+ path = os.path.join(root, f)
+ files_to_zip[archive_path] = path
+ with zipfile.ZipFile(zip_path, 'w') as outzip:
+ for archive_path, path in files_to_zip.iteritems():
+ outzip.write(path, archive_path)
+
+
def main():
- options = ParseArgs()
+ args = build_utils.ExpandFileArgs(sys.argv[1:])
+
+ options = ParseArgs(args)
android_jar = os.path.join(options.android_sdk, 'android.jar')
aapt = os.path.join(options.android_sdk_tools, 'aapt')
- build_utils.DeleteDirectory(options.R_dir)
- build_utils.MakeDirectory(options.R_dir)
+ input_files = []
with build_utils.TempDir() as temp_dir:
deps_dir = os.path.join(temp_dir, 'deps')
@@ -143,6 +165,9 @@ def main():
v14_dir = os.path.join(temp_dir, 'v14')
build_utils.MakeDirectory(v14_dir)
+ gen_dir = os.path.join(temp_dir, 'gen')
+ build_utils.MakeDirectory(gen_dir)
+
input_resource_dirs = build_utils.ParseGypList(options.resource_dirs)
for resource_dir in input_resource_dirs:
@@ -151,6 +176,16 @@ def main():
v14_dir,
options.v14_verify_only)
+ dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
+ input_files += dep_zips
+ dep_subdirs = []
+ for z in dep_zips:
+ subdir = os.path.join(deps_dir, os.path.basename(z))
+ if os.path.exists(subdir):
+ raise Exception('Resource zip name conflict: ' + os.path.basename(z))
+ build_utils.ExtractAll(z, path=subdir)
+ dep_subdirs.append(subdir)
+
# Generate R.java. This R.java contains non-final constants and is used only
# while compiling the library jar (e.g. chromium_content.jar). When building
# an apk, a new R.java file with the correct resource -> ID mappings will be
@@ -162,19 +197,14 @@ def main():
'-M', options.android_manifest,
'--auto-add-overlay',
'-I', android_jar,
- '--output-text-symbols', options.R_dir,
- '-J', options.R_dir]
+ '--output-text-symbols', gen_dir,
+ '-J', gen_dir]
for d in input_resource_dirs:
package_command += ['-S', d]
- dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
- for z in dep_zips:
- subdir = os.path.join(deps_dir, os.path.basename(z))
- if os.path.exists(subdir):
- raise Exception('Resource zip name conflict: ' + os.path.basename(z))
- build_utils.ExtractAll(z, path=subdir)
- package_command += ['-S', subdir]
+ for d in dep_subdirs:
+ package_command += ['-S', d]
if options.non_constant_id:
package_command.append('--non-constant-id')
@@ -186,7 +216,7 @@ def main():
if options.extra_res_packages:
CreateExtraRJavaFiles(
- options.R_dir,
+ gen_dir,
build_utils.ParseGypList(options.extra_res_packages),
build_utils.ParseGypList(options.extra_r_text_files))
@@ -210,22 +240,20 @@ def main():
'-S', d]
build_utils.CheckOutput(aapt_cmd, fail_func=DidCrunchFail)
- # Python zipfile does not provide a way to replace a file (it just writes
- # another file with the same name). So, first collect all the files to put
- # in the zip (with proper overriding), and then zip them.
- files_to_zip = dict()
- for d in zip_resource_dirs:
- for root, _, files in os.walk(d):
- for f in files:
- archive_path = os.path.join(os.path.relpath(root, d), f)
- path = os.path.join(root, f)
- files_to_zip[archive_path] = path
- with zipfile.ZipFile(options.resource_zip_out, 'w') as outzip:
- for archive_path, path in files_to_zip.iteritems():
- outzip.write(path, archive_path)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
+ ZipResources(zip_resource_dirs, options.resource_zip_out)
+
+ if options.R_dir:
+ build_utils.DeleteDirectory(options.R_dir)
+ shutil.copytree(gen_dir, options.R_dir)
+ else:
+ build_utils.ZipDir(options.srcjar_out, gen_dir)
+
+ if options.depfile:
+ input_files += build_utils.GetPythonDependencies()
+ build_utils.WriteDepfile(options.depfile, input_files)
+
+ if options.stamp:
+ build_utils.Touch(options.stamp)
if __name__ == '__main__':
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
index 9b74f689..9ceb3ff 100644
--- a/build/android/gyp/util/build_utils.py
+++ b/build/android/gyp/util/build_utils.py
@@ -198,6 +198,8 @@ def ExtractAll(zip_path, path=None, no_clobber=True):
with zipfile.ZipFile(zip_path) as z:
for name in z.namelist():
+ if name.endswith('/'):
+ continue
CheckZipPath(name)
if no_clobber:
output_path = os.path.join(path, name)
@@ -216,6 +218,16 @@ def DoZip(inputs, output, base_dir):
outfile.write(f, os.path.relpath(f, base_dir))
+def ZipDir(output, base_dir):
+ with zipfile.ZipFile(output, 'w') as outfile:
+ for root, _, files in os.walk(base_dir):
+ for f in files:
+ path = os.path.join(root, f)
+ archive_path = os.path.relpath(path, base_dir)
+ CheckZipPath(archive_path)
+ outfile.write(path, archive_path)
+
+
def PrintWarning(message):
print 'WARNING: ' + message
@@ -226,6 +238,42 @@ def PrintBigWarning(message):
print '***** ' * 8
+def GetSortedTransitiveDependencies(top, deps_func):
+ """Gets the list of all transitive dependencies in sorted order.
+
+ There should be no cycles in the dependency graph.
+
+ Args:
+ top: a list of the top level nodes
+ deps_func: A function that takes a node and returns its direct dependencies.
+ Returns:
+ A list of all transitive dependencies of nodes in top, in order (a node will
+ appear in the list at a higher index than all of its dependencies).
+ """
+ def Node(dep):
+ return (dep, deps_func(dep))
+
+ # First: find all deps
+ unchecked_deps = list(top)
+ all_deps = set(top)
+ while unchecked_deps:
+ dep = unchecked_deps.pop()
+ new_deps = deps_func(dep).difference(all_deps)
+ unchecked_deps.extend(new_deps)
+ all_deps = all_deps.union(new_deps)
+
+ # Then: simple, slow topological sort.
+ sorted_deps = []
+ unsorted_deps = dict(map(Node, all_deps))
+ while unsorted_deps:
+ for library, dependencies in unsorted_deps.items():
+ if not dependencies.intersection(unsorted_deps.keys()):
+ sorted_deps.append(library)
+ del unsorted_deps[library]
+
+ return sorted_deps
+
+
def GetPythonDependencies():
"""Gets the paths of imported non-system python modules.
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index ff12a1e..794e6a3 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -10,16 +10,17 @@ The build_config file for a target is a json file containing information about
how to build that target based on the target's dependencies. This includes
things like: the javac classpath, the list of android resources dependencies,
etc. It also includes the information needed to create the build_config for
-other target's that depend on that one.
+other targets that depend on that one.
There are several different types of build_configs:
android_library: An android library containing java code.
+ android_resources: A target containing android resources.
Android build scripts should not refer to the build_config directly, and the
build specification should instead pass information in using the special
file-arg syntax (see build_utils.py:ExpandFileArgs). That syntax allows passing
of values in a json dict in a file and looks like this:
- --python-arg=@(build_config_path):javac:classpath
+ --python-arg=@(build_config_path:javac:classpath)
Note: If paths to input files are passed in this way, it is important that:
1. inputs/deps of the action ensure that the files are available the first
@@ -35,17 +36,40 @@ import sys
from util import build_utils
+dep_config_cache = {}
+def GetDepConfig(path):
+ if not path in dep_config_cache:
+ dep_config_cache[path] = build_utils.ReadJson(path)['deps_info']
+ return dep_config_cache[path]
+
+
+def DepsOfType(wanted_type, configs):
+ return [c for c in configs if c['type'] == wanted_type]
+
+
+def GetAllDepsConfigsInOrder(deps_config_paths):
+ def Deps(path):
+ return set(GetDepConfig(path)['deps_configs'])
+ return build_utils.GetSortedTransitiveDependencies(deps_config_paths, Deps)
+
+
def main(argv):
parser = optparse.OptionParser()
build_utils.AddDepfileOption(parser)
parser.add_option('--build-config', help='Path to build_config output.')
- parser.add_option('--type', help='Type of this target.')
+ parser.add_option(
+ '--type',
+ help='Type of this target (e.g. android_library).')
parser.add_option(
'--possible-deps-configs',
help='List of paths for dependency\'s build_config files. Some '
'dependencies may not write build_config files. Missing build_config '
'files are handled differently based on the type of this target.')
+ # android_resources options
+ parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
+ parser.add_option('--resources-zip', help='Path to target\'s resources zip.')
+
# android_library options
parser.add_option('--jar-path', help='Path to target\'s jar output.')
@@ -57,37 +81,67 @@ def main(argv):
required_options = ('build_config', 'type')
build_utils.CheckOptions(options, parser, required_options)
+ if not options.type in [
+ 'android_library', 'android_resources']:
+ raise Exception('Unknown type: <%s>' % options.type)
+
if options.type == 'android_library':
required_options = ('jar_path',)
build_utils.CheckOptions(options, parser, required_options)
- deps_configs = build_utils.ParseGypList(options.possible_deps_configs)
- for c in deps_configs:
+ possible_deps_configs = build_utils.ParseGypList(
+ options.possible_deps_configs)
+ for c in possible_deps_configs:
if not os.path.exists(c):
# Currently we only allow deps to things that write build_config files.
raise Exception('Unknown dep type: ' + c)
- deps_configs = [build_utils.ReadJson(c) for c in deps_configs]
+ direct_deps_config_paths = possible_deps_configs
+ all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)
- if options.type == 'android_library':
- javac_classpath = [c['outputs']['jar_path'] for c in deps_configs]
- config = {
- 'outputs': {
- 'jar_path': options.jar_path
- },
- 'javac': {
- 'classpath': javac_classpath
- }
+ direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
+ all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]
+
+ direct_library_deps = DepsOfType('android_library', direct_deps_configs)
+ all_resources_deps = DepsOfType('android_resources', all_deps_configs)
+
+ # Initialize some common config.
+ config = {
+ 'deps_info': {
+ 'path': options.build_config,
+ 'type': options.type,
+ 'deps_configs': direct_deps_config_paths,
}
- else:
- raise Exception('Unknown type: ' + options.type)
+ }
+ deps_info = config['deps_info']
- build_utils.WriteJson(config, options.build_config)
+ if options.type == 'android_library':
+ javac_classpath = [c['jar_path'] for c in direct_library_deps]
+ deps_info['jar_path'] = options.jar_path
+ config['javac'] = {
+ 'classpath': javac_classpath,
+ }
+ # Only resources might have srcjars (normal srcjar targets are listed in
+ # srcjar_deps). A resource's srcjar contains the R.java file for those
+ # resources, and (like Android's default build system) we allow a library to
+ # refer to the resources in any of its dependents.
+ config['javac']['srcjars'] = [
+ c['srcjar'] for c in all_resources_deps if 'srcjar' in c]
+
+ if options.type == 'android_resources':
+ deps_info['resources_zip'] = options.resources_zip
+ if options.srcjar:
+ deps_info['srcjar'] = options.srcjar
+ config['resources'] = {}
+ config['resources']['dependency_zips'] = [
+ c['resources_zip'] for c in all_resources_deps]
+
+ build_utils.WriteJson(config, options.build_config, only_if_changed=True)
if options.depfile:
build_utils.WriteDepfile(
options.depfile,
- build_utils.GetPythonDependencies())
+ all_deps_config_paths + build_utils.GetPythonDependencies())
if __name__ == '__main__':
diff --git a/build/android/gyp/write_ordered_libraries.py b/build/android/gyp/write_ordered_libraries.py
index b1e3cec..31aba74 100755
--- a/build/android/gyp/write_ordered_libraries.py
+++ b/build/android/gyp/write_ordered_libraries.py
@@ -65,33 +65,18 @@ def GetNonSystemDependencies(library_name):
def GetSortedTransitiveDependencies(libraries):
"""Returns all transitive library dependencies in dependency order."""
- def GraphNode(library):
- return (library, GetNonSystemDependencies(library))
-
- # First: find all library dependencies.
- unchecked_deps = libraries
- all_deps = set(libraries)
- while unchecked_deps:
- lib = unchecked_deps.pop()
- new_deps = GetNonSystemDependencies(lib).difference(all_deps)
- unchecked_deps.extend(new_deps)
- all_deps = all_deps.union(new_deps)
-
- # Then: simple, slow topological sort.
- sorted_deps = []
- unsorted_deps = dict(map(GraphNode, all_deps))
- while unsorted_deps:
- for library, dependencies in unsorted_deps.items():
- if not dependencies.intersection(unsorted_deps.keys()):
- sorted_deps.append(library)
- del unsorted_deps[library]
-
- return sorted_deps
-
-def GetSortedTransitiveDependenciesForExecutable(executable):
- """Returns all transitive library dependencies in dependency order."""
- all_deps = GetDependencies(executable)
- libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)]
+ return build_utils.GetSortedTransitiveDependencies(
+ libraries, GetNonSystemDependencies)
+
+
+def GetSortedTransitiveDependenciesForBinaries(binaries):
+ if binaries[0].endswith('.so'):
+ libraries = [os.path.basename(lib) for lib in binaries]
+ else:
+ assert len(binaries) == 1
+ all_deps = GetDependencies(binaries[0])
+ libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)]
+
return GetSortedTransitiveDependencies(libraries)
@@ -111,11 +96,7 @@ def main():
libraries = build_utils.ParseGypList(_options.input_libraries)
if len(libraries):
- if libraries[0].endswith('.so'):
- libraries = [os.path.basename(lib) for lib in libraries]
- libraries = GetSortedTransitiveDependencies(libraries)
- else:
- libraries = GetSortedTransitiveDependenciesForExecutable(libraries[0])
+ libraries = GetSortedTransitiveDependenciesForBinaries(libraries)
build_utils.WriteJson(libraries, _options.output, only_if_changed=True)
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index abb737b..522318e 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -54,8 +54,13 @@ if (is_android) {
# Path to the Android NDK and SDK.
android_ndk_root = "//third_party/android_tools/ndk"
+ android_sdk = "${android_sdk_root}/platforms/android-${android_sdk_version}"
+
+ android_sdk_tools = "${android_sdk_root}/tools"
+ android_sdk_build_tools = "${android_sdk_root}/build-tools/19.0.0"
+
# Path to the SDK's android.jar
- android_sdk_jar = "$android_sdk_root/platforms/android-19/android.jar"
+ android_sdk_jar = "$android_sdk/android.jar"
# Subdirectories inside android_ndk_root that contain the sysroot for the
# associated platform.
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index f9ed63e..a4bd0b9 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -4,6 +4,13 @@
import("//build/config/android/config.gni")
+assert(is_android)
+
+
+rebased_android_sdk = rebase_path(android_sdk, root_build_dir)
+rebased_android_sdk_root = rebase_path(android_sdk_root, root_build_dir)
+rebased_android_sdk_build_tools = rebase_path(android_sdk_build_tools, root_build_dir)
+
# Write the target's .build_config file. This is a json file that contains a
# dictionary of information about how to build this target (things that
@@ -22,7 +29,7 @@ template("write_build_config") {
type = invoker.type
build_config = base_path + ".build_config"
- assert(type == "android_library" || type == "android_binary")
+ assert(type == "android_binary" || type == "android_library" || type == "android_resources")
action(target_name) {
script = "//build/android/gyp/write_build_config.py"
@@ -58,9 +65,22 @@ template("write_build_config") {
"--jar-path", rebase_path(jar_path, root_build_dir),
]
}
+
+ if (type == "android_resources") {
+ assert(defined(invoker.resources_zip))
+ args += [
+ "--resources-zip", rebase_path(invoker.resources_zip, root_build_dir),
+ ]
+ if (defined(invoker.srcjar)) {
+ args += [
+ "--srcjar", rebase_path(invoker.srcjar, root_build_dir)
+ ]
+ }
+ }
}
}
+
# Creates a zip archive of the inputs.
# If base_dir is provided, the archive paths will be relative to it.
template("zip") {
@@ -90,7 +110,8 @@ template("zip") {
}
}
-# Compiles and jars a set of java_files.
+
+# Compiles and jars a set of java files.
#
# Outputs:
# $jar_path.jar
@@ -164,6 +185,7 @@ template("java_library") {
"--classpath=@($rebase_build_config:javac:classpath)",
"--jar-path=$rebase_jar_path",
"--java-srcjars=$rebase_java_srcjars",
+ "--java-srcjars=@($rebase_build_config:javac:srcjars)",
"--jar-excluded-classes=$jar_excluded_patterns",
]
if (chromium_code) {
@@ -200,6 +222,7 @@ template("java_library") {
}
}
+
# This adds Android-specific parts to the java_library template.
#
# Runs Android lint against the compiled java files.
@@ -232,3 +255,62 @@ template("android_java_library") {
]
}
}
+
+
+# Runs process_resources.py
+template("process_resources") {
+ zip_path = invoker.zip_path
+ srcjar_path = invoker.srcjar_path
+ build_config = invoker.build_config
+ resource_dirs = invoker.resource_dirs
+ android_manifest = invoker.android_manifest
+
+ action(target_name) {
+ script = "//build/android/gyp/process_resources.py"
+
+ depfile = "$target_gen_dir/$target_name.d"
+ outputs = [
+ depfile,
+ zip_path,
+ srcjar_path,
+ ]
+
+ sources_build_rel = exec_script(
+ "//build/android/gyp/find.py",
+ rebase_path(resource_dirs, root_build_dir),
+ "list lines"
+ )
+ sources = rebase_path(sources_build_rel, ".", root_build_dir)
+
+ source_prereqs = [
+ build_config,
+ android_manifest,
+ ]
+
+ rebase_resource_dirs = rebase_path(resource_dirs, root_build_dir)
+ rebase_build_config = rebase_path(build_config, root_build_dir)
+ args = [
+ "--depfile", rebase_path(depfile, root_build_dir),
+ "--android-sdk", rebase_path(android_sdk, root_build_dir),
+ "--android-sdk-tools", rebase_path(android_sdk_build_tools, root_build_dir),
+ "--non-constant-id",
+ "--android-manifest", rebase_path(android_manifest, root_build_dir),
+
+ "--resource-dirs=$rebase_resource_dirs",
+ "--srcjar-out", rebase_path(srcjar_path, root_build_dir),
+ "--resource-zip-out", rebase_path(zip_path, root_build_dir),
+
+ "--dependencies-res-zips=@($rebase_build_config:resources:dependency_zips)",
+ ]
+
+ if (defined(invoker.custom_package)) {
+ args += [
+ "--custom-package", invoker.custom_package,
+ ]
+ }
+
+ if (defined(invoker.v14_verify_only) && invoker.v14_verify_only) {
+ args += ["--v14-verify-only"]
+ }
+ }
+}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 7cb6c8f..662a501 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -4,6 +4,10 @@
import("//build/config/android/config.gni")
import("//build/config/android/internal_rules.gni")
+import("//tools/grit/grit_rule.gni")
+
+assert(is_android)
+
# Declare a jni target
#
@@ -167,6 +171,7 @@ template("generate_jar_jni") {
}
}
+
# Declare a target for c-preprocessor-generated java files
#
# This target generates java files using the host C pre-processor. Each file in
@@ -184,7 +189,8 @@ template("generate_jar_jni") {
# FooBar.java.
# inputs: additional compile-time dependencies. Any files
# `#include`-ed in the templates should be listed here.
-# package_name: this will be the subdirectory for each .java file in the .srcjar.
+# package_name: this will be the subdirectory for each .java file in the
+# .srcjar.
#
# Example
# java_cpp_template("foo_generated_enum") {
@@ -217,7 +223,7 @@ template("java_cpp_template") {
sources = invoker.sources
- gen_dir = "${target_gen_dir}/${package_name}"
+ gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template/${package_name}"
gcc_template_output_pattern = "${gen_dir}/{{source_name_part}}.java"
outputs = [
@@ -250,6 +256,131 @@ template("java_cpp_template") {
}
}
+
+# Declare an Android resources target
+#
+# This creates a resources zip file that will be used when building an Android
+# library or apk and included into a final apk.
+#
+# To include these resources in a library/apk, this target should be listed in
+# the library's deps. A library/apk will also include any resources used by its
+# own dependencies.
+#
+# Variables
+# deps: Specifies the dependencies of this target. Any Android resources
+# listed in deps will be included by libraries/apks that depend on this
+# target.
+# resource_dirs: List of directories containing resources for this target.
+# android_manifest: AndroidManifest.xml for this target. Defaults to
+# //build/android/AndroidManifest.xml.
+# custom_package: java package for generated .java files.
+# v14_verify_only: If true, don't generate v14/v17 resources and just verify
+# that the resources are v14-compliant (see
+# build/android/gyp/generate_v14_compatible_resources.py). Defaults to
+# false.
+#
+# Example
+# android_resources("foo_resources") {
+# deps = [":foo_strings_grd"]
+# resource_dirs = ["res"]
+# custom_package = "org.chromium.foo"
+# }
+template("android_resources") {
+ assert(defined(invoker.resource_dirs))
+
+ base_path = "$target_gen_dir/$target_name"
+ zip_path = base_path + ".resources.zip"
+ srcjar_path = base_path + ".srcjar"
+ build_config = base_path + ".build_config"
+
+ write_build_config("${target_name}__build_config") {
+ type = "android_resources"
+ resources_zip = zip_path
+ srcjar = srcjar_path
+ if (defined(invoker.deps)) {
+ deps = invoker.deps
+ }
+ }
+
+ android_manifest = "//build/android/AndroidManifest.xml"
+ if (defined(invoker.android_manifest)) {
+ android_manifest = invoker.android_manifest
+ }
+
+ process_resources("${target_name}__process_resources") {
+ resource_dirs = invoker.resource_dirs
+ if (defined(invoker.custom_package)) {
+ custom_package = invoker.custom_package
+ }
+
+ if (defined(invoker.v14_verify_only)) {
+ v14_verify_only = invoker.v14_verify_only
+ }
+ }
+
+ group(target_name) {
+ deps = [
+ ":${target_name}__build_config",
+ ":${target_name}__process_resources",
+ ]
+ }
+}
+
+
+# Declare a target that generates localized strings.xml from a .grd file.
+#
+# If this target is included in the deps of an android resources/library/apk,
+# the strings.xml will be included with that target.
+#
+# Variables
+# deps: Specifies the dependencies of this target.
+# grd_file: Path to the .grd file to generate strings.xml from.
+#
+# Example
+# java_strings_grd("foo_strings_grd") {
+# grd_file = "foo_strings.grd"
+# }
+template("java_strings_grd") {
+ base_path = "$target_gen_dir/$target_name"
+ resources_zip = base_path + ".resources.zip"
+
+ write_build_config("${target_name}__build_config") {
+ type = "android_resources"
+ if (defined(invoker.deps)) {
+ deps = invoker.deps
+ }
+ }
+
+ grit_target_name = "${target_name}__grit"
+ grit_output_dir = base_path + "_grit_output"
+ grit(grit_target_name) {
+ grit_flags = [
+ "-E", "ANDROID_JAVA_TAGGED_ONLY=false",
+ ]
+ output_dir = grit_output_dir
+ resource_ids = ""
+ source = invoker.grd_file
+ }
+
+ # This needs to get outputs from grit's internal target, not the final
+ # source_set.
+ generate_strings_outputs = get_target_outputs(":${grit_target_name}_grit")
+
+ zip("${target_name}__zip") {
+ base_dir = grit_output_dir
+ inputs = generate_strings_outputs
+ output = resources_zip
+ }
+
+ group(target_name) {
+ deps = [
+ ":${target_name}__build_config",
+ ":${target_name}__zip",
+ ]
+ }
+}
+
+
# Declare an Android library target
#
# This target creates an Android library containing java code and Android
@@ -257,12 +388,14 @@ template("java_cpp_template") {
#
# Variables
# deps: Specifies the dependencies of this target. Java targets in this list
-# will be added to the javac classpath.
+# will be added to the javac classpath. Android resources in dependencies
+# will be used when building this library.
# java_files: List of .java files included in this library.
# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
# will be added to java_files and be included in this library.
#
-# jar_excluded_patterns: List of patterns of .class files to exclude from the final jar.
+# jar_excluded_patterns: List of patterns of .class files to exclude from the
+# final jar.
#
# Example
# android_library("foo_java") {
@@ -282,11 +415,9 @@ template("java_cpp_template") {
# ]
# }
template("android_library") {
- #TODO(cjhopman): resources
-
assert(defined(invoker.java_files))
- dep = ":${target_name}"
- base_path = get_label_info(dep, "target_gen_dir") + "/" + target_name
+
+ base_path = "$target_gen_dir/$target_name"
build_config = base_path + ".build_config"
write_build_config("${target_name}__build_config") {
@@ -314,4 +445,3 @@ template("android_library") {
}
}
}
-
diff --git a/build/secondary/tools/grit/grit_rule.gni b/build/secondary/tools/grit/grit_rule.gni
index 2f03335..86a155a 100644
--- a/build/secondary/tools/grit/grit_rule.gni
+++ b/build/secondary/tools/grit/grit_rule.gni
@@ -13,6 +13,14 @@
# grit_flags (optional)
# List of strings containing extra command-line flags to pass to Grit.
#
+# resource_ids (optional)
+# Path to a grit "firstidsfile". Default is
+# //tools/gritsettings/resource_ids. Set to "" to use the value specified in
+# the <grit> nodes of the processed files.
+#
+# output_dir (optional)
+# Directory for generated files.
+#
# deps (optional)
# visibility (optional)
# Normal meaning.
@@ -161,11 +169,24 @@ template("grit") {
"Neither \"sources\" nor \"outputs\" can be defined for the grit " +
"template $target_name")
+ if (defined(invoker.resource_ids)) {
+ resource_ids = invoker.resource_ids
+ } else {
+ resource_ids = grit_resource_id_file
+ }
+
+ if (defined(invoker.output_dir)) {
+ output_dir = invoker.output_dir
+ } else {
+ output_dir = target_gen_dir
+ }
+
# These are all passed as arguments to the script so have to be relative to
# the build directory.
- resource_ids =
- rebase_path(grit_resource_id_file, root_build_dir)
- output_dir = rebase_path(target_gen_dir, root_build_dir)
+ if (resource_ids != "") {
+ resource_ids = rebase_path(resource_ids, root_build_dir)
+ }
+ rebased_output_dir = rebase_path(output_dir, root_build_dir)
source_path = rebase_path(invoker.source, root_build_dir)
if (defined(invoker.grit_flags)) {
@@ -183,7 +204,7 @@ template("grit") {
]
grit_outputs_build_rel = exec_script(grit_info_script,
- [ "--outputs", "$output_dir", source_path, "-f", resource_ids ] +
+ [ "--outputs", "$rebased_output_dir", source_path, "-f", resource_ids ] +
grit_flags,
"list lines")
@@ -199,13 +220,13 @@ template("grit") {
# overwritten inside the innter classes so we need to compute it here.
target_visibility = ":$target_name"
- # The current grit setup makes an file in $target_gen_dir/grit/foo.h that
+ # The current grit setup makes an file in $output_dir/grit/foo.h that
# the source code expects to include via "grit/foo.h". It would be nice to
# change this to including absolute paths relative to the root gen directory
# (like "mycomponent/foo.h"). This config sets up the include path.
grit_config = target_name + "_grit_config"
config(grit_config) {
- include_dirs = [ target_gen_dir ]
+ include_dirs = [ output_dir ]
visibility = target_visibility
}
@@ -218,7 +239,7 @@ template("grit") {
args = [
"-i", source_path, "build",
"-f", resource_ids,
- "-o", output_dir,
+ "-o", rebased_output_dir,
] + grit_defines + grit_flags
visibility = target_visibility