1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2024 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 argparse 17import json 18import os 19import shutil 20import stat 21import utils 22import subprocess 23 24 25def _get_args(): 26 parser = argparse.ArgumentParser(add_help=True) 27 parser.add_argument( 28 "-sp", 29 "--source_code_path", 30 default=r".", 31 type=str, 32 help="Path of source code", 33 ) 34 parser.add_argument( 35 "-hp", 36 "--hpmcache_path", 37 default=r".", 38 type=str, 39 help="Path of .hpmcache", 40 ) 41 parser.add_argument( 42 "-v", 43 "--variants", 44 default=r".", 45 type=str, 46 help="variants of build target", 47 ) 48 parser.add_argument( 49 "-rp", 50 "--root_path", 51 default=r".", 52 type=str, 53 help="Path of root", 54 ) 55 args = parser.parse_args() 56 return args 57 58 59def _get_dependence_json(_path) -> dict: 60 dependences_path = os.path.join(_path, 'dependences.json') 61 _json = utils.get_json(dependences_path) 62 return _json 63 64 65def _get_bundle_path(hpm_cache_path, dependences_json, part_name): 66 bundle_path = (hpm_cache_path + 67 dependences_json[part_name]['installPath'] + os.sep + 'bundle.json') 68 return bundle_path 69 70 71def _get_src_bundle_path(source_code_path): 72 bundle_paths = list() 73 for root, dirs, files in os.walk(source_code_path): 74 for file in files: 75 if file.endswith("bundle.json"): 76 bundle_paths.append(os.path.join(root, file)) 77 return bundle_paths 78 79 80def _symlink_src2dest(src_dir, dest_dir): 81 if os.path.exists(dest_dir) and os.path.islink(dest_dir): 82 os.unlink(dest_dir) 83 if os.path.exists(dest_dir) and dest_dir != src_dir: 84 if os.path.isdir(dest_dir): 85 shutil.rmtree(dest_dir) 86 else: 87 os.remove(dest_dir) 88 os.symlink(src_dir, dest_dir) 89 90 91def _symlink_binarys(hpm_cache_path, bundle_json, dependences_json, part_name): 92 path = bundle_json["segment"]["destPath"] 93 link_path = os.path.join("binarys", path) 94 if not os.path.isdir(link_path): 95 try: 96 os.remove(link_path) 97 except FileNotFoundError: 98 pass 99 os.makedirs(link_path, exist_ok=True) 100 real_path = hpm_cache_path + dependences_json[part_name]['installPath'] 101 _symlink_src2dest(real_path, link_path) 102 103 104def _link_kernel_binarys(variants, hpm_cache_path, dependences_json): 105 musl_real_path = hpm_cache_path + dependences_json["musl"]['installPath'] 106 musl_include_link_path = os.path.join("out", variants, "obj/binarys/third_party/musl/usr/include/arm-linux-ohos") 107 musl_lib_link_path = os.path.join("out", variants, "obj/binarys/third_party/musl/usr/lib/arm-linux-ohos") 108 os.makedirs(musl_include_link_path, exist_ok=True) 109 os.makedirs(musl_lib_link_path, exist_ok=True) 110 _symlink_src2dest(os.path.join(musl_real_path, 'innerapis', 'includes'), musl_include_link_path) 111 _symlink_src2dest(os.path.join(musl_real_path, 'innerapis', 'libs'), musl_lib_link_path) 112 113 kernel_real_path = hpm_cache_path + dependences_json["linux"]['installPath'] 114 kernel_link_path = os.path.join("kernel", "linux") 115 if not os.path.isdir(kernel_link_path): 116 try: 117 os.remove(kernel_link_path) 118 except FileNotFoundError: 119 pass 120 os.makedirs(kernel_link_path, exist_ok=True) 121 os.makedirs(kernel_link_path, exist_ok=True) 122 _symlink_src2dest(os.path.join(kernel_real_path, "innerapis"), kernel_link_path) 123 124 125def _gen_components_info(components_json, bundle_json, part_name, src_build_name_list, _part_toolchain_map_dict): 126 subsystem = bundle_json["component"]["subsystem"] 127 path = bundle_json["segment"]["destPath"] 128 try: 129 component = bundle_json["component"]["build"]["inner_kits"] 130 except KeyError: 131 if not bundle_json["component"]["build"]: 132 bundle_json["component"]["build"] = {} 133 if "inner_api" not in bundle_json["component"]["build"].keys(): 134 bundle_json["component"]["build"]["inner_api"] = [] 135 component = bundle_json["component"]["build"]["inner_api"] 136 innerapi_value_list = list() 137 for i in component: 138 innerapi_name = i["name"].split(':')[-1] 139 if part_name == 'musl': 140 innerapi_label = "{}:{}".format(os.path.join("//binarys", path), innerapi_name) 141 elif part_name in src_build_name_list: 142 innerapi_label = i['name'] 143 else: 144 innerapi_label = "{}:{}".format(os.path.join("//binarys", path, "innerapis", innerapi_name), innerapi_name) 145 innerapi_value_list.append({"name": innerapi_name, "label": innerapi_label}) 146 if innerapi_name in _part_toolchain_map_dict.keys(): 147 _name = innerapi_name 148 innerapi_name = f"{innerapi_name}({_part_toolchain_map_dict[_name]['toolchain_value']})" 149 innerapi_label = "{}:{}".format(os.path.join("//binarys", path, "innerapis", 150 _name, 151 _part_toolchain_map_dict[_name]['toolchain_key']), 152 innerapi_name) 153 innerapi_value_list.append({"name": innerapi_name, "label": innerapi_label}) 154 if part_name == 'cjson': 155 part_name = 'cJSON' 156 if part_name == 'freebsd': 157 part_name = 'FreeBSD' 158 spe_component_names = ['astc_encoder', 'llvm_project', 'alsa_lib', 'alsa_utils', 'abseil_cpp', 'cups_filters', 159 'libnfc_nci', 'vulkan_loader', 'libjpeg_turbo', 'opencl_headers', 'f2fs_tools', 'noto_cjk', 160 'fsverity_utils', 'vk_gl_cts', 161 'spirv_tools', 'spirv_headers', 'vulkan_headers', 'u_boot', 'weex_loader', 'ntfs_3g', 162 'css_what'] 163 if part_name in spe_component_names: 164 part_name = part_name.replace('_', '-') 165 one_component_dict = {part_name: { 166 "innerapis": innerapi_value_list, 167 "path": path, 168 "subsystem": subsystem 169 }} 170 components_json.update(one_component_dict) 171 172 return components_json 173 174 175def _get_src_part_name(src_bundle_paths): 176 _name = '' 177 _path = '' 178 for src_bundle_path in src_bundle_paths: 179 src_bundle_json = utils.get_json(src_bundle_path) 180 part_name = "" 181 try: 182 part_name = src_bundle_json['component']['name'] 183 except KeyError: 184 print(f'--get bundle json component name error--') 185 if part_name.endswith('_lite'): 186 pass 187 else: 188 _name = part_name 189 _path = src_bundle_path 190 return _name, _path 191 192 193def _binarys_permissions_handler(): 194 binarys_path = "binarys" 195 cmd = ["chmod", "755", "-R", binarys_path] 196 subprocess.Popen(cmd) 197 198 199def _components_info_handler(part_name_list, source_code_path, hpm_cache_path, root_path, dependences_json, 200 _part_toolchain_map_dict): 201 components_json = dict() 202 src_bundle_paths = _get_src_bundle_path(source_code_path) 203 src_part_name, src_bundle_path = _get_src_part_name(src_bundle_paths) 204 src_build_name_list = [src_part_name, 'build_framework'] 205 components_json = _gen_components_info(components_json, utils.get_json(src_bundle_path), src_part_name, 206 src_build_name_list, _part_toolchain_map_dict) 207 components_json = _gen_components_info(components_json, 208 utils.get_json(os.path.join(root_path, "build", "bundle.json")), 209 "build_framework", src_build_name_list, _part_toolchain_map_dict) 210 for part_name in part_name_list: 211 if part_name and part_name != src_part_name: 212 bundle_path = _get_bundle_path(hpm_cache_path, dependences_json, part_name) 213 bundle_json = utils.get_json(bundle_path) 214 components_json = _gen_components_info(components_json, bundle_json, part_name, src_build_name_list, 215 _part_toolchain_map_dict) 216 _symlink_binarys(hpm_cache_path, bundle_json, dependences_json, part_name) 217 218 return components_json 219 220 221def _out_components_json(components_json, output_path): 222 file_name = os.path.join(output_path, "components.json") 223 flags = os.O_WRONLY | os.O_CREAT 224 modes = stat.S_IWUSR | stat.S_IRUSR 225 with os.fdopen(os.open(file_name, flags, modes), 'w') as f: 226 json.dump(components_json, f, indent=4) 227 228 229def _generate_platforms_list(output_path): 230 platforms_list_gni_file = os.path.join(output_path, "platforms_list.gni") 231 platforms_list = ['phone'] 232 platforms_list_strings = ' "," '.join(platforms_list) 233 gni_file_content = [f'target_platform_list = [ "{platforms_list_strings}" ]', 234 f'kits_platform_list = [ "{platforms_list_strings}" ]'] 235 flags = os.O_WRONLY | os.O_CREAT 236 modes = stat.S_IWUSR | stat.S_IRUSR 237 with os.fdopen(os.open(platforms_list_gni_file, flags, modes), 'w') as f: 238 f.write('\n'.join(gni_file_content)) 239 240 241def _get_toolchain_json(_path): 242 toolchain_json = os.path.join(_path, 'build', 'indep_configs', 'variants', 'common', 'toolchain.json') 243 _json = utils.get_json(toolchain_json) 244 return _json 245 246 247def _get_all_have_toolchain_component(toolchain_json, hpm_cache_path): 248 _toolchain_list = toolchain_json.keys() 249 binarys_path = os.path.join(hpm_cache_path, 'binarys') 250 _part_toolchain_map_dict = dict() 251 for toolchain in _toolchain_list: 252 for root, dirs, files in os.walk(binarys_path, topdown=False, followlinks=True): 253 if toolchain in dirs: 254 _part_name = root.split(os.sep)[-1] 255 _part_toolchain_map_dict.update({ 256 _part_name: { 257 'toolchain_key': toolchain, 258 'toolchain_value': toolchain_json[toolchain] 259 } 260 }) 261 return _part_toolchain_map_dict 262 263 264def main(): 265 args = _get_args() 266 source_code_path = args.source_code_path 267 hpm_cache_path = args.hpmcache_path 268 variants = args.variants 269 root_path = args.root_path 270 project_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 271 output_part_path = os.path.join(project_path, 'out', variants, 'build_configs', 'parts_info') 272 output_config_path = os.path.join(project_path, 'out', variants, 'build_configs') 273 dependences_json = _get_dependence_json(hpm_cache_path) 274 toolchain_json = _get_toolchain_json(root_path) 275 part_name_list = dependences_json.keys() 276 277 _part_toolchain_map_dict = _get_all_have_toolchain_component(toolchain_json, hpm_cache_path) 278 components_json = _components_info_handler(part_name_list, source_code_path, 279 hpm_cache_path, root_path, dependences_json, _part_toolchain_map_dict) 280 _binarys_permissions_handler() 281 _out_components_json(components_json, output_part_path) 282 _generate_platforms_list(output_config_path) 283 _link_kernel_binarys(variants, hpm_cache_path, dependences_json) 284 285 286if __name__ == '__main__': 287 main() 288