#!/usr/bin/python import os import subprocess import re import shutil from pprint import pprint as pp OTR_RE = re.compile('^\t([^ ]+) (.+)') SPLIT = re.compile('[\n\r]+') LP_RE = re.compile('@loader_path/(.+)$') FPREFIX = 'gqrx.app/Contents/Frameworks/' LIB_PATHS = ['/usr/local/opt/boost/lib/'] lib_deps = {} def iteration(pass_num): print '\nFixing dependencied, pass: {0}'.format(pass_num) for root, dirs, files in os.walk(FPREFIX): for fn in files: if not fn.endswith('.dylib'): continue lib_path = os.path.join(root, fn) deps = [] output = subprocess.check_output(['otool', '-L', lib_path]) for line in SPLIT.split(output): mo = OTR_RE.match(line) if mo is None: continue d = mo.group(1) if d.startswith('/System/') or d.startswith('/usr/lib') or d.startswith('@executable_path'): continue deps.append(d) lib_deps[lib_path.replace(FPREFIX, '')] = deps counter = 0 for lib_name, deps in lib_deps.iteritems(): for d in deps: mo = LP_RE.match(d) if mo is None: continue counter += 1 lib = mo.group(1) new_fn = os.path.join(FPREFIX, lib) missing = lib_deps.get(lib, None) is None if missing: print 'Library `{0}` is missing, trying to fix'.format(lib) for p in LIB_PATHS: fn = os.path.join(p, lib) if os.path.exists(fn): print ' found {0}, copy to {1}'.format(fn, new_fn) shutil.copy(fn, new_fn) os.chmod(new_fn, 0o644) # fix ID cmd = ['install_name_tool', '-id', '@executable_path/../Frameworks/{0}'.format(lib), new_fn] subprocess.check_output(cmd) else: print 'File `{0}`: referense to shared library broken: `{1}`, trying to fix'.format(os.path.join(FPREFIX, lib_name), lib) cmd = ['install_name_tool', '-change', '@loader_path/{0}'.format(lib), '@executable_path/../Frameworks/{0}'.format(lib), \ os.path.join(FPREFIX, lib_name)] subprocess.check_output(cmd) return counter for x in range(30): if iteration(x+1) == 0: print 'Finished!' break