Daniel Norman | bfc51ef | 2019-07-24 14:34:54 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright (C) 2019 The Android Open Source Project |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 6 | # use this file except in compliance with the License. You may obtain a copy of |
| 7 | # 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, WITHOUT |
| 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 14 | # License for the specific language governing permissions and limitations under |
| 15 | # the License. |
| 16 | # |
| 17 | """Merges two non-dist partial builds together. |
| 18 | |
| 19 | Given two partial builds, a framework build and a vendor build, merge the builds |
| 20 | together so that the images can be flashed using 'fastboot flashall'. |
| 21 | |
| 22 | To support both DAP and non-DAP vendor builds with a single framework partial |
| 23 | build, the framework partial build should always be built with DAP enabled. The |
| 24 | vendor partial build determines whether the merged result supports DAP. |
| 25 | |
| 26 | This script does not require builds to be built with 'make dist'. |
| 27 | This script assumes that images other than super_empty.img do not require |
| 28 | regeneration, including vbmeta images. |
| 29 | TODO(b/137853921): Add support for regenerating vbmeta images. |
| 30 | |
| 31 | Usage: merge_builds.py [args] |
| 32 | |
| 33 | --framework_images comma_separated_image_list |
| 34 | Comma-separated list of image names that should come from the framework |
| 35 | build. |
| 36 | |
| 37 | --product_out_framework product_out_framework_path |
| 38 | Path to out/target/product/<framework build>. |
| 39 | |
| 40 | --product_out_vendor product_out_vendor_path |
| 41 | Path to out/target/product/<vendor build>. |
| 42 | """ |
| 43 | from __future__ import print_function |
| 44 | |
| 45 | import logging |
| 46 | import os |
| 47 | import sys |
| 48 | |
| 49 | import build_super_image |
| 50 | import common |
| 51 | |
| 52 | logger = logging.getLogger(__name__) |
| 53 | |
| 54 | OPTIONS = common.OPTIONS |
| 55 | OPTIONS.framework_images = ("system",) |
| 56 | OPTIONS.product_out_framework = None |
| 57 | OPTIONS.product_out_vendor = None |
| 58 | |
| 59 | |
| 60 | def CreateImageSymlinks(): |
| 61 | for image in OPTIONS.framework_images: |
| 62 | image_path = os.path.join(OPTIONS.product_out_framework, "%s.img" % image) |
| 63 | symlink_path = os.path.join(OPTIONS.product_out_vendor, "%s.img" % image) |
| 64 | if os.path.exists(symlink_path): |
| 65 | if os.path.islink(symlink_path): |
| 66 | os.remove(symlink_path) |
| 67 | else: |
| 68 | raise ValueError("Attempting to overwrite built image: %s" % |
| 69 | symlink_path) |
| 70 | os.symlink(image_path, symlink_path) |
| 71 | |
| 72 | |
| 73 | def BuildSuperEmpty(): |
| 74 | framework_dict = common.LoadDictionaryFromFile( |
| 75 | os.path.join(OPTIONS.product_out_framework, "misc_info.txt")) |
| 76 | vendor_dict = common.LoadDictionaryFromFile( |
| 77 | os.path.join(OPTIONS.product_out_vendor, "misc_info.txt")) |
| 78 | # Regenerate super_empty.img if both partial builds enable DAP. If only the |
| 79 | # the vendor build enables DAP, the vendor build's existing super_empty.img |
| 80 | # will be reused. If only the framework build should enable DAP, super_empty |
| 81 | # should be included in the --framework_images flag to copy the existing |
| 82 | # super_empty.img from the framework build. |
| 83 | if (framework_dict.get("use_dynamic_partitions") == "true") and ( |
| 84 | vendor_dict.get("use_dynamic_partitions") == "true"): |
| 85 | merged_dict = dict(vendor_dict) |
| 86 | merged_dict.update( |
| 87 | common.MergeDynamicPartitionInfoDicts( |
| 88 | framework_dict=framework_dict, |
| 89 | vendor_dict=vendor_dict, |
| 90 | size_prefix="super_", |
| 91 | size_suffix="_group_size", |
| 92 | list_prefix="super_", |
| 93 | list_suffix="_partition_list")) |
| 94 | output_super_empty_path = os.path.join(OPTIONS.product_out_vendor, |
| 95 | "super_empty.img") |
| 96 | build_super_image.BuildSuperImage(merged_dict, output_super_empty_path) |
| 97 | |
| 98 | |
| 99 | def MergeBuilds(): |
| 100 | CreateImageSymlinks() |
| 101 | BuildSuperEmpty() |
| 102 | # TODO(b/137853921): Add support for regenerating vbmeta images. |
| 103 | |
| 104 | |
| 105 | def main(): |
| 106 | common.InitLogging() |
| 107 | |
| 108 | def option_handler(o, a): |
| 109 | if o == "--framework_images": |
| 110 | OPTIONS.framework_images = [i.strip() for i in a.split(",")] |
| 111 | elif o == "--product_out_framework": |
| 112 | OPTIONS.product_out_framework = a |
| 113 | elif o == "--product_out_vendor": |
| 114 | OPTIONS.product_out_vendor = a |
| 115 | else: |
| 116 | return False |
| 117 | return True |
| 118 | |
| 119 | args = common.ParseOptions( |
| 120 | sys.argv[1:], |
| 121 | __doc__, |
| 122 | extra_long_opts=[ |
| 123 | "framework_images=", |
| 124 | "product_out_framework=", |
| 125 | "product_out_vendor=", |
| 126 | ], |
| 127 | extra_option_handler=option_handler) |
| 128 | |
| 129 | if (args or OPTIONS.product_out_framework is None or |
| 130 | OPTIONS.product_out_vendor is None): |
| 131 | common.Usage(__doc__) |
| 132 | sys.exit(1) |
| 133 | |
| 134 | MergeBuilds() |
| 135 | |
| 136 | |
| 137 | if __name__ == "__main__": |
| 138 | main() |