| 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 |
| 11 things like: the javac classpath, the list of android resources dependencies, | 11 things like: the javac classpath, the list of android resources dependencies, |
| 12 etc. It also includes the information needed to create the build_config for | 12 etc. It also includes the information needed to create the build_config for |
| 13 other targets that depend on that one. | 13 other targets that depend on that one. |
| 14 | 14 |
| 15 Android build scripts should not refer to the build_config directly, and the | 15 Android build scripts should not refer to the build_config directly, and the |
| 16 build specification should instead pass information in using the special | 16 build specification should instead pass information in using the special |
| 17 file-arg syntax (see build_utils.py:ExpandFileArgs). That syntax allows passing | 17 file-arg syntax (see build_utils.py:ExpandFileArgs). That syntax allows passing |
| 18 of values in a json dict in a file and looks like this: | 18 of values in a json dict in a file and looks like this: |
| 19 --python-arg=@FileArg(build_config_path:javac:classpath) | 19 --python-arg=@FileArg(build_config_path:javac:classpath) |
| 20 | 20 |
| 21 Note: If paths to input files are passed in this way, it is important that: | 21 Note: If paths to input files are passed in this way, it is important that: |
| 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 itertools |
| 29 import optparse | 30 import optparse |
| 30 import os | 31 import os |
| 31 import sys | 32 import sys |
| 32 import xml.dom.minidom | 33 import xml.dom.minidom |
| 33 | 34 |
| 34 from util import build_utils | 35 from util import build_utils |
| 35 from util import md5_check | 36 from util import md5_check |
| 36 | 37 |
| 37 import write_ordered_libraries | 38 import write_ordered_libraries |
| 38 | 39 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 102 |
| 102 def Direct(self, wanted_type=None): | 103 def Direct(self, wanted_type=None): |
| 103 if wanted_type is None: | 104 if wanted_type is None: |
| 104 return self.direct_deps_configs | 105 return self.direct_deps_configs |
| 105 return DepsOfType(wanted_type, self.direct_deps_configs) | 106 return DepsOfType(wanted_type, self.direct_deps_configs) |
| 106 | 107 |
| 107 def AllConfigPaths(self): | 108 def AllConfigPaths(self): |
| 108 return self.all_deps_config_paths | 109 return self.all_deps_config_paths |
| 109 | 110 |
| 110 | 111 |
| 112 def _MergeAssets(all_assets): |
| 113 """Merges all assets from the given deps. |
| 114 |
| 115 Returns: |
| 116 A tuple of lists: (compressed, uncompressed) |
| 117 Each tuple entry is a list of "srcPath:zipPath", where ":zipPath" is |
| 118 optional. |
| 119 """ |
| 120 compressed = {} |
| 121 uncompressed = {} |
| 122 for asset_dep in all_assets: |
| 123 entry = asset_dep['assets'] |
| 124 disable_compression = entry.get('disable_compression', False) |
| 125 dest_map = uncompressed if disable_compression else compressed |
| 126 other_map = compressed if disable_compression else uncompressed |
| 127 outputs = entry.get('outputs', []) |
| 128 for src, dest in itertools.izip_longest(entry['paths'], outputs): |
| 129 if not dest: |
| 130 dest = os.path.basename(src) |
| 131 # Merge so that each path shows up in only one of the lists, and that |
| 132 # deps of the same target override previous ones. |
| 133 other_map.pop(dest, 0) |
| 134 dest_map[dest] = src |
| 135 |
| 136 def create_list(asset_map): |
| 137 ret = [] |
| 138 for dest, src in asset_map.iteritems(): |
| 139 ret.append(src) |
| 140 if dest != os.path.basename(src): |
| 141 ret[-1] += ':%s' % dest |
| 142 # Sort to ensure deterministic ordering. |
| 143 ret.sort() |
| 144 return ret |
| 145 |
| 146 return create_list(compressed), create_list(uncompressed) |
| 147 |
| 148 |
| 111 def main(argv): | 149 def main(argv): |
| 112 parser = optparse.OptionParser() | 150 parser = optparse.OptionParser() |
| 113 build_utils.AddDepfileOption(parser) | 151 build_utils.AddDepfileOption(parser) |
| 114 parser.add_option('--build-config', help='Path to build_config output.') | 152 parser.add_option('--build-config', help='Path to build_config output.') |
| 115 parser.add_option( | 153 parser.add_option( |
| 116 '--type', | 154 '--type', |
| 117 help='Type of this target (e.g. android_library).') | 155 help='Type of this target (e.g. android_library).') |
| 118 parser.add_option( | 156 parser.add_option( |
| 119 '--possible-deps-configs', | 157 '--possible-deps-configs', |
| 120 help='List of paths for dependency\'s build_config files. Some ' | 158 help='List of paths for dependency\'s build_config files. Some ' |
| 121 'dependencies may not write build_config files. Missing build_config ' | 159 'dependencies may not write build_config files. Missing build_config ' |
| 122 'files are handled differently based on the type of this target.') | 160 'files are handled differently based on the type of this target.') |
| 123 | 161 |
| 124 # android_resources options | 162 # android_resources options |
| 125 parser.add_option('--srcjar', help='Path to target\'s resources srcjar.') | 163 parser.add_option('--srcjar', help='Path to target\'s resources srcjar.') |
| 126 parser.add_option('--resources-zip', help='Path to target\'s resources zip.') | 164 parser.add_option('--resources-zip', help='Path to target\'s resources zip.') |
| 127 parser.add_option('--r-text', help='Path to target\'s R.txt file.') | 165 parser.add_option('--r-text', help='Path to target\'s R.txt file.') |
| 128 parser.add_option('--package-name', | 166 parser.add_option('--package-name', |
| 129 help='Java package name for these resources.') | 167 help='Java package name for these resources.') |
| 130 parser.add_option('--android-manifest', help='Path to android manifest.') | 168 parser.add_option('--android-manifest', help='Path to android manifest.') |
| 131 | 169 |
| 170 # android_assets options |
| 171 parser.add_option('--assets', help='List of asset\'s sources.') |
| 172 parser.add_option('--asset-outputs', help='List of asset outputs.') |
| 173 parser.add_option('--disable-asset-compression', action='store_true', |
| 174 help='Whether to disable asset compression.') |
| 175 |
| 132 # java library options | 176 # java library options |
| 133 parser.add_option('--jar-path', help='Path to target\'s jar output.') | 177 parser.add_option('--jar-path', help='Path to target\'s jar output.') |
| 134 parser.add_option('--supports-android', action='store_true', | 178 parser.add_option('--supports-android', action='store_true', |
| 135 help='Whether this library supports running on the Android platform.') | 179 help='Whether this library supports running on the Android platform.') |
| 136 parser.add_option('--requires-android', action='store_true', | 180 parser.add_option('--requires-android', action='store_true', |
| 137 help='Whether this library requires running on the Android platform.') | 181 help='Whether this library requires running on the Android platform.') |
| 138 parser.add_option('--bypass-platform-checks', action='store_true', | 182 parser.add_option('--bypass-platform-checks', action='store_true', |
| 139 help='Bypass checks for support/require Android platform.') | 183 help='Bypass checks for support/require Android platform.') |
| 140 | 184 |
| 141 # android library options | 185 # android library options |
| 142 parser.add_option('--dex-path', help='Path to target\'s dex output.') | 186 parser.add_option('--dex-path', help='Path to target\'s dex output.') |
| 143 | 187 |
| 144 # native library options | 188 # native library options |
| 145 parser.add_option('--native-libs', help='List of top-level native libs.') | 189 parser.add_option('--native-libs', help='List of top-level native libs.') |
| 146 parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.') | 190 parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.') |
| 147 | 191 |
| 148 parser.add_option('--tested-apk-config', | 192 parser.add_option('--tested-apk-config', |
| 149 help='Path to the build config of the tested apk (for an instrumentation ' | 193 help='Path to the build config of the tested apk (for an instrumentation ' |
| 150 'test apk).') | 194 'test apk).') |
| 151 | 195 |
| 152 options, args = parser.parse_args(argv) | 196 options, args = parser.parse_args(argv) |
| 153 | 197 |
| 154 if args: | 198 if args: |
| 155 parser.error('No positional arguments should be given.') | 199 parser.error('No positional arguments should be given.') |
| 156 | 200 |
| 157 | 201 required_options_map = { |
| 158 if not options.type in [ | 202 'java_library': ['build_config', 'jar_path'], |
| 159 'java_library', 'android_resources', 'android_apk', 'deps_dex']: | 203 'android_assets': ['build_config', 'assets'], |
| 204 'android_resources': ['build_config', 'resources_zip'], |
| 205 'android_apk': ['build_config', 'jar_path', 'dex_path', 'resources_zip'], |
| 206 'deps_dex': ['build_config', 'dex_path'] |
| 207 } |
| 208 required_options = required_options_map.get(options.type) |
| 209 if not required_options: |
| 160 raise Exception('Unknown type: <%s>' % options.type) | 210 raise Exception('Unknown type: <%s>' % options.type) |
| 161 | 211 |
| 162 required_options = ['build_config'] + { | |
| 163 'java_library': ['jar_path'], | |
| 164 'android_resources': ['resources_zip'], | |
| 165 'android_apk': ['jar_path', 'dex_path', 'resources_zip'], | |
| 166 'deps_dex': ['dex_path'] | |
| 167 }[options.type] | |
| 168 | |
| 169 if options.native_libs: | 212 if options.native_libs: |
| 170 required_options.append('readelf_path') | 213 required_options.append('readelf_path') |
| 171 | 214 |
| 172 build_utils.CheckOptions(options, parser, required_options) | 215 build_utils.CheckOptions(options, parser, required_options) |
| 173 | 216 |
| 174 if options.type == 'java_library': | 217 if options.type == 'java_library': |
| 175 if options.supports_android and not options.dex_path: | 218 if options.supports_android and not options.dex_path: |
| 176 raise Exception('java_library that supports Android requires a dex path.') | 219 raise Exception('java_library that supports Android requires a dex path.') |
| 177 | 220 |
| 178 if options.requires_android and not options.supports_android: | 221 if options.requires_android and not options.supports_android: |
| 179 raise Exception( | 222 raise Exception( |
| 180 '--supports-android is required when using --requires-android') | 223 '--supports-android is required when using --requires-android') |
| 181 | 224 |
| 182 possible_deps_config_paths = build_utils.ParseGypList( | 225 possible_deps_config_paths = build_utils.ParseGypList( |
| 183 options.possible_deps_configs) | 226 options.possible_deps_configs) |
| 184 | 227 |
| 185 allow_unknown_deps = (options.type == 'android_apk' or | 228 allow_unknown_deps = (options.type in |
| 186 options.type == 'android_resources') | 229 ('android_apk', 'android_assets', 'android_resources')) |
| 187 unknown_deps = [ | 230 unknown_deps = [ |
| 188 c for c in possible_deps_config_paths if not os.path.exists(c)] | 231 c for c in possible_deps_config_paths if not os.path.exists(c)] |
| 189 if unknown_deps and not allow_unknown_deps: | 232 if unknown_deps and not allow_unknown_deps: |
| 190 raise Exception('Unknown deps: ' + str(unknown_deps)) | 233 raise Exception('Unknown deps: ' + str(unknown_deps)) |
| 191 | 234 |
| 192 direct_deps_config_paths = [ | 235 direct_deps_config_paths = [ |
| 193 c for c in possible_deps_config_paths if not c in unknown_deps] | 236 c for c in possible_deps_config_paths if not c in unknown_deps] |
| 194 | 237 |
| 195 deps = Deps(direct_deps_config_paths) | 238 deps = Deps(direct_deps_config_paths) |
| 196 direct_library_deps = deps.Direct('java_library') | 239 direct_library_deps = deps.Direct('java_library') |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 # srcjar_deps). A resource's srcjar contains the R.java file for those | 298 # srcjar_deps). A resource's srcjar contains the R.java file for those |
| 256 # resources, and (like Android's default build system) we allow a library to | 299 # resources, and (like Android's default build system) we allow a library to |
| 257 # refer to the resources in any of its dependents. | 300 # refer to the resources in any of its dependents. |
| 258 config['javac']['srcjars'] = [ | 301 config['javac']['srcjars'] = [ |
| 259 c['srcjar'] for c in direct_resources_deps if 'srcjar' in c] | 302 c['srcjar'] for c in direct_resources_deps if 'srcjar' in c] |
| 260 | 303 |
| 261 if options.type == 'android_apk': | 304 if options.type == 'android_apk': |
| 262 # Apks will get their resources srcjar explicitly passed to the java step. | 305 # Apks will get their resources srcjar explicitly passed to the java step. |
| 263 config['javac']['srcjars'] = [] | 306 config['javac']['srcjars'] = [] |
| 264 | 307 |
| 308 if options.type == 'android_assets': |
| 309 deps_info['assets'] = { |
| 310 'paths': build_utils.ParseGypList(options.assets), |
| 311 } |
| 312 if options.disable_asset_compression: |
| 313 deps_info['assets']['disable_compression'] = True |
| 314 if options.asset_outputs: |
| 315 deps_info['assets']['outputs'] = ( |
| 316 build_utils.ParseGypList(options.asset_outputs)) |
| 317 |
| 265 if options.type == 'android_resources': | 318 if options.type == 'android_resources': |
| 266 deps_info['resources_zip'] = options.resources_zip | 319 deps_info['resources_zip'] = options.resources_zip |
| 267 if options.srcjar: | 320 if options.srcjar: |
| 268 deps_info['srcjar'] = options.srcjar | 321 deps_info['srcjar'] = options.srcjar |
| 269 if options.android_manifest: | 322 if options.android_manifest: |
| 270 manifest = AndroidManifest(options.android_manifest) | 323 manifest = AndroidManifest(options.android_manifest) |
| 271 deps_info['package_name'] = manifest.GetPackageName() | 324 deps_info['package_name'] = manifest.GetPackageName() |
| 272 if options.package_name: | 325 if options.package_name: |
| 273 deps_info['package_name'] = options.package_name | 326 deps_info['package_name'] = options.package_name |
| 274 if options.r_text: | 327 if options.r_text: |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 if not library_paths: | 404 if not library_paths: |
| 352 prev_config = build_utils.ReadJson(options.build_config) | 405 prev_config = build_utils.ReadJson(options.build_config) |
| 353 java_libraries_list_holder[0] = ( | 406 java_libraries_list_holder[0] = ( |
| 354 prev_config['native']['java_libraries_list']) | 407 prev_config['native']['java_libraries_list']) |
| 355 library_paths.extend(prev_config['native']['libraries']) | 408 library_paths.extend(prev_config['native']['libraries']) |
| 356 | 409 |
| 357 config['native'] = { | 410 config['native'] = { |
| 358 'libraries': library_paths, | 411 'libraries': library_paths, |
| 359 'java_libraries_list': java_libraries_list_holder[0], | 412 'java_libraries_list': java_libraries_list_holder[0], |
| 360 } | 413 } |
| 414 config['assets'], config['uncompressed_assets'] = ( |
| 415 _MergeAssets(deps.All('android_assets'))) |
| 361 | 416 |
| 362 build_utils.WriteJson(config, options.build_config, only_if_changed=True) | 417 build_utils.WriteJson(config, options.build_config, only_if_changed=True) |
| 363 | 418 |
| 364 if options.depfile: | 419 if options.depfile: |
| 365 build_utils.WriteDepfile( | 420 build_utils.WriteDepfile( |
| 366 options.depfile, | 421 options.depfile, |
| 367 deps.AllConfigPaths() + build_utils.GetPythonDependencies()) | 422 deps.AllConfigPaths() + build_utils.GetPythonDependencies()) |
| 368 | 423 |
| 369 | 424 |
| 370 if __name__ == '__main__': | 425 if __name__ == '__main__': |
| 371 sys.exit(main(sys.argv[1:])) | 426 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |