TOOLS/dylib_unhell.py: simplify the otool output processing
There is no need to pipe things through shell and grep/awk, python is perfectly fine word processor. This makes it simpler to reason what is extracted and from where and also makes the script faster as we spawn only single process directly, not shell with multiple children.
This commit is contained in:
1 parent
3183ea9980
commit
ed99433277
1 file changed
+26
-35
+26
-35
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user