import os
import subprocess
def run_cmd(cmd: str):
res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
sout, serr = res.communicate(timeout=60)
return res.pid, res.returncode, sout, serr
def get_needed_lib(file_path: str) -> list:
cmd = " ".join(["readelf", "-d", file_path])
res = run_cmd(cmd)
if res[1] != 0:
print("error run readelf -d {}".format(file_path))
print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n",
res[2].decode(), res[3].decode()]))
return []
needed_lib_name = []
lib_info = res[2].decode().split()
for i, val in enumerate(lib_info):
if val == "(NEEDED)" and lib_info[i + 3].startswith("[") and lib_info[i + 3].endswith("]"):
needed_lib_name.append(lib_info[i + 3][1 : -1])
return needed_lib_name
def judge_lib_available(lib_name: str, lib_chain: list, available_libs: list, lib_to_path: dict) -> bool:
if lib_name in available_libs:
return True
lib_path = lib_to_path.get(lib_name)
if lib_path is None:
return False
for next_lib in get_needed_lib(lib_path):
if next_lib not in lib_chain:
lib_chain.append(next_lib)
if not judge_lib_available(next_lib, lib_chain, available_libs, lib_to_path):
return False
lib_chain.remove(next_lib)
available_libs.add(lib_name)
return True
def judge_updater_available(updater_root_path: str) -> bool:
lib_to_path = dict()
for path in [os.path.join(updater_root_path, "lib64"), os.path.join(updater_root_path, "lib")]:
for root, dirs, files in os.walk(path):
for file in files:
lib_to_path[file] = os.path.join(root, file)
lib_to_path["updater"] = os.path.join(updater_root_path, "bin", "updater")
lib_chain = ["updater"]
available_libs = set()
if not judge_lib_available("updater", lib_chain, available_libs, lib_to_path):
print("Reason: not allow updater to depend dynamic library which not exist in updater.img. {}"\
.format("->".join(lib_chain)))
print("Solution: add updater in install_images field when compiling {}".format(lib_chain[-1]))
return False
return True
def judge_updater_img_available(updater_root_path: str) -> bool:
return judge_updater_available(updater_root_path)