diff --git a/TOOLS/dylib_unhell.py b/TOOLS/dylib_unhell.py index f2312e8f2e..8562d7a4fc 100755 --- a/TOOLS/dylib_unhell.py +++ b/TOOLS/dylib_unhell.py @@ -6,7 +6,6 @@ import re import shutil import subprocess import sys -from functools import partial sys_re = re.compile("^/System") usr_re = re.compile("^/usr/lib/") @@ -25,9 +24,16 @@ def is_user_lib(objfile, libname): "libswift" not in libname def otool(objfile, rapths): - command = f"otool -L '{objfile}' | grep -e '\t' | awk '{{ print $1 }}'" - output = subprocess.check_output(command, shell=True, universal_newlines=True) - libs = set(filter(partial(is_user_lib, objfile), output.split())) + output = subprocess.check_output( + ["otool", "-L", objfile], universal_newlines=True, + ) + libs = set() + for line in output.splitlines(): + if not line.startswith("\t"): + continue + lib = line.split()[0] + if is_user_lib(objfile, lib): + libs.add(lib) libs_resolved = set() libs_relative = set() @@ -39,41 +45,27 @@ def otool(objfile, rapths): return libs_resolved, libs_relative -def get_rapths(objfile): - rpaths: list[str] = [] - command = f"otool -l '{objfile}' | grep -A2 LC_RPATH | grep path" +def iter_rpaths(objfile): + output = subprocess.check_output( + ["otool", "-l", objfile], universal_newlines=True, + ) path_re = re.compile(r"^\s*path (.*) \(offset \d*\)$") + for line in output.splitlines(): + if match := path_re.match(line): + yield match.group(1).strip() - try: - result = subprocess.check_output(command, shell=True, universal_newlines=True) - except Exception: - return rpaths - - for line in result.splitlines(): - match = path_re.search(line) - if match is None: - continue - line_clean = match.group(1).strip() +def get_rapths(objfile): + loader_path = os.path.dirname(objfile) + return [ # resolve @loader_path - if line_clean.startswith("@loader_path/"): - line_clean = line_clean[len("@loader_path/"):] - line_clean = os.path.join(os.path.dirname(objfile), line_clean) - line_clean = os.path.normpath(line_clean) - rpaths.append(line_clean) - - return rpaths + os.path.normpath(rpath.replace("@loader_path", loader_path, 1)) + for rpath in iter_rpaths(objfile) + ] def get_rpaths_dev_tools(binary): - command = ( - f"otool -l '{binary}' | grep -A2 LC_RPATH | grep path | " - 'grep "Xcode\\|CommandLineTools"' - ) - result = subprocess.check_output(command, shell = True, universal_newlines=True) - path_re = re.compile(r"^\s*path (.*) \(offset \d*\)$") return [ - match.group(1).strip() - for line in result.splitlines() - if (match := path_re.search(line)) is not None + rpath for rpath in iter_rpaths(binary) + if "Xcode" in rpath or "CommandLineTools" in rpath ] def resolve_lib_path(objfile, lib, rapths): @@ -97,8 +89,7 @@ def resolve_lib_path(objfile, lib, rapths): def check_vulkan_max_version(version): try: subprocess.check_output( - f"pkg-config vulkan --max-version={version}", - shell=True, + ["pkg-config", "vulkan", f"--max-version={version}"], ) return True except Exception: