1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys 17import os 18import shutil 19import argparse 20import json 21from mkimage import mkimages 22 23sys.path.append( 24 os.path.dirname(os.path.dirname(os.path.dirname( 25 os.path.abspath(__file__))))) 26from scripts.util import build_utils 27from build_scripts.build import find_top # noqa: E402 28 29 30def _prepare_userdata(userdata_path: str): 31 if os.path.exists(userdata_path): 32 shutil.rmtree(userdata_path) 33 os.makedirs(userdata_path, exist_ok=True) 34 35 36def _prepare_root(system_path: str, target_cpu: str): 37 root_dir = os.path.join(os.path.dirname(system_path), 'root') 38 if os.path.exists(root_dir): 39 shutil.rmtree(root_dir) 40 os.makedirs(root_dir, exist_ok=True) 41 _dir_list = [ 42 'config', 'dev', 'proc', 'sys', 'updater', 'system', 'vendor', 'data', 'chip_ckm', 43 'storage', 'mnt', 'tmp', 'sys_prod', 'chip_prod', 'module_update', 'eng_system', 'eng_chipset' 44 ] 45 for _dir_name in _dir_list: 46 os.makedirs(os.path.join(root_dir, _dir_name), exist_ok=True) 47 os.symlink('/system/bin', os.path.join(root_dir, 'bin')) 48 os.symlink('/system/bin/init', os.path.join(root_dir, 'init')) 49 os.symlink('/system/etc', os.path.join(root_dir, 'etc')) 50 os.symlink('/vendor', os.path.join(root_dir, 'chipset')) 51 if target_cpu == 'arm64' or target_cpu == 'riscv64': 52 os.symlink('/system/lib64', os.path.join(root_dir, 'lib64')) 53 os.symlink('/system/lib', os.path.join(root_dir, 'lib')) 54 55 56def _prepare_updater(updater_path: str, target_cpu: str): 57 _dir_list = ['dev', 'proc', 'sys', 'system', 'tmp', 'lib', 'lib64', 'vendor'] 58 for _dir_name in _dir_list: 59 _path = os.path.join(updater_path, _dir_name) 60 if os.path.exists(_path): 61 continue 62 os.makedirs(_path, exist_ok=True) 63 if not os.path.exists(os.path.join(updater_path, 'init')): 64 os.symlink('bin/init', os.path.join(updater_path, 'init')) 65 if not os.path.exists(os.path.join(updater_path, 'system/bin')): 66 os.symlink('/bin', os.path.join(updater_path, 'system/bin')) 67 if not os.path.exists(os.path.join(updater_path, 'system/lib')): 68 os.symlink('/lib', os.path.join(updater_path, 'system/lib')) 69 if target_cpu == 'arm64': 70 if not os.path.exists(os.path.join(updater_path, 'system/lib64')): 71 os.symlink('/lib64', os.path.join(updater_path, 'system/lib64')) 72 if not os.path.exists(os.path.join(updater_path, 'vendor/lib64')): 73 os.symlink('/lib64', os.path.join(updater_path, 'vendor/lib64')) 74 else: 75 if not os.path.exists(os.path.join(updater_path, 'vendor/lib')): 76 os.symlink('/lib', os.path.join(updater_path, 'vendor/lib')) 77 if not os.path.exists(os.path.join(updater_path, 'system/etc')): 78 os.symlink('/etc', os.path.join(updater_path, 'system/etc')) 79 80 81def _prepare_ramdisk(ramdisk_path: str): 82 _dir_list = ['bin', 'dev', 'etc', 'lib', 'proc', 'sys', 'system', 'usr', 'mnt', 'storage'] 83 for _dir_name in _dir_list: 84 _path = os.path.join(ramdisk_path, _dir_name) 85 if os.path.exists(_path): 86 continue 87 os.makedirs(_path, exist_ok=True) 88 if not os.path.exists(os.path.join(ramdisk_path, 'init')): 89 os.symlink('bin/init_early', os.path.join(ramdisk_path, 'init')) 90 91 92def _prepare_eng_ststem(eng_system_path: str, build_variant: str): 93 if os.path.exists(eng_system_path): 94 shutil.rmtree(eng_system_path) 95 os.makedirs(eng_system_path, exist_ok=True) 96 if build_variant == "user": 97 return 98 _dir_list_first = ['etc', 'bin'] 99 for _dir_name in _dir_list_first: 100 _path = os.path.join(eng_system_path, _dir_name) 101 if os.path.exists(_path): 102 shutil.rmtree(_path) 103 os.makedirs(_path, exist_ok=True) 104 _dir_list_second = ['param', 'init', 'selinux'] 105 for _dir_name in _dir_list_second: 106 _path = os.path.join(eng_system_path, 'etc', _dir_name) 107 if os.path.exists(_path): 108 shutil.rmtree(_path) 109 os.makedirs(_path, exist_ok=True) 110 _target_policy_path = os.path.join(eng_system_path, 'etc', 'selinux', 'targeted', 'policy') 111 if os.path.exists(_target_policy_path): 112 shutil.rmtree(_target_policy_path) 113 os.makedirs(_target_policy_path, exist_ok=True) 114 root_path = find_top() 115 copy_eng_system_config = os.path.join(root_path, "build/ohos/images/mkimage/root_image.json") 116 with open(copy_eng_system_config, 'rb') as input_f: 117 default_build_args = json.load(input_f) 118 for arg in default_build_args.values(): 119 sources_file = arg.get('source_file') 120 dest_file = arg.get('dest_file') 121 if(os.path.exists(dest_file)): 122 os.remove(dest_file) 123 if(os.path.exists(sources_file)): 124 shutil.copy(sources_file, dest_file) 125 126 127def _make_image(args): 128 if args.image_name == 'system': 129 _prepare_root(args.input_path, args.target_cpu) 130 elif args.image_name == 'updater': 131 _prepare_updater(args.input_path, args.target_cpu) 132 elif args.image_name == 'updater_ramdisk': 133 _prepare_updater(args.input_path, args.target_cpu) 134 elif args.image_name == 'ramdisk': 135 _prepare_ramdisk(args.input_path) 136 image_type = "raw" 137 if args.sparse_image: 138 image_type = "sparse" 139 config_file = args.image_config_file 140 if (os.path.exists(args.device_image_config_file)): 141 config_file = args.device_image_config_file 142 mk_image_args = [ 143 args.input_path, config_file, args.output_image_path, 144 image_type 145 ] 146 if args.build_image_tools_path: 147 env_path = ':'.join(args.build_image_tools_path) 148 os.environ['PATH'] = '{}:{}'.format(env_path, os.environ.get('PATH')) 149 mkimages.mk_images(mk_image_args) 150 151 152def main(argv): 153 parser = argparse.ArgumentParser() 154 parser.add_argument('--depfile', required=True) 155 parser.add_argument('--image-name', required=True) 156 parser.add_argument('--build-variant', required=True) 157 parser.add_argument('--image-config-file', required=True) 158 parser.add_argument('--device-image-config-file', required=True) 159 parser.add_argument('--input-path', required=True) 160 parser.add_argument('--output-image-path', required=True) 161 parser.add_argument('--sparse-image', 162 dest="sparse_image", 163 action='store_true') 164 parser.set_defaults(sparse_image=False) 165 parser.add_argument('--build-image-tools-path', nargs='*', required=False) 166 parser.add_argument('--target-cpu', required=False) 167 args = parser.parse_args(argv) 168 169 if os.path.exists(args.output_image_path): 170 os.remove(args.output_image_path) 171 if args.image_name == 'userdata': 172 _prepare_userdata(args.input_path) 173 elif args.image_name == 'eng_system': 174 _prepare_eng_ststem(args.input_path, args.build_variant) 175 if os.path.isdir(args.input_path): 176 _make_image(args) 177 _dep_files = [] 178 for _root, _, _files in os.walk(args.input_path): 179 for _file in _files: 180 _dep_files.append(os.path.join(_root, _file)) 181 if (os.path.exists(args.device_image_config_file)): 182 _dep_files.append(args.device_image_config_file) 183 build_utils.write_depfile(args.depfile, 184 args.output_image_path, 185 _dep_files, 186 add_pydeps=False) 187 return 0 188 189 190if __name__ == '__main__': 191 sys.exit(main(sys.argv[1:])) 192