Fix osx-fix-libs.py

Create symbolic links, to make libicu happy
Rewrite the script in python3, as python2 is deprecated
This commit is contained in:
wangqr 2020-03-08 19:17:53 -04:00
parent e7b64aa741
commit 3a50ba0386
2 changed files with 92 additions and 75 deletions

View file

@ -98,7 +98,7 @@ done
echo echo
echo "---- Libraries ----" echo "---- Libraries ----"
python tools/osx-fix-libs.py "${PKG_DIR}/Contents/MacOS/aegisub" || exit $? python3 tools/osx-fix-libs.py "${PKG_DIR}/Contents/MacOS/aegisub" || exit $?
echo echo
echo "Done Creating \"${PKG_DIR}\"" echo "Done Creating \"${PKG_DIR}\""

View file

@ -1,103 +1,120 @@
#!/usr/bin/env python #!/usr/bin/env python3
import re import re
import sys import sys
import os import os
import shutil import shutil
import stat import stat
import subprocess
is_bad_lib = re.compile(r'(/usr/local|/opt)').match is_bad_lib = re.compile(r'(/usr/local|/opt)').match
is_sys_lib = re.compile(r'(/usr|/System)').match is_sys_lib = re.compile(r'(/usr|/System)').match
otool_libname_extract = re.compile(r'\s+(/.*?)[\(\s:]').search otool_libname_extract = re.compile(r'\s+(/.*?)[(\s:]').search
goodlist = [] goodlist = []
badlist = [] badlist = []
link_map = {} link_map = {}
def otool(cmdline): def otool(cmdline):
pipe = os.popen("otool " + cmdline, 'r') with subprocess.Popen(['otool'] + cmdline, stdout=subprocess.PIPE,
output = pipe.readlines() encoding='utf-8') as p:
pipe.close() return p.stdout.readlines()
return output
def collectlibs(lib, masterlist, targetdir): def collectlibs(lib, masterlist, targetdir):
global goodlist, link_map global goodlist, link_map
liblist = otool("-L '" + lib + "'") liblist = otool(['-L', lib])
locallist = [] locallist = []
for l in liblist: for l in liblist:
lr = otool_libname_extract(l) lr = otool_libname_extract(l)
if not lr: continue if not lr:
continue
l = lr.group(1) l = lr.group(1)
if is_bad_lib(l) and not l in badlist: if is_bad_lib(l) and l not in badlist:
badlist.append(l) badlist.append(l)
if ((not is_sys_lib(l)) or is_bad_lib(l)) and not l in masterlist: if ((not is_sys_lib(l)) or is_bad_lib(l)) and l not in masterlist:
locallist.append(l) locallist.append(l)
print "found %s:" % l print("found %s:" % l)
check = l check = l
link_list = [] link_list = []
while check: while check:
basename = os.path.basename(check)
target = os.path.join(targetdir, basename)
if os.path.isfile(check) and not os.path.islink(check): if os.path.isfile(check) and not os.path.islink(check):
os.system("cp '%s' '%s'" % (check, targetdir)) try:
print " FILE %s ... copied to target" % check shutil.copy(check, target)
except PermissionError:
print(" FILE %s ... skipped" % check)
break
print(" FILE %s ... copied to target" % check)
if link_list: if link_list:
for link in link_list: for link in link_list:
link_map[link] = os.path.basename(check) link_map[link] = basename
break break
if os.path.islink(check): if os.path.islink(check):
print " LINK %s" % check link_dst = os.readlink(check)
link_list.append(os.path.basename(check)) try:
check = os.path.dirname(check) + "/" + os.readlink(check) os.symlink(link_dst, target)
except FileExistsError:
print(" LINK %s ... existed" % check)
break
print(" LINK %s ... copied to target" % check)
link_list.append(basename)
check = os.path.join(os.path.dirname(check), link_dst)
elif not l in goodlist and not l in masterlist: elif l not in goodlist and l not in masterlist:
goodlist.append(l) goodlist.append(l)
masterlist.extend(locallist) masterlist.extend(locallist)
for l in locallist: for l in locallist:
collectlibs(l, masterlist, targetdir) collectlibs(l, masterlist, targetdir)
exit;
if __name__ == '__main__':
binname = sys.argv[1] binname = sys.argv[1]
targetdir = os.path.dirname(binname) targetdir = os.path.dirname(binname)
print "Searching for libraries in ", binname, "..." print("Searching for libraries in", binname, "...")
libs = [binname] libs = [binname]
collectlibs(sys.argv[1], libs, targetdir) collectlibs(binname, libs, targetdir)
print()
print print("System libraries used...")
print "System libraries used..."
goodlist.sort() goodlist.sort()
for l in goodlist: for l in goodlist:
print l print(l)
print()
print print("Fixing library install names...")
print "Fixing library install names..." in_tool_cmdline = ['install_name_tool']
in_tool_cmdline = "install_name_tool "
for lib in libs: for lib in libs:
libbase = os.path.basename(lib) libbase = os.path.basename(lib)
if libbase in link_map: if libbase in link_map:
libbase = link_map[libbase] libbase = link_map[libbase]
in_tool_cmdline = in_tool_cmdline + ("-change '%s' '@executable_path/%s' " % (lib, libbase)) in_tool_cmdline = in_tool_cmdline + ['-change', lib,
'@executable_path/' + libbase]
for lib in libs: for lib in libs:
libbase = os.path.basename(lib) libbase = os.path.basename(lib)
if libbase in link_map: if libbase in link_map:
libbase = link_map[libbase] libbase = link_map[libbase]
print "%s -> @executable_path/%s (REMAPPED)" % (lib, libbase) print("%s -> @executable_path/%s (REMAPPED)" % (lib, libbase))
else: else:
print "%s -> @executable_path/%s" % (lib, libbase) print("%s -> @executable_path/%s" % (lib, libbase))
os.system("%s -id '@executable_path/%s' '%s/%s'" % (in_tool_cmdline, libbase, targetdir, libbase)) subprocess.run(in_tool_cmdline + ['-id', '@executable_path/' + libbase,
sys.stdout.flush() targetdir + '/' + libbase])
if badlist: if badlist:
print print()
print "WARNING: The following libraries have blacklisted paths:" print("WARNING: The following libraries have blacklisted paths:")
for lib in sorted(badlist): for lib in sorted(badlist):
print lib print(lib)
print "These paths normally have files from a package manager, which means that end result may not work if copied to another machine." print(
"These paths normally have files from a package manager, which means that end result may not work if copied to another machine.")
print print()
print "All done!" print("All done!")