fix-install-names.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/python
  2. import hashlib
  3. import optparse
  4. import ConfigParser
  5. import os
  6. import platform
  7. import subprocess
  8. import sys
  9. import shutil
  10. def exec_cmd(args, env={}, supress_output=False):
  11. cmd = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, env = env)
  12. output = ''
  13. while True:
  14. out = cmd.stdout.read(1)
  15. if out == '' and cmd.poll() != None:
  16. break
  17. if out != '':
  18. if not supress_output:
  19. sys.stdout.write(out)
  20. output += out
  21. if cmd.wait() != 0:
  22. raise Exception("Command failed: \"%s\"" % " ".join(args), output)
  23. return output
  24. def fix_install_name(path):
  25. for root, dirs, files in os.walk(path):
  26. for f in files:
  27. fpath = os.path.join(root, f)
  28. if (f.endswith(".dylib") or f in ['fc-cache'] or f.endswith(".so")) and not os.path.islink(fpath) and os.path.exists(fpath):
  29. # Fix permissions
  30. if not os.access(fpath, os.W_OK) or not os.access(fpath, os.R_OK) or not os.access(fpath, os.X_OK):
  31. os.chmod(fpath, 0o644)
  32. try:
  33. basename = os.path.basename(fpath)
  34. otoolout = exec_cmd(["otool", "-L", fpath], supress_output=True)
  35. for l in otoolout.split("\n")[1:]:
  36. l = l.rstrip().strip()
  37. # See if we need to fix it up.
  38. if len(l) > 0 and (l.startswith("/Users/admin/") or l[0] != '/'):
  39. current_lib = l.split(" (compat")[0]
  40. current_basename = os.path.basename(current_lib)
  41. correct_lib = os.path.join(root, current_basename)
  42. if not os.path.exists(correct_lib):
  43. # look for it further up, like in the root path:
  44. if os.path.exists(os.path.join(path, "lib", current_basename)):
  45. correct_lib = os.path.join(path, "lib", current_basename)
  46. else:
  47. print "Can't link %s" % current_lib
  48. continue
  49. # print current_lib, correct_lib
  50. if current_lib != correct_lib:
  51. if current_basename.split('.')[0] == basename.split('.')[0]:
  52. print "-- Fixing ID for", basename
  53. exec_cmd(["install_name_tool", "-id", correct_lib, fpath], supress_output=True)
  54. else:
  55. print "-- Fixing library link for %s (%s)" % (basename, current_basename)
  56. exec_cmd(["install_name_tool", "-change", current_lib, correct_lib, fpath], supress_output=True)
  57. except:
  58. print "** Fail when running installname on %s" % f
  59. raise
  60. continue
  61. if __name__=='__main__':
  62. if os.path.isdir(sys.argv[1]):
  63. fix_install_name(sys.argv[1])