diff --git a/tools/osx-bundle.sh b/tools/osx-bundle.sh index eb82b554f..dd50e0aa6 100755 --- a/tools/osx-bundle.sh +++ b/tools/osx-bundle.sh @@ -98,7 +98,7 @@ done echo 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 "Done Creating \"${PKG_DIR}\"" diff --git a/tools/osx-fix-libs.py b/tools/osx-fix-libs.py index 6e14c9064..02eb85053 100755 --- a/tools/osx-fix-libs.py +++ b/tools/osx-fix-libs.py @@ -1,103 +1,120 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import re import sys import os import shutil import stat +import subprocess is_bad_lib = re.compile(r'(/usr/local|/opt)').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 = [] badlist = [] link_map = {} + def otool(cmdline): - pipe = os.popen("otool " + cmdline, 'r') - output = pipe.readlines() - pipe.close() - return output + with subprocess.Popen(['otool'] + cmdline, stdout=subprocess.PIPE, + encoding='utf-8') as p: + return p.stdout.readlines() + def collectlibs(lib, masterlist, targetdir): - global goodlist, link_map - liblist = otool("-L '" + lib + "'") - locallist = [] + global goodlist, link_map + liblist = otool(['-L', lib]) + locallist = [] - for l in liblist: - lr = otool_libname_extract(l) - if not lr: continue - l = lr.group(1) - if is_bad_lib(l) and not l in badlist: - badlist.append(l) - if ((not is_sys_lib(l)) or is_bad_lib(l)) and not l in masterlist: - locallist.append(l) - print "found %s:" % l + for l in liblist: + lr = otool_libname_extract(l) + if not lr: + continue + l = lr.group(1) + if is_bad_lib(l) and l not in badlist: + badlist.append(l) + if ((not is_sys_lib(l)) or is_bad_lib(l)) and l not in masterlist: + locallist.append(l) + print("found %s:" % l) - check = l - link_list = [] - while check: - if os.path.isfile(check) and not os.path.islink(check): - os.system("cp '%s' '%s'" % (check, targetdir)) - print " FILE %s ... copied to target" % check - if link_list: - for link in link_list: - link_map[link] = os.path.basename(check) - break - - if os.path.islink(check): - print " LINK %s" % check - link_list.append(os.path.basename(check)) - check = os.path.dirname(check) + "/" + os.readlink(check) + check = l + link_list = [] + while check: + basename = os.path.basename(check) + target = os.path.join(targetdir, basename) - elif not l in goodlist and not l in masterlist: - goodlist.append(l) - masterlist.extend(locallist) + if os.path.isfile(check) and not os.path.islink(check): + try: + shutil.copy(check, target) + except PermissionError: + print(" FILE %s ... skipped" % check) + break + print(" FILE %s ... copied to target" % check) + if link_list: + for link in link_list: + link_map[link] = basename + break - for l in locallist: - collectlibs(l, masterlist, targetdir) + if os.path.islink(check): + link_dst = os.readlink(check) + try: + 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) -exit; -binname = sys.argv[1] -targetdir = os.path.dirname(binname) -print "Searching for libraries in ", binname, "..." -libs = [binname] -collectlibs(sys.argv[1], libs, targetdir) + elif l not in goodlist and l not in masterlist: + goodlist.append(l) + masterlist.extend(locallist) + + for l in locallist: + collectlibs(l, masterlist, targetdir) -print -print "System libraries used..." -goodlist.sort() -for l in goodlist: - print l +if __name__ == '__main__': + binname = sys.argv[1] + targetdir = os.path.dirname(binname) + print("Searching for libraries in", binname, "...") + libs = [binname] + collectlibs(binname, libs, targetdir) + print() + print("System libraries used...") + goodlist.sort() + for l in goodlist: + print(l) -print -print "Fixing library install names..." -in_tool_cmdline = "install_name_tool " -for lib in libs: - libbase = os.path.basename(lib) - if libbase in link_map: - libbase = link_map[libbase] - in_tool_cmdline = in_tool_cmdline + ("-change '%s' '@executable_path/%s' " % (lib, libbase)) -for lib in libs: - libbase = os.path.basename(lib) + print() + print("Fixing library install names...") + in_tool_cmdline = ['install_name_tool'] + for lib in libs: + libbase = os.path.basename(lib) + if libbase in link_map: + libbase = link_map[libbase] + in_tool_cmdline = in_tool_cmdline + ['-change', lib, + '@executable_path/' + libbase] + for lib in libs: + libbase = os.path.basename(lib) - if libbase in link_map: - libbase = link_map[libbase] - print "%s -> @executable_path/%s (REMAPPED)" % (lib, libbase) - else: - print "%s -> @executable_path/%s" % (lib, libbase) + if libbase in link_map: + libbase = link_map[libbase] + print("%s -> @executable_path/%s (REMAPPED)" % (lib, libbase)) + else: + print("%s -> @executable_path/%s" % (lib, libbase)) - os.system("%s -id '@executable_path/%s' '%s/%s'" % (in_tool_cmdline, libbase, targetdir, libbase)) - sys.stdout.flush() + subprocess.run(in_tool_cmdline + ['-id', '@executable_path/' + libbase, + targetdir + '/' + libbase]) -if badlist: - print - print "WARNING: The following libraries have blacklisted paths:" - for lib in sorted(badlist): - 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." + if badlist: + print() + print("WARNING: The following libraries have blacklisted paths:") + for lib in sorted(badlist): + 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 -print "All done!" + print() + print("All done!")