Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(558)

Side by Side Diff: build/android/gyp/process_resources.py

Issue 361633002: [Android][gn] Add android resources templates (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gn-java
Patch Set: Fix bad rebase Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/gyp/javac.py ('k') | build/android/gyp/util/build_utils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Process Android resources to generate R.java, and prepare for packaging. 7 """Process Android resources to generate R.java, and prepare for packaging.
8 8
9 This will crunch images and generate v14 compatible resources 9 This will crunch images and generate v14 compatible resources
10 (see generate_v14_compatible_resources.py). 10 (see generate_v14_compatible_resources.py).
11 """ 11 """
12 12
13 import optparse 13 import optparse
14 import os 14 import os
15 import re 15 import re
16 import shutil
17 import sys
16 import zipfile 18 import zipfile
17 19
18 import generate_v14_compatible_resources 20 import generate_v14_compatible_resources
19 21
20 from util import build_utils 22 from util import build_utils
21 23
22 def ParseArgs(): 24 def ParseArgs(args):
23 """Parses command line options. 25 """Parses command line options.
24 26
25 Returns: 27 Returns:
26 An options object as from optparse.OptionsParser.parse_args() 28 An options object as from optparse.OptionsParser.parse_args()
27 """ 29 """
28 parser = optparse.OptionParser() 30 parser = optparse.OptionParser()
31 build_utils.AddDepfileOption(parser)
29 32
30 parser.add_option('--android-sdk', help='path to the Android SDK folder') 33 parser.add_option('--android-sdk', help='path to the Android SDK folder')
31 parser.add_option('--android-sdk-tools', 34 parser.add_option('--android-sdk-tools',
32 help='path to the Android SDK build tools folder') 35 help='path to the Android SDK build tools folder')
33 parser.add_option('--non-constant-id', action='store_true') 36 parser.add_option('--non-constant-id', action='store_true')
34 37
35 parser.add_option('--android-manifest', help='AndroidManifest.xml path') 38 parser.add_option('--android-manifest', help='AndroidManifest.xml path')
36 parser.add_option('--custom-package', help='Java package for R.java') 39 parser.add_option('--custom-package', help='Java package for R.java')
37 40
38 parser.add_option('--resource-dirs', 41 parser.add_option('--resource-dirs',
39 help='Directories containing resources of this target.') 42 help='Directories containing resources of this target.')
40 parser.add_option('--dependencies-res-zips', 43 parser.add_option('--dependencies-res-zips',
41 help='Resources from dependents.') 44 help='Resources from dependents.')
42 45
43 parser.add_option('--R-dir', help='directory to hold generated R.java')
44 parser.add_option('--resource-zip-out', 46 parser.add_option('--resource-zip-out',
45 help='Path for output zipped resources.') 47 help='Path for output zipped resources.')
46 48
49 parser.add_option('--R-dir',
50 help='directory to hold generated R.java.')
51 parser.add_option('--srcjar-out',
52 help='Path to srcjar to contain generated R.java.')
53
47 parser.add_option('--proguard-file', 54 parser.add_option('--proguard-file',
48 help='Path to proguard.txt generated file') 55 help='Path to proguard.txt generated file')
49 56
50 parser.add_option( 57 parser.add_option(
51 '--v14-verify-only', 58 '--v14-verify-only',
52 action='store_true', 59 action='store_true',
53 help='Do not generate v14 resources. Instead, just verify that the ' 60 help='Do not generate v14 resources. Instead, just verify that the '
54 'resources are already compatible with v14, i.e. they don\'t use ' 61 'resources are already compatible with v14, i.e. they don\'t use '
55 'attributes that cause crashes on certain devices.') 62 'attributes that cause crashes on certain devices.')
56 63
57 parser.add_option( 64 parser.add_option(
58 '--extra-res-packages', 65 '--extra-res-packages',
59 help='Additional package names to generate R.java files for') 66 help='Additional package names to generate R.java files for')
60 parser.add_option( 67 parser.add_option(
61 '--extra-r-text-files', 68 '--extra-r-text-files',
62 help='For each additional package, the R.txt file should contain a ' 69 help='For each additional package, the R.txt file should contain a '
63 'list of resources to be included in the R.java file in the format ' 70 'list of resources to be included in the R.java file in the format '
64 'generated by aapt') 71 'generated by aapt')
65 72
66 parser.add_option('--stamp', help='File to touch on success') 73 parser.add_option('--stamp', help='File to touch on success')
67 74
68 (options, args) = parser.parse_args() 75 (options, args) = parser.parse_args(args)
69 76
70 if args: 77 if args:
71 parser.error('No positional arguments should be given.') 78 parser.error('No positional arguments should be given.')
72 79
73 # Check that required options have been provided. 80 # Check that required options have been provided.
74 required_options = ( 81 required_options = (
75 'android_sdk', 82 'android_sdk',
76 'android_sdk_tools', 83 'android_sdk_tools',
77 'android_manifest', 84 'android_manifest',
78 'dependencies_res_zips', 85 'dependencies_res_zips',
79 'resource_dirs', 86 'resource_dirs',
80 'resource_zip_out', 87 'resource_zip_out',
81 'R_dir',
82 ) 88 )
83 build_utils.CheckOptions(options, parser, required=required_options) 89 build_utils.CheckOptions(options, parser, required=required_options)
84 90
91 if (options.R_dir is None) == (options.srcjar_out is None):
92 raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.')
93
85 return options 94 return options
86 95
87 96
88 def CreateExtraRJavaFiles( 97 def CreateExtraRJavaFiles(
89 r_dir, extra_packages, extra_r_text_files): 98 r_dir, extra_packages, extra_r_text_files):
90 if len(extra_packages) != len(extra_r_text_files): 99 if len(extra_packages) != len(extra_r_text_files):
91 raise Exception('--extra-res-packages and --extra-r-text-files' 100 raise Exception('--extra-res-packages and --extra-r-text-files'
92 'should have the same length') 101 'should have the same length')
93 102
94 java_files = build_utils.FindInDirectory(r_dir, "R.java") 103 java_files = build_utils.FindInDirectory(r_dir, "R.java")
95 if len(java_files) != 1: 104 if len(java_files) != 1:
96 return 105 return
97 r_java_file = java_files[0] 106 r_java_file = java_files[0]
98 r_java_contents = open(r_java_file).read() 107 r_java_contents = open(r_java_file).read()
99 108
100 for package in extra_packages: 109 for package in extra_packages:
101 package_r_java_dir = os.path.join(r_dir, *package.split('.')) 110 package_r_java_dir = os.path.join(r_dir, *package.split('.'))
102 build_utils.MakeDirectory(package_r_java_dir) 111 build_utils.MakeDirectory(package_r_java_dir)
103 package_r_java_path = os.path.join(package_r_java_dir, 'R.java') 112 package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
104 open(package_r_java_path, 'w').write( 113 open(package_r_java_path, 'w').write(
105 re.sub(r'package [.\w]*;', 'package %s;' % package, r_java_contents)) 114 re.sub(r'package [.\w]*;', 'package %s;' % package, r_java_contents))
106 # TODO(cjhopman): These extra package's R.java files should be filtered to 115 # TODO(cjhopman): These extra package's R.java files should be filtered to
107 # only contain the resources listed in their R.txt files. At this point, we 116 # only contain the resources listed in their R.txt files. At this point, we
108 # have already compiled those other libraries, so doing this would only 117 # have already compiled those other libraries, so doing this would only
109 # affect how the code in this .apk target could refer to the resources. 118 # affect how the code in this .apk target could refer to the resources.
110 119
111 120
112
113
114
115
116 def DidCrunchFail(returncode, stderr): 121 def DidCrunchFail(returncode, stderr):
117 """Determines whether aapt crunch failed from its return code and output. 122 """Determines whether aapt crunch failed from its return code and output.
118 123
119 Because aapt's return code cannot be trusted, any output to stderr is 124 Because aapt's return code cannot be trusted, any output to stderr is
120 an indication that aapt has failed (http://crbug.com/314885), except 125 an indication that aapt has failed (http://crbug.com/314885), except
121 lines that contain "libpng warning", which is a known non-error condition 126 lines that contain "libpng warning", which is a known non-error condition
122 (http://crbug.com/364355). 127 (http://crbug.com/364355).
123 """ 128 """
124 if returncode != 0: 129 if returncode != 0:
125 return True 130 return True
126 for line in stderr.splitlines(): 131 for line in stderr.splitlines():
127 if line and not 'libpng warning' in line: 132 if line and not 'libpng warning' in line:
128 return True 133 return True
129 return False 134 return False
130 135
131 136
137 def ZipResources(resource_dirs, zip_path):
138 # Python zipfile does not provide a way to replace a file (it just writes
139 # another file with the same name). So, first collect all the files to put
140 # in the zip (with proper overriding), and then zip them.
141 files_to_zip = dict()
142 for d in resource_dirs:
143 for root, _, files in os.walk(d):
144 for f in files:
145 archive_path = os.path.join(os.path.relpath(root, d), f)
146 path = os.path.join(root, f)
147 files_to_zip[archive_path] = path
148 with zipfile.ZipFile(zip_path, 'w') as outzip:
149 for archive_path, path in files_to_zip.iteritems():
150 outzip.write(path, archive_path)
151
152
132 def main(): 153 def main():
133 options = ParseArgs() 154 args = build_utils.ExpandFileArgs(sys.argv[1:])
155
156 options = ParseArgs(args)
134 android_jar = os.path.join(options.android_sdk, 'android.jar') 157 android_jar = os.path.join(options.android_sdk, 'android.jar')
135 aapt = os.path.join(options.android_sdk_tools, 'aapt') 158 aapt = os.path.join(options.android_sdk_tools, 'aapt')
136 159
137 build_utils.DeleteDirectory(options.R_dir) 160 input_files = []
138 build_utils.MakeDirectory(options.R_dir)
139 161
140 with build_utils.TempDir() as temp_dir: 162 with build_utils.TempDir() as temp_dir:
141 deps_dir = os.path.join(temp_dir, 'deps') 163 deps_dir = os.path.join(temp_dir, 'deps')
142 build_utils.MakeDirectory(deps_dir) 164 build_utils.MakeDirectory(deps_dir)
143 v14_dir = os.path.join(temp_dir, 'v14') 165 v14_dir = os.path.join(temp_dir, 'v14')
144 build_utils.MakeDirectory(v14_dir) 166 build_utils.MakeDirectory(v14_dir)
145 167
168 gen_dir = os.path.join(temp_dir, 'gen')
169 build_utils.MakeDirectory(gen_dir)
170
146 input_resource_dirs = build_utils.ParseGypList(options.resource_dirs) 171 input_resource_dirs = build_utils.ParseGypList(options.resource_dirs)
147 172
148 for resource_dir in input_resource_dirs: 173 for resource_dir in input_resource_dirs:
149 generate_v14_compatible_resources.GenerateV14Resources( 174 generate_v14_compatible_resources.GenerateV14Resources(
150 resource_dir, 175 resource_dir,
151 v14_dir, 176 v14_dir,
152 options.v14_verify_only) 177 options.v14_verify_only)
153 178
179 dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
180 input_files += dep_zips
181 dep_subdirs = []
182 for z in dep_zips:
183 subdir = os.path.join(deps_dir, os.path.basename(z))
184 if os.path.exists(subdir):
185 raise Exception('Resource zip name conflict: ' + os.path.basename(z))
186 build_utils.ExtractAll(z, path=subdir)
187 dep_subdirs.append(subdir)
188
154 # Generate R.java. This R.java contains non-final constants and is used only 189 # Generate R.java. This R.java contains non-final constants and is used only
155 # while compiling the library jar (e.g. chromium_content.jar). When building 190 # while compiling the library jar (e.g. chromium_content.jar). When building
156 # an apk, a new R.java file with the correct resource -> ID mappings will be 191 # an apk, a new R.java file with the correct resource -> ID mappings will be
157 # generated by merging the resources from all libraries and the main apk 192 # generated by merging the resources from all libraries and the main apk
158 # project. 193 # project.
159 package_command = [aapt, 194 package_command = [aapt,
160 'package', 195 'package',
161 '-m', 196 '-m',
162 '-M', options.android_manifest, 197 '-M', options.android_manifest,
163 '--auto-add-overlay', 198 '--auto-add-overlay',
164 '-I', android_jar, 199 '-I', android_jar,
165 '--output-text-symbols', options.R_dir, 200 '--output-text-symbols', gen_dir,
166 '-J', options.R_dir] 201 '-J', gen_dir]
167 202
168 for d in input_resource_dirs: 203 for d in input_resource_dirs:
169 package_command += ['-S', d] 204 package_command += ['-S', d]
170 205
171 dep_zips = build_utils.ParseGypList(options.dependencies_res_zips) 206 for d in dep_subdirs:
172 for z in dep_zips: 207 package_command += ['-S', d]
173 subdir = os.path.join(deps_dir, os.path.basename(z))
174 if os.path.exists(subdir):
175 raise Exception('Resource zip name conflict: ' + os.path.basename(z))
176 build_utils.ExtractAll(z, path=subdir)
177 package_command += ['-S', subdir]
178 208
179 if options.non_constant_id: 209 if options.non_constant_id:
180 package_command.append('--non-constant-id') 210 package_command.append('--non-constant-id')
181 if options.custom_package: 211 if options.custom_package:
182 package_command += ['--custom-package', options.custom_package] 212 package_command += ['--custom-package', options.custom_package]
183 if options.proguard_file: 213 if options.proguard_file:
184 package_command += ['-G', options.proguard_file] 214 package_command += ['-G', options.proguard_file]
185 build_utils.CheckOutput(package_command, print_stderr=False) 215 build_utils.CheckOutput(package_command, print_stderr=False)
186 216
187 if options.extra_res_packages: 217 if options.extra_res_packages:
188 CreateExtraRJavaFiles( 218 CreateExtraRJavaFiles(
189 options.R_dir, 219 gen_dir,
190 build_utils.ParseGypList(options.extra_res_packages), 220 build_utils.ParseGypList(options.extra_res_packages),
191 build_utils.ParseGypList(options.extra_r_text_files)) 221 build_utils.ParseGypList(options.extra_r_text_files))
192 222
193 # This is the list of directories with resources to put in the final .zip 223 # This is the list of directories with resources to put in the final .zip
194 # file. The order of these is important so that crunched/v14 resources 224 # file. The order of these is important so that crunched/v14 resources
195 # override the normal ones. 225 # override the normal ones.
196 zip_resource_dirs = input_resource_dirs + [v14_dir] 226 zip_resource_dirs = input_resource_dirs + [v14_dir]
197 227
198 base_crunch_dir = os.path.join(temp_dir, 'crunch') 228 base_crunch_dir = os.path.join(temp_dir, 'crunch')
199 229
200 # Crunch image resources. This shrinks png files and is necessary for 230 # Crunch image resources. This shrinks png files and is necessary for
201 # 9-patch images to display correctly. 'aapt crunch' accepts only a single 231 # 9-patch images to display correctly. 'aapt crunch' accepts only a single
202 # directory at a time and deletes everything in the output directory. 232 # directory at a time and deletes everything in the output directory.
203 for idx, d in enumerate(input_resource_dirs): 233 for idx, d in enumerate(input_resource_dirs):
204 crunch_dir = os.path.join(base_crunch_dir, str(idx)) 234 crunch_dir = os.path.join(base_crunch_dir, str(idx))
205 build_utils.MakeDirectory(crunch_dir) 235 build_utils.MakeDirectory(crunch_dir)
206 zip_resource_dirs.append(crunch_dir) 236 zip_resource_dirs.append(crunch_dir)
207 aapt_cmd = [aapt, 237 aapt_cmd = [aapt,
208 'crunch', 238 'crunch',
209 '-C', crunch_dir, 239 '-C', crunch_dir,
210 '-S', d] 240 '-S', d]
211 build_utils.CheckOutput(aapt_cmd, fail_func=DidCrunchFail) 241 build_utils.CheckOutput(aapt_cmd, fail_func=DidCrunchFail)
212 242
213 # Python zipfile does not provide a way to replace a file (it just writes 243 ZipResources(zip_resource_dirs, options.resource_zip_out)
214 # another file with the same name). So, first collect all the files to put
215 # in the zip (with proper overriding), and then zip them.
216 files_to_zip = dict()
217 for d in zip_resource_dirs:
218 for root, _, files in os.walk(d):
219 for f in files:
220 archive_path = os.path.join(os.path.relpath(root, d), f)
221 path = os.path.join(root, f)
222 files_to_zip[archive_path] = path
223 with zipfile.ZipFile(options.resource_zip_out, 'w') as outzip:
224 for archive_path, path in files_to_zip.iteritems():
225 outzip.write(path, archive_path)
226 244
227 if options.stamp: 245 if options.R_dir:
228 build_utils.Touch(options.stamp) 246 build_utils.DeleteDirectory(options.R_dir)
247 shutil.copytree(gen_dir, options.R_dir)
248 else:
249 build_utils.ZipDir(options.srcjar_out, gen_dir)
250
251 if options.depfile:
252 input_files += build_utils.GetPythonDependencies()
253 build_utils.WriteDepfile(options.depfile, input_files)
254
255 if options.stamp:
256 build_utils.Touch(options.stamp)
229 257
230 258
231 if __name__ == '__main__': 259 if __name__ == '__main__':
232 main() 260 main()
OLDNEW
« no previous file with comments | « build/android/gyp/javac.py ('k') | build/android/gyp/util/build_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698