15f9996aaSopenharmony_ci#!/usr/bin/env python3 25f9996aaSopenharmony_ci# coding: utf-8 35f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 65f9996aaSopenharmony_ci# You may obtain a copy of the License at 75f9996aaSopenharmony_ci# 85f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 145f9996aaSopenharmony_ci# limitations under the License. 155f9996aaSopenharmony_ci 165f9996aaSopenharmony_ciimport os 175f9996aaSopenharmony_ciimport subprocess 185f9996aaSopenharmony_ci 195f9996aaSopenharmony_ci 205f9996aaSopenharmony_cidef run_cmd(cmd: str): 215f9996aaSopenharmony_ci res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, 225f9996aaSopenharmony_ci stderr=subprocess.PIPE) 235f9996aaSopenharmony_ci sout, serr = res.communicate(timeout=60) 245f9996aaSopenharmony_ci 255f9996aaSopenharmony_ci return res.pid, res.returncode, sout, serr 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_ci 285f9996aaSopenharmony_cidef get_needed_lib(file_path: str) -> list: 295f9996aaSopenharmony_ci cmd = " ".join(["readelf", "-d", file_path]) 305f9996aaSopenharmony_ci res = run_cmd(cmd) 315f9996aaSopenharmony_ci if res[1] != 0: 325f9996aaSopenharmony_ci print("error run readelf -d {}".format(file_path)) 335f9996aaSopenharmony_ci print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n", 345f9996aaSopenharmony_ci res[2].decode(), res[3].decode()])) 355f9996aaSopenharmony_ci return [] 365f9996aaSopenharmony_ci needed_lib_name = [] 375f9996aaSopenharmony_ci lib_info = res[2].decode().split() 385f9996aaSopenharmony_ci for i, val in enumerate(lib_info): 395f9996aaSopenharmony_ci # lib_info : ... (NEEDED) Shared library: [libc++.so] ... 405f9996aaSopenharmony_ci if val == "(NEEDED)" and lib_info[i + 3].startswith("[") and lib_info[i + 3].endswith("]"): 415f9996aaSopenharmony_ci needed_lib_name.append(lib_info[i + 3][1 : -1]) 425f9996aaSopenharmony_ci return needed_lib_name 435f9996aaSopenharmony_ci 445f9996aaSopenharmony_ci 455f9996aaSopenharmony_cidef judge_lib_available(lib_name: str, lib_chain: list, available_libs: list, lib_to_path: dict) -> bool: 465f9996aaSopenharmony_ci if lib_name in available_libs: 475f9996aaSopenharmony_ci return True 485f9996aaSopenharmony_ci lib_path = lib_to_path.get(lib_name) 495f9996aaSopenharmony_ci if lib_path is None: 505f9996aaSopenharmony_ci return False 515f9996aaSopenharmony_ci for next_lib in get_needed_lib(lib_path): 525f9996aaSopenharmony_ci if next_lib not in lib_chain: 535f9996aaSopenharmony_ci lib_chain.append(next_lib) 545f9996aaSopenharmony_ci if not judge_lib_available(next_lib, lib_chain, available_libs, lib_to_path): 555f9996aaSopenharmony_ci return False 565f9996aaSopenharmony_ci lib_chain.remove(next_lib) 575f9996aaSopenharmony_ci available_libs.add(lib_name) 585f9996aaSopenharmony_ci return True 595f9996aaSopenharmony_ci 605f9996aaSopenharmony_ci 615f9996aaSopenharmony_cidef judge_updater_available(updater_root_path: str) -> bool: 625f9996aaSopenharmony_ci lib_to_path = dict() 635f9996aaSopenharmony_ci for path in [os.path.join(updater_root_path, "lib64"), os.path.join(updater_root_path, "lib")]: 645f9996aaSopenharmony_ci for root, dirs, files in os.walk(path): 655f9996aaSopenharmony_ci for file in files: 665f9996aaSopenharmony_ci lib_to_path[file] = os.path.join(root, file) 675f9996aaSopenharmony_ci lib_to_path["updater"] = os.path.join(updater_root_path, "bin", "updater") 685f9996aaSopenharmony_ci lib_chain = ["updater"] 695f9996aaSopenharmony_ci available_libs = set() 705f9996aaSopenharmony_ci if not judge_lib_available("updater", lib_chain, available_libs, lib_to_path): 715f9996aaSopenharmony_ci print("Reason: not allow updater to depend dynamic library which not exist in updater.img. {}"\ 725f9996aaSopenharmony_ci .format("->".join(lib_chain))) 735f9996aaSopenharmony_ci print("Solution: add updater in install_images field when compiling {}".format(lib_chain[-1])) 745f9996aaSopenharmony_ci return False 755f9996aaSopenharmony_ci return True 765f9996aaSopenharmony_ci 775f9996aaSopenharmony_ci 785f9996aaSopenharmony_cidef judge_updater_img_available(updater_root_path: str) -> bool: 795f9996aaSopenharmony_ci return judge_updater_available(updater_root_path) 80