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