fix-install-names.py 3.1 KB

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