gen_sym_files.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/env python
  2. import logging, os, re, subprocess, sys
  3. import os.path
  4. import pdb, pprint
  5. if len(sys.argv) < 4:
  6. print("Usage:")
  7. print("\tgen_sym_files.py <path to breakpad's dump_syms> <path to owncloud.app> <symbol output dir>")
  8. print("")
  9. print("Symbols will be created in './symbols'")
  10. sys.exit(1)
  11. dump_symsPath = sys.argv[1]
  12. bundlePath = sys.argv[2]
  13. outPath = sys.argv[3]
  14. macOsDir = os.path.join(bundlePath, 'Contents', 'MacOS')
  15. pluginsDir = os.path.join(bundlePath, 'Contents', 'PlugIns')
  16. def resolvePath(input):
  17. resolved = re.sub(r'@\w+', macOsDir, input)
  18. return os.path.normpath(resolved)
  19. def extractDeps(macho):
  20. deps = [macho]
  21. otool = subprocess.Popen(['otool', '-L', macho], stdout=subprocess.PIPE)
  22. for l in otool.communicate()[0].splitlines():
  23. if 'is not an object file' in l:
  24. return []
  25. m = re.search(r'@[^\s]+', l)
  26. if m:
  27. path = resolvePath(m.group(0))
  28. if not os.path.exists(path):
  29. logging.warning("Non-existent file found in dependencies, ignoring: [%s]", path)
  30. continue
  31. deps.append(path)
  32. return deps
  33. def findDeps():
  34. deps = []
  35. for f in os.listdir(macOsDir):
  36. path = os.path.join(macOsDir, f)
  37. if not os.path.islink(path):
  38. deps += extractDeps(path)
  39. for root, dirs, files in os.walk(pluginsDir):
  40. for f in files:
  41. path = os.path.join(root, f)
  42. deps += extractDeps(path)
  43. return sorted(set(deps))
  44. def dumpSyms(deps):
  45. for dep in deps:
  46. print("Generating symbols for [%s]" % dep)
  47. with open('temp.sym', 'w') as temp:
  48. subprocess.check_call([dump_symsPath, dep], stdout=temp)
  49. with open('temp.sym', 'r') as temp:
  50. header = temp.readline()
  51. fields = header.split()
  52. key, name = fields[3:5]
  53. destDir = '%s/%s/%s/' % (outPath, name, key)
  54. destPath = destDir + name + '.sym'
  55. if os.path.exists(destPath):
  56. logging.warning("Symbols already exist: [%s]", destPath)
  57. continue
  58. if not os.path.exists(destDir):
  59. os.makedirs(destDir)
  60. os.rename('temp.sym', destPath)
  61. def strip(deps):
  62. for dep in deps:
  63. print("Stripping symbols off [%s]" % dep)
  64. subprocess.check_call(['strip', '-S', dep])
  65. print('=== Generating symbols for [%s] in [%s]' % (bundlePath, outPath))
  66. deps = findDeps()
  67. dumpSyms(deps)
  68. strip(deps)