Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2014 The Chromium Authors. All rights reserved. | 3 # Copyright 2014 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 """Writes a build_config file. | 7 """Writes a build_config file. |
| 8 | 8 |
| 9 The build_config file for a target is a json file containing information about | 9 The build_config file for a target is a json file containing information about |
| 10 how to build that target based on the target's dependencies. This includes | 10 how to build that target based on the target's dependencies. This includes |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 1. inputs/deps of the action ensure that the files are available the first | 22 1. inputs/deps of the action ensure that the files are available the first |
| 23 time the action runs. | 23 time the action runs. |
| 24 2. Either (a) or (b) | 24 2. Either (a) or (b) |
| 25 a. inputs/deps ensure that the action runs whenever one of the files changes | 25 a. inputs/deps ensure that the action runs whenever one of the files changes |
| 26 b. the files are added to the action's depfile | 26 b. the files are added to the action's depfile |
| 27 """ | 27 """ |
| 28 | 28 |
| 29 import optparse | 29 import optparse |
| 30 import os | 30 import os |
| 31 import sys | 31 import sys |
| 32 import xml.dom.minidom | |
| 32 | 33 |
| 33 from util import build_utils | 34 from util import build_utils |
| 34 | 35 |
| 35 import write_ordered_libraries | 36 import write_ordered_libraries |
| 36 | 37 |
| 38 class AndroidManifest(object): | |
| 39 def __init__(self, path): | |
| 40 self.path = path | |
| 41 dom = xml.dom.minidom.parse(path) | |
| 42 manifests = dom.getElementsByTagName('manifest') | |
| 43 assert len(manifests) == 1 | |
| 44 self.manifest = manifests[0] | |
| 45 | |
| 46 def GetInstrumentation(self): | |
| 47 instrumentation_els = self.manifest.getElementsByTagName('instrumentation') | |
| 48 if len(instrumentation_els) == 0: | |
| 49 return None | |
| 50 if len(instrumentation_els) != 1: | |
| 51 raise Exception( | |
| 52 'Unexpected number of instrumentation nodes in Android manifest (%s):' | |
|
newt (away)
2015/04/23 03:19:18
I'd keep this simple:
"More than one <instrumen
cjhopman
2015/04/24 01:26:21
Done.
| |
| 53 % self.path, *(map(lambda e: e.toprettyxml(), instrumentation_els))) | |
| 54 return instrumentation_els[0] | |
| 55 | |
| 56 def CheckInstrumentation(self, expected_package): | |
| 57 instr = self.GetInstrumentation() | |
| 58 if not instr: | |
| 59 raise Exception( | |
| 60 'No instrumentation nodes found in Android manifest (%s)' % self.path) | |
|
newt (away)
2015/04/23 03:19:18
s/nodes/elements
node is the parent type of eleme
cjhopman
2015/04/24 01:26:21
Done.
| |
| 61 instrumented_package = instr.getAttributeNS( | |
| 62 'http://schemas.android.com/apk/res/android', 'targetPackage') | |
| 63 if instrumented_package != expected_package: | |
| 64 raise Exception( | |
| 65 'Wrong instrumented package. Expected %s, got %s' | |
| 66 % (expected_package, instrumented_package)) | |
| 67 | |
| 68 def GetPackageName(self): | |
| 69 return self.manifest.getAttribute('package') | |
| 70 | |
| 37 | 71 |
| 38 dep_config_cache = {} | 72 dep_config_cache = {} |
| 39 def GetDepConfig(path): | 73 def GetDepConfig(path): |
| 40 if not path in dep_config_cache: | 74 if not path in dep_config_cache: |
| 41 dep_config_cache[path] = build_utils.ReadJson(path)['deps_info'] | 75 dep_config_cache[path] = build_utils.ReadJson(path)['deps_info'] |
| 42 return dep_config_cache[path] | 76 return dep_config_cache[path] |
| 43 | 77 |
| 44 | 78 |
| 45 def DepsOfType(wanted_type, configs): | 79 def DepsOfType(wanted_type, configs): |
| 46 return [c for c in configs if c['type'] == wanted_type] | 80 return [c for c in configs if c['type'] == wanted_type] |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 config = { | 185 config = { |
| 152 'deps_info': { | 186 'deps_info': { |
| 153 'name': os.path.basename(options.build_config), | 187 'name': os.path.basename(options.build_config), |
| 154 'path': options.build_config, | 188 'path': options.build_config, |
| 155 'type': options.type, | 189 'type': options.type, |
| 156 'deps_configs': direct_deps_config_paths, | 190 'deps_configs': direct_deps_config_paths, |
| 157 } | 191 } |
| 158 } | 192 } |
| 159 deps_info = config['deps_info'] | 193 deps_info = config['deps_info'] |
| 160 | 194 |
| 161 | |
| 162 if options.type == 'java_library' and not options.bypass_platform_checks: | 195 if options.type == 'java_library' and not options.bypass_platform_checks: |
| 163 deps_info['requires_android'] = options.requires_android | 196 deps_info['requires_android'] = options.requires_android |
| 164 deps_info['supports_android'] = options.supports_android | 197 deps_info['supports_android'] = options.supports_android |
| 165 | 198 |
| 166 deps_require_android = (all_resources_deps + | 199 deps_require_android = (all_resources_deps + |
| 167 [d['name'] for d in all_library_deps if d['requires_android']]) | 200 [d['name'] for d in all_library_deps if d['requires_android']]) |
| 168 deps_not_support_android = ( | 201 deps_not_support_android = ( |
| 169 [d['name'] for d in all_library_deps if not d['supports_android']]) | 202 [d['name'] for d in all_library_deps if not d['supports_android']]) |
| 170 | 203 |
| 171 if deps_require_android and not options.requires_android: | 204 if deps_require_android and not options.requires_android: |
| 172 raise Exception('Some deps require building for the Android platform: ' + | 205 raise Exception('Some deps require building for the Android platform: ' + |
| 173 str(deps_require_android)) | 206 str(deps_require_android)) |
| 174 | 207 |
| 175 if deps_not_support_android and options.supports_android: | 208 if deps_not_support_android and options.supports_android: |
| 176 raise Exception('Not all deps support the Android platform: ' + | 209 raise Exception('Not all deps support the Android platform: ' + |
| 177 str(deps_not_support_android)) | 210 str(deps_not_support_android)) |
| 178 | 211 |
| 179 | |
| 180 if options.type in ['java_library', 'android_apk']: | 212 if options.type in ['java_library', 'android_apk']: |
| 181 javac_classpath = [c['jar_path'] for c in direct_library_deps] | 213 javac_classpath = [c['jar_path'] for c in direct_library_deps] |
| 182 java_full_classpath = [c['jar_path'] for c in all_library_deps] | 214 java_full_classpath = [c['jar_path'] for c in all_library_deps] |
| 183 deps_info['resources_deps'] = [c['path'] for c in all_resources_deps] | 215 deps_info['resources_deps'] = [c['path'] for c in all_resources_deps] |
| 184 deps_info['jar_path'] = options.jar_path | 216 deps_info['jar_path'] = options.jar_path |
| 185 if options.type == 'android_apk' or options.supports_android: | 217 if options.type == 'android_apk' or options.supports_android: |
| 186 deps_info['dex_path'] = options.dex_path | 218 deps_info['dex_path'] = options.dex_path |
| 187 config['javac'] = { | 219 config['javac'] = { |
| 188 'classpath': javac_classpath, | 220 'classpath': javac_classpath, |
| 189 } | 221 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 213 if options.type == 'android_resources' or options.type == 'android_apk': | 245 if options.type == 'android_resources' or options.type == 'android_apk': |
| 214 config['resources'] = {} | 246 config['resources'] = {} |
| 215 config['resources']['dependency_zips'] = [ | 247 config['resources']['dependency_zips'] = [ |
| 216 c['resources_zip'] for c in all_resources_deps] | 248 c['resources_zip'] for c in all_resources_deps] |
| 217 config['resources']['extra_package_names'] = [] | 249 config['resources']['extra_package_names'] = [] |
| 218 | 250 |
| 219 if options.type == 'android_apk': | 251 if options.type == 'android_apk': |
| 220 config['resources']['extra_package_names'] = [ | 252 config['resources']['extra_package_names'] = [ |
| 221 c['package_name'] for c in all_resources_deps if 'package_name' in c] | 253 c['package_name'] for c in all_resources_deps if 'package_name' in c] |
| 222 | 254 |
| 223 | 255 excluded_deps_dex_files = [] |
| 224 deps_dex_files = [c['dex_path'] for c in all_library_deps] | |
| 225 # An instrumentation test apk should exclude the dex files that are in the apk | 256 # An instrumentation test apk should exclude the dex files that are in the apk |
| 226 # under test. | 257 # under test. |
| 227 if options.type == 'android_apk' and options.tested_apk_config: | 258 if options.type == 'android_apk' and options.tested_apk_config: |
| 228 tested_apk_config_paths = GetAllDepsConfigsInOrder( | 259 tested_apk_config_paths = GetAllDepsConfigsInOrder( |
| 229 [options.tested_apk_config]) | 260 [options.tested_apk_config]) |
| 230 tested_apk_configs = [GetDepConfig(p) for p in tested_apk_config_paths] | 261 tested_apk_configs = [GetDepConfig(p) for p in tested_apk_config_paths] |
| 231 tested_apk_library_deps = DepsOfType('java_library', tested_apk_configs) | 262 tested_apk_library_deps = DepsOfType('java_library', tested_apk_configs) |
| 232 tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps] | 263 excluded_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps] |
|
newt (away)
2015/04/23 03:19:18
Why not just modify deps_dex_files at this point?
cjhopman
2015/04/24 01:26:21
Done.
| |
| 233 deps_dex_files = [ | 264 tested_apk_config = GetDepConfig(options.tested_apk_config) |
| 234 p for p in deps_dex_files if not p in tested_apk_deps_dex_files] | 265 expected_tested_package = tested_apk_config['package_name'] |
| 235 | 266 AndroidManifest(options.android_manifest).CheckInstrumentation( |
| 267 expected_tested_package) | |
| 236 | 268 |
| 237 # Dependencies for the final dex file of an apk or a 'deps_dex'. | 269 # Dependencies for the final dex file of an apk or a 'deps_dex'. |
| 238 if options.type in ['android_apk', 'deps_dex']: | 270 if options.type in ['android_apk', 'deps_dex']: |
| 239 config['final_dex'] = {} | 271 config['final_dex'] = {} |
| 240 dex_config = config['final_dex'] | 272 dex_config = config['final_dex'] |
| 241 # TODO(cjhopman): proguard version | 273 # TODO(cjhopman): proguard version |
| 274 deps_dex_files = [c['dex_path'] for c in all_library_deps | |
| 275 if not c in excluded_deps_dex_files] | |
| 242 dex_config['dependency_dex_files'] = deps_dex_files | 276 dex_config['dependency_dex_files'] = deps_dex_files |
| 243 | 277 |
| 244 | |
| 245 if options.type == 'android_apk': | 278 if options.type == 'android_apk': |
| 246 config['dist_jar'] = { | 279 config['dist_jar'] = { |
| 247 'dependency_jars': [ | 280 'dependency_jars': [ |
| 248 c['jar_path'] for c in all_library_deps | 281 c['jar_path'] for c in all_library_deps |
| 249 ] | 282 ] |
| 250 } | 283 } |
| 284 manifest = AndroidManifest(options.android_manifest) | |
| 285 deps_info['package_name'] = manifest.GetPackageName() | |
| 286 if not options.tested_apk_config and manifest.GetInstrumentation(): | |
| 287 # This must then have instrumentation only for itself. | |
| 288 manifest.CheckInstrumentation(manifest.GetPackageName()) | |
| 251 | 289 |
| 252 library_paths = [] | 290 library_paths = [] |
| 253 java_libraries_list = [] | 291 java_libraries_list = [] |
| 254 if options.native_libs: | 292 if options.native_libs: |
| 255 libraries = build_utils.ParseGypList(options.native_libs) | 293 libraries = build_utils.ParseGypList(options.native_libs) |
| 256 if libraries: | 294 if libraries: |
| 257 libraries_dir = os.path.dirname(libraries[0]) | 295 libraries_dir = os.path.dirname(libraries[0]) |
| 258 write_ordered_libraries.SetReadelfPath(options.readelf_path) | 296 write_ordered_libraries.SetReadelfPath(options.readelf_path) |
| 259 write_ordered_libraries.SetLibraryDirs([libraries_dir]) | 297 write_ordered_libraries.SetLibraryDirs([libraries_dir]) |
| 260 all_native_library_deps = ( | 298 all_native_library_deps = ( |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 275 build_utils.WriteJson(config, options.build_config, only_if_changed=True) | 313 build_utils.WriteJson(config, options.build_config, only_if_changed=True) |
| 276 | 314 |
| 277 if options.depfile: | 315 if options.depfile: |
| 278 build_utils.WriteDepfile( | 316 build_utils.WriteDepfile( |
| 279 options.depfile, | 317 options.depfile, |
| 280 all_deps_config_paths + build_utils.GetPythonDependencies()) | 318 all_deps_config_paths + build_utils.GetPythonDependencies()) |
| 281 | 319 |
| 282 | 320 |
| 283 if __name__ == '__main__': | 321 if __name__ == '__main__': |
| 284 sys.exit(main(sys.argv[1:])) | 322 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |