1#!/usr/bin/env python3 2# 3# Copyright (C) 2017 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import argparse 19import glob 20import json 21import logging 22import os 23import sys 24 25import utils 26 27 28class GenBuildFile(object): 29 """Generates Android.bp for VNDK snapshot. 30 31 VNDK snapshot directory structure under prebuilts/vndk/v{version}: 32 Android.bp 33 {SNAPSHOT_ARCH}/ 34 Android.bp 35 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ 36 shared/ 37 vndk-core/ 38 (VNDK-core libraries, e.g. libbinder.so) 39 vndk-sp/ 40 (VNDK-SP libraries, e.g. libc++.so) 41 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ 42 shared/ 43 vndk-core/ 44 (VNDK-core libraries, e.g. libbinder.so) 45 vndk-sp/ 46 (VNDK-SP libraries, e.g. libc++.so) 47 binder32/ 48 (This directory is newly introduced in v28 (Android P) to hold 49 prebuilts built for 32-bit binder interface.) 50 Android.bp 51 arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/ 52 ... 53 configs/ 54 (various *.txt configuration files, e.g. ld.config.*.txt) 55 ... (other {SNAPSHOT_ARCH}/ directories) 56 common/ 57 Android.bp 58 NOTICE_FILES/ 59 (license files, e.g. libfoo.so.txt) 60 """ 61 INDENT = ' ' 62 ETC_MODULES = [ 63 'llndk.libraries.txt', 64 'vndksp.libraries.txt', 65 'vndkcore.libraries.txt', 66 'vndkprivate.libraries.txt', 67 'vndkproduct.libraries.txt', 68 ] 69 70 """Some vendor prebuilts reference libprotobuf-cpp-lite.so and 71 libprotobuf-cpp-full.so and expect the 3.0.0-beta3 version. 72 The new version of protobuf will be installed as 73 /vendor/lib64/libprotobuf-cpp-lite-3.9.1.so. The VNDK doesn't 74 help here because we compile old devices against the current 75 branch and not an old VNDK snapshot. We need to continue to 76 provide a vendor libprotobuf-cpp-lite.so until all products in 77 the current branch get updated prebuilts or are obsoleted. 78 79 VENDOR_COMPAT is a dictionary that has VNDK versions as keys and 80 the list of (library name string, shared libs list) as values. 81 """ 82 VENDOR_COMPAT = { 83 28: [ 84 ('libprotobuf-cpp-lite', 85 ['libc++', 'libc', 'libdl', 'liblog', 'libm', 'libz']), 86 ('libprotobuf-cpp-full', 87 ['libc++', 'libc', 'libdl', 'liblog', 'libm', 'libz']), 88 ] 89 } 90 91 def __init__(self, install_dir, vndk_version): 92 """GenBuildFile constructor. 93 94 Args: 95 install_dir: string, absolute path to the prebuilts/vndk/v{version} 96 directory where the build files will be generated. 97 vndk_version: int, VNDK snapshot version (e.g. 30) 98 """ 99 self._install_dir = install_dir 100 self._vndk_version = vndk_version 101 self._etc_paths = self._get_etc_paths() 102 self._snapshot_archs = utils.get_snapshot_archs(install_dir) 103 self._root_bpfile = os.path.join(install_dir, utils.ROOT_BP_PATH) 104 self._common_bpfile = os.path.join(install_dir, utils.COMMON_BP_PATH) 105 self._llndk = self._parse_lib_list( 106 os.path.basename(self._etc_paths['llndk.libraries.txt'])) 107 self._vndk_core = self._parse_lib_list( 108 os.path.basename(self._etc_paths['vndkcore.libraries.txt'])) 109 self._vndk_sp = self._parse_lib_list( 110 os.path.basename(self._etc_paths['vndksp.libraries.txt'])) 111 self._vndk_private = self._parse_lib_list( 112 os.path.basename(self._etc_paths['vndkprivate.libraries.txt'])) 113 self._vndk_product = self._parse_lib_list( 114 os.path.basename(self._etc_paths['vndkproduct.libraries.txt'])) 115 self._modules_with_notice = self._get_modules_with_notice() 116 117 def _get_etc_paths(self): 118 """Returns a map of relative file paths for each ETC module.""" 119 120 etc_paths = dict() 121 for etc_module in self.ETC_MODULES: 122 etc_pattern = '{}*'.format(os.path.splitext(etc_module)[0]) 123 globbed = glob.glob( 124 os.path.join(self._install_dir, utils.CONFIG_DIR_PATH_PATTERN, 125 etc_pattern)) 126 if len(globbed) > 0: 127 rel_etc_path = globbed[0].replace(self._install_dir, '')[1:] 128 etc_paths[etc_module] = rel_etc_path 129 return etc_paths 130 131 def _parse_lib_list(self, txt_filename): 132 """Returns a map of VNDK library lists per VNDK snapshot arch. 133 134 Args: 135 txt_filename: string, name of snapshot config file 136 137 Returns: 138 dict, e.g. {'arm64': ['libfoo.so', 'libbar.so', ...], ...} 139 """ 140 lib_map = dict() 141 for txt_path in utils.find(self._install_dir, [txt_filename]): 142 arch = utils.snapshot_arch_from_path(txt_path) 143 abs_path_of_txt = os.path.join(self._install_dir, txt_path) 144 with open(abs_path_of_txt, 'r') as f: 145 lib_map[arch] = f.read().strip().split('\n') 146 if lib_map[arch] == ['']: 147 lib_map[arch].clear() 148 return lib_map 149 150 def _get_modules_with_notice(self): 151 """Returns a list of modules that have associated notice files. """ 152 notice_paths = glob.glob( 153 os.path.join(self._install_dir, utils.NOTICE_FILES_DIR_PATH, 154 '*.txt')) 155 return sorted(os.path.splitext(os.path.basename(p))[0] for p in notice_paths) 156 157 def generate_root_android_bp(self): 158 """Autogenerates Android.bp.""" 159 160 logging.info('Generating Android.bp for snapshot v{}'.format( 161 self._vndk_version)) 162 prebuilt_buildrules = [] 163 for prebuilt in self.ETC_MODULES: 164 prebuilt_buildrules.append(self._gen_etc_prebuilt(prebuilt)) 165 166 if self._vndk_version in self.VENDOR_COMPAT: 167 prebuilt_buildrules.append('// Defining prebuilt libraries ' 168 'for the compatibility of old vendor modules') 169 for vendor_compat_lib_info in self.VENDOR_COMPAT[self._vndk_version]: 170 prebuilt_buildrules.append( 171 self._gen_prebuilt_library_shared(vendor_compat_lib_info)) 172 173 with open(self._root_bpfile, 'w') as bpfile: 174 bpfile.write(self._gen_autogen_msg('/')) 175 bpfile.write('\n') 176 bpfile.write('\n'.join(prebuilt_buildrules)) 177 bpfile.write('\n') 178 179 logging.info('Successfully generated {}'.format(self._root_bpfile)) 180 181 def generate_common_android_bp(self): 182 """Autogenerates common/Android.bp.""" 183 184 logging.info('Generating common/Android.bp for snapshot v{}'.format( 185 self._vndk_version)) 186 with open(self._common_bpfile, 'w') as bpfile: 187 bpfile.write(self._gen_autogen_msg('/')) 188 for module in self._modules_with_notice: 189 bpfile.write('\n') 190 bpfile.write(self._gen_notice_filegroup(module)) 191 192 def generate_android_bp(self): 193 """Autogenerates Android.bp.""" 194 195 def gen_for_variant(arch, is_binder32=False): 196 """Generates Android.bp file for specified VNDK snapshot variant. 197 198 A VNDK snapshot variant is defined by the TARGET_ARCH and binder 199 bitness. Example snapshot variants: 200 vndk_v{ver}_arm: {arch: arm, binder: 64-bit} 201 vndk_v{ver}_arm_binder32: {arch: arm, binder: 32-bit} 202 203 Args: 204 arch: string, VNDK snapshot arch (e.g. 'arm64') 205 is_binder32: bool, True if binder interface is 32-bit 206 """ 207 binder32_suffix = '_{}'.format( 208 utils.BINDER32) if is_binder32 else '' 209 logging.info('Generating Android.bp for vndk_v{}_{}{}'.format( 210 self._vndk_version, arch, binder32_suffix)) 211 212 src_root = os.path.join(self._install_dir, arch) 213 module_names_txt = os.path.join( 214 src_root, "configs", "module_names.txt") 215 module_names = dict() 216 try: 217 with open(module_names_txt, 'r') as f: 218 # Remove empty lines from module_names_txt 219 module_list = filter(None, f.read().split('\n')) 220 for module in module_list: 221 lib, name = module.split(' ') 222 module_names[lib] = name 223 except IOError: 224 # If module_names.txt doesn't exist, ignore it and parse 225 # module names out from .so filenames. (old snapshot) 226 pass 227 228 variant_subpath = arch 229 if is_binder32: 230 variant_subpath = os.path.join(arch, utils.BINDER32) 231 variant_path = os.path.join(self._install_dir, variant_subpath) 232 bpfile_path = os.path.join(variant_path, 'Android.bp') 233 234 vndk_core_buildrules = self._gen_vndk_shared_prebuilts( 235 self._vndk_core[arch], 236 arch, 237 is_llndk=False, 238 is_vndk_sp=False, 239 is_binder32=is_binder32, 240 module_names=module_names) 241 vndk_sp_buildrules = self._gen_vndk_shared_prebuilts( 242 self._vndk_sp[arch], 243 arch, 244 is_llndk=False, 245 is_vndk_sp=True, 246 is_binder32=is_binder32, 247 module_names=module_names) 248 include_llndk = self._vndk_version > 30 249 if include_llndk: 250 llndk_buildrules = self._gen_vndk_shared_prebuilts( 251 self._llndk[arch], 252 arch, 253 is_llndk=True, 254 is_vndk_sp=False, 255 is_binder32=is_binder32, 256 module_names=module_names) 257 258 with open(bpfile_path, 'w') as bpfile: 259 bpfile.write(self._gen_autogen_msg('/')) 260 bpfile.write('\n') 261 bpfile.write('\n'.join(vndk_core_buildrules)) 262 bpfile.write('\n') 263 bpfile.write('\n'.join(vndk_sp_buildrules)) 264 if include_llndk: 265 bpfile.write('\n') 266 bpfile.write('\n'.join(llndk_buildrules)) 267 268 variant_include_path = os.path.join(variant_path, 'include') 269 include_path = os.path.join(self._install_dir, arch, 'include') 270 if os.path.isdir(include_path) and variant_include_path != include_path: 271 os.symlink(os.path.relpath(include_path, variant_path), 272 variant_include_path) 273 274 logging.info('Successfully generated {}'.format(bpfile_path)) 275 276 for arch in self._snapshot_archs: 277 if os.path.isdir( 278 os.path.join(self._install_dir, arch, utils.BINDER32)): 279 gen_for_variant(arch, is_binder32=True) 280 gen_for_variant(arch) 281 282 def _gen_autogen_msg(self, comment_char): 283 return ('{0}{0} THIS FILE IS AUTOGENERATED BY ' 284 'development/vndk/snapshot/gen_buildfiles.py\n' 285 '{0}{0} DO NOT EDIT\n'.format(comment_char)) 286 287 def _get_versioned_name(self, 288 prebuilt, 289 arch, 290 is_etc=False, 291 is_binder32=False, 292 module_names=None): 293 """Returns the VNDK version-specific module name for a given prebuilt. 294 295 The VNDK version-specific module name is defined as follows: 296 For a VNDK shared lib: 'libfoo.so' 297 if binder is 32-bit: 298 'libfoo.vndk.{version}.{arch}.binder32.vendor' 299 else: 300 'libfoo.vndk.{version}.{arch}.vendor' 301 For an ETC module: 'foo.txt' -> 'foo.{version}.txt' 302 303 Args: 304 prebuilt: string, name of the prebuilt object 305 arch: string, VNDK snapshot arch (e.g. 'arm64') 306 is_etc: bool, True if the LOCAL_MODULE_CLASS of prebuilt is 'ETC' 307 is_binder32: bool, True if binder interface is 32-bit 308 module_names: dict, module names for given prebuilts 309 """ 310 if is_etc: 311 name, ext = os.path.splitext(prebuilt) 312 versioned_name = '{}.{}{}'.format(name, self._vndk_version, ext) 313 else: 314 module_names = module_names or dict() 315 if prebuilt in module_names: 316 name = module_names[prebuilt] 317 else: 318 name = os.path.splitext(prebuilt)[0] 319 binder_suffix = '.{}'.format(utils.BINDER32) if is_binder32 else '' 320 versioned_name = '{}.vndk.{}.{}{}.vendor'.format( 321 name, self._vndk_version, arch, binder_suffix) 322 323 return versioned_name 324 325 def _gen_etc_prebuilt(self, prebuilt): 326 """Generates build rule for an ETC prebuilt. 327 328 Args: 329 prebuilt: string, name of ETC prebuilt object 330 """ 331 etc_path = self._etc_paths[prebuilt] 332 etc_sub_path = etc_path[etc_path.index('/') + 1:] 333 334 prebuilt_etc = ('prebuilt_etc {{\n' 335 '{ind}name: "{versioned_name}",\n' 336 '{ind}target: {{\n'.format( 337 ind=self.INDENT, 338 versioned_name=self._get_versioned_name( 339 prebuilt, None, is_etc=True))) 340 for arch in self._snapshot_archs: 341 prebuilt_etc += ('{ind}{ind}android_{arch}: {{\n' 342 '{ind}{ind}{ind}src: "{arch}/{etc_sub_path}",\n' 343 '{ind}{ind}}},\n'.format( 344 ind=self.INDENT, 345 arch=arch, 346 etc_sub_path=etc_sub_path)) 347 prebuilt_etc += ('{ind}}},\n' 348 '}}\n'.format(ind=self.INDENT)) 349 return prebuilt_etc 350 351 def _gen_prebuilt_library_shared(self, prebuilt_lib_info): 352 """Generates cc_prebuilt_library_shared modules for the old vendor 353 compatibility. 354 355 Some vendor modules still require old version of libraries that is not 356 available from the current source tree. To provide the old copy of the 357 libraries, use the vndk snapshot. 358 359 Args: 360 prebuilt_lib_info: pair of (string, list of strings), name of the 361 prebuilt library and the list of shared libs for it. 362 """ 363 lib_name = prebuilt_lib_info[0] 364 shared_libs = prebuilt_lib_info[1] 365 366 shared_libs_prop = '' 367 if shared_libs: 368 shared_libs_prop = ('{ind}shared_libs: [\n'.format(ind=self.INDENT)) 369 for lib in shared_libs: 370 shared_libs_prop += ('{ind}{ind}"{lib}",\n'.format( 371 ind=self.INDENT, lib=lib)) 372 shared_libs_prop += ('{ind}],\n'.format(ind=self.INDENT)) 373 374 cc_prebuilt_libraries = ('cc_prebuilt_library_shared {{\n' 375 '{ind}name: "{name}-vendorcompat",\n' 376 '{ind}stem: "{name}",\n' 377 '{ind}vendor: true,\n' 378 '{ind}// These are already stripped, and ' 379 'restripping them just issues diagnostics.\n' 380 '{ind}strip: {{\n' 381 '{ind}{ind}none: true,\n' 382 '{ind}}},\n' 383 '{shared_libs}' 384 '{ind}target: {{\n'.format( 385 ind=self.INDENT, 386 name=lib_name, 387 shared_libs=shared_libs_prop)) 388 src_paths = utils.find(self._install_dir, [lib_name+'.so']) 389 for src in src_paths: 390 dirs = src.split(os.path.sep) 391 if len(dirs) < 3 or not dirs[1].startswith('arch-{}-'.format(dirs[0])): 392 continue 393 cc_prebuilt_libraries += ('{ind}{ind}android_{arch}: {{\n' 394 '{ind}{ind}{ind}srcs: ["{src}"],\n' 395 '{ind}{ind}}},\n'.format( 396 ind=self.INDENT, arch=dirs[0], src=src)) 397 cc_prebuilt_libraries += ('{ind}}},\n' 398 '}}\n'.format(ind=self.INDENT)) 399 return cc_prebuilt_libraries 400 401 def _gen_notice_filegroup(self, module): 402 """Generates a notice filegroup build rule for a given module. 403 404 Args: 405 notice: string, module name 406 """ 407 return ('filegroup {{\n' 408 '{ind}name: "{filegroup_name}",\n' 409 '{ind}srcs: ["{notice_dir}/{module}.txt"],\n' 410 '}}\n'.format( 411 ind=self.INDENT, 412 filegroup_name=self._get_notice_filegroup_name(module), 413 module=module, 414 notice_dir=utils.NOTICE_FILES_DIR_NAME)) 415 416 def _get_notice_filegroup_name(self, module): 417 """ Gets a notice filegroup module name for a given module. 418 419 Args: 420 notice: string, module name. 421 """ 422 return 'vndk-v{ver}-{module}-notice'.format( 423 ver=self._vndk_version, module=module) 424 425 def _gen_vndk_shared_prebuilts(self, 426 prebuilts, 427 arch, 428 is_llndk, 429 is_vndk_sp, 430 is_binder32, 431 module_names): 432 """Returns list of build rules for given prebuilts. 433 434 Args: 435 prebuilts: list of VNDK shared prebuilts 436 arch: string, VNDK snapshot arch (e.g. 'arm64') 437 is_llndk: bool, True if the prebuilts are LLNDK stubs 438 is_vndk_sp: bool, True if prebuilts are VNDK_SP libs 439 is_binder32: bool, True if binder interface is 32-bit 440 module_names: dict, module names for given prebuilts 441 """ 442 443 build_rules = [] 444 for prebuilt in prebuilts: 445 bp_module = self._gen_vndk_shared_prebuilt( 446 prebuilt, 447 arch, 448 is_llndk=is_llndk, 449 is_vndk_sp=is_vndk_sp, 450 is_binder32=is_binder32, 451 module_names=module_names) 452 if bp_module: 453 build_rules.append(bp_module) 454 return build_rules 455 456 def _gen_vndk_shared_prebuilt(self, 457 prebuilt, 458 arch, 459 is_llndk, 460 is_vndk_sp, 461 is_binder32, 462 module_names): 463 """Returns build rule for given prebuilt, or an empty string if the 464 prebuilt is invalid (e.g. srcs doesn't exist). 465 466 Args: 467 prebuilt: string, name of prebuilt object 468 arch: string, VNDK snapshot arch (e.g. 'arm64') 469 is_llndk: bool, True if prebuilt is a LLNDK stub 470 is_vndk_sp: bool, True if prebuilt is a VNDK_SP lib 471 is_binder32: bool, True if binder interface is 32-bit 472 module_names: dict, module names for given prebuilts 473 """ 474 475 def get_notice_file(prebuilt): 476 """Returns build rule for notice file (attribute 'notice'). 477 478 Args: 479 prebuilt: string, name of prebuilt object 480 """ 481 notice = '' 482 if prebuilt in self._modules_with_notice: 483 notice = '{ind}notice: ":{notice_filegroup}",\n'.format( 484 ind=self.INDENT, 485 notice_filegroup=self._get_notice_filegroup_name(prebuilt)) 486 return notice 487 488 def get_arch_props(prebuilt, arch, src_paths): 489 """Returns build rule for arch specific srcs. 490 491 e.g., 492 arch: { 493 arm: { 494 export_include_dirs: ["..."], 495 export_system_include_dirs: ["..."], 496 export_flags: ["..."], 497 relative_install_path: "...", 498 srcs: ["..."] 499 }, 500 arm64: { 501 export_include_dirs: ["..."], 502 export_system_include_dirs: ["..."], 503 export_flags: ["..."], 504 relative_install_path: "...", 505 srcs: ["..."] 506 }, 507 } 508 509 Args: 510 prebuilt: string, name of prebuilt object 511 arch: string, VNDK snapshot arch (e.g. 'arm64') 512 src_paths: list of string paths, prebuilt source paths 513 """ 514 arch_props = '{ind}arch: {{\n'.format(ind=self.INDENT) 515 516 def list_to_prop_value(l, name): 517 if len(l) == 0: 518 return '' 519 dirs=',\n{ind}{ind}{ind}{ind}'.format( 520 ind=self.INDENT).join(['"%s"' % d for d in l]) 521 return ('{ind}{ind}{ind}{name}: [\n' 522 '{ind}{ind}{ind}{ind}{dirs},\n' 523 '{ind}{ind}{ind}],\n'.format( 524 ind=self.INDENT, 525 dirs=dirs, 526 name=name)) 527 528 for src in sorted(src_paths): 529 include_dirs = '' 530 system_include_dirs = '' 531 flags = '' 532 relative_install_path = '' 533 prop_path = os.path.join(src_root, src+'.json') 534 props = dict() 535 try: 536 with open(prop_path, 'r') as f: 537 props = json.loads(f.read()) 538 os.unlink(prop_path) 539 except: 540 # TODO(b/70312118): Parse from soong build system 541 if prebuilt == 'android.hidl.memory@1.0-impl.so': 542 props['RelativeInstallPath'] = 'hw' 543 if 'ExportedDirs' in props: 544 l = ['include/%s' % d for d in props['ExportedDirs']] 545 include_dirs = list_to_prop_value(l, 'export_include_dirs') 546 if 'ExportedSystemDirs' in props: 547 l = ['include/%s' % d for d in props['ExportedSystemDirs']] 548 system_include_dirs = list_to_prop_value(l, 'export_system_include_dirs') 549 if 'ExportedFlags' in props: 550 flags = list_to_prop_value(props['ExportedFlags'], 'export_flags') 551 if 'RelativeInstallPath' in props: 552 relative_install_path = ('{ind}{ind}{ind}' 553 'relative_install_path: "{path}",\n').format( 554 ind=self.INDENT, 555 path=props['RelativeInstallPath']) 556 557 arch_props += ('{ind}{ind}{arch}: {{\n' 558 '{include_dirs}' 559 '{system_include_dirs}' 560 '{flags}' 561 '{relative_install_path}' 562 '{ind}{ind}{ind}srcs: ["{src}"],\n' 563 '{ind}{ind}}},\n').format( 564 ind=self.INDENT, 565 arch=utils.prebuilt_arch_from_path( 566 os.path.join(arch, src)), 567 include_dirs=include_dirs, 568 system_include_dirs=system_include_dirs, 569 flags=flags, 570 relative_install_path=relative_install_path, 571 src=src) 572 arch_props += '{ind}}},\n'.format(ind=self.INDENT) 573 return arch_props 574 575 src_root = os.path.join(self._install_dir, arch) 576 if is_binder32: 577 src_root = os.path.join(src_root, utils.BINDER32) 578 579 src_paths = utils.find(src_root, [prebuilt]) 580 # filter out paths under 'binder32' subdirectory 581 src_paths = list(filter(lambda src: not src.startswith(utils.BINDER32), 582 src_paths)) 583 # This prebuilt is invalid if no srcs are found. 584 if not src_paths: 585 logging.info('No srcs found for {}; skipping'.format(prebuilt)) 586 return "" 587 588 if prebuilt in module_names: 589 name = module_names[prebuilt] 590 else: 591 name = os.path.splitext(prebuilt)[0] 592 593 product_available = '' 594 # if vndkproduct.libraries.txt is empty, make the VNDKs available to product by default. 595 if not self._vndk_product[arch] or prebuilt in self._vndk_product[arch] or is_llndk: 596 product_available = '{ind}product_available: true,\n'.format( 597 ind=self.INDENT) 598 599 vndk_props = '' 600 if not is_llndk: 601 vndk_sp = '' 602 if is_vndk_sp: 603 vndk_sp = '{ind}{ind}support_system_process: true,\n'.format( 604 ind=self.INDENT) 605 606 vndk_private = '' 607 if prebuilt in self._vndk_private[arch]: 608 vndk_private = '{ind}{ind}private: true,\n'.format( 609 ind=self.INDENT) 610 611 vndk_props = ('{ind}vndk: {{\n' 612 '{ind}{ind}enabled: true,\n' 613 '{vndk_sp}' 614 '{vndk_private}' 615 '{ind}}},\n'.format( 616 ind=self.INDENT, 617 product_available=product_available, 618 vndk_sp=vndk_sp, 619 vndk_private=vndk_private)) 620 621 notice = get_notice_file(prebuilt) 622 arch_props = get_arch_props(prebuilt, arch, src_paths) 623 624 binder32bit = '' 625 if is_binder32: 626 binder32bit = '{ind}binder32bit: true,\n'.format(ind=self.INDENT) 627 628 return ('vndk_prebuilt_shared {{\n' 629 '{ind}name: "{name}",\n' 630 '{ind}version: "{ver}",\n' 631 '{ind}target_arch: "{target_arch}",\n' 632 '{binder32bit}' 633 '{ind}vendor_available: true,\n' 634 '{product_available}' 635 '{vndk_props}' 636 '{notice}' 637 '{arch_props}' 638 '}}\n'.format( 639 ind=self.INDENT, 640 name=name, 641 ver=self._vndk_version, 642 target_arch=arch, 643 binder32bit=binder32bit, 644 product_available=product_available, 645 vndk_props=vndk_props, 646 notice=notice, 647 arch_props=arch_props)) 648 649 650def get_args(): 651 parser = argparse.ArgumentParser() 652 parser.add_argument( 653 'vndk_version', 654 type=utils.vndk_version_int, 655 help='VNDK snapshot version to install, e.g. "{}".'.format( 656 utils.MINIMUM_VNDK_VERSION)) 657 parser.add_argument( 658 '-v', 659 '--verbose', 660 action='count', 661 default=0, 662 help='Increase output verbosity, e.g. "-v", "-vv".') 663 return parser.parse_args() 664 665 666def main(): 667 """For local testing purposes. 668 669 Note: VNDK snapshot must be already installed under 670 prebuilts/vndk/v{version}. 671 """ 672 ANDROID_BUILD_TOP = utils.get_android_build_top() 673 PREBUILTS_VNDK_DIR = utils.join_realpath(ANDROID_BUILD_TOP, 674 'prebuilts/vndk') 675 676 args = get_args() 677 vndk_version = args.vndk_version 678 install_dir = os.path.join(PREBUILTS_VNDK_DIR, 'v{}'.format(vndk_version)) 679 if not os.path.isdir(install_dir): 680 raise ValueError( 681 'Please provide valid VNDK version. {} does not exist.' 682 .format(install_dir)) 683 utils.set_logging_config(args.verbose) 684 685 buildfile_generator = GenBuildFile(install_dir, vndk_version) 686 buildfile_generator.generate_root_android_bp() 687 buildfile_generator.generate_common_android_bp() 688 buildfile_generator.generate_android_bp() 689 690 logging.info('Done.') 691 692 693if __name__ == '__main__': 694 main() 695