1# 2# 3import shutil 4import re 5import subprocess 6import os 7home=os.getenv("HOME") 8print "Preparing independant bundle, home="+home+"..." 9rootFolder=home+"/Avidemux2.6.app/Contents/Resources" 10libFolder=rootFolder+"/lib" 11binFolder=rootFolder+"/bin" 12frameWorkFolder=rootFolder+"/../Frameworks" 13qtPluginFolder=rootFolder+"/../plugins" 14qts = ['QtCore', 'QtGui', 'QtOpenGL','QtScript','QtWidgets','QtPrintSupport','QtNetwork'] 15 16# 17# 18allSymbols=[] 19# 20 21def log(s): 22 #print "Log:<"+str(s)+">" 23 pass 24# 25# 26# 27def getShortName(fl): 28 shortName=re.sub('^.*\/','',fl) 29 return shortName 30# 31# Returns the list of libs as dependencies in /opt (macport) 32# 33def getGlobalDeps(target): 34 cmd = ["/usr/bin/otool","-L", target] 35 log(cmd) 36 q = [] 37 cmd = subprocess.Popen(" ".join(cmd), shell=True, stdout=subprocess.PIPE) 38 for line in cmd.stdout: 39 line = re.sub('[ \t\r\n]*', '', line) 40 line = re.sub('\(.*$', '', line) 41 if(not line.startswith('/opt/local') and not line.startswith('/usr/local/opt') and not line.startswith('/usr/local/Cellar/qt5/') and not line.startswith('@rpath')): 42 continue 43 if(":" in line): 44 continue 45 log(line) 46 q.append(line) 47 log(str(q)) 48 return q; 49# 50# 51# 52def getGlobalDepsNoQt(target): 53 q= [] 54 p = getGlobalDeps(target) 55 for line in p: 56 if not getShortName(line).startswith('Qt'): 57 q.append(line) 58 return q 59# 60def getGlobalDepsQtOnly(target): 61 q= [] 62 p = getGlobalDeps(target) 63 for line in p: 64 if getShortName(line).startswith('Qt'): 65 q.append(line) 66 return q 67# 68def getRpathDepsOnly(target): 69 q= [] 70 p = getGlobalDeps(target) 71 for line in p: 72 if getShortName(line).startswith('@rpath'): 73 q.append(line) 74 return q 75# 76# Returns the list of libs as dependencies to local installation folder ( 77# 78def getLocalDeps(target): 79 cmd = ["/usr/bin/otool","-L", target] 80 log(cmd) 81 q = [] 82 cmd = subprocess.Popen(" ".join(cmd), shell=True, stdout=subprocess.PIPE) 83 for line in cmd.stdout: 84 line = re.sub('[ \t\r\n]*', '', line) 85 line = re.sub('\(.*$', '', line) 86 if(not line.startswith(libFolder)): 87 continue 88 if(":" in line): 89 continue 90 log(line) 91 q.append(line) 92 log(str(q)) 93 return q; 94# 95# 96# Copy used library coming from /opt/local 97# 98def copyFiles(folder,libFolder): 99 copied=0 100 log("Copy files"+folder) 101 for dirname, dirnames, filenames in os.walk(folder): 102 for filename in filenames: 103 absPath=os.path.join(dirname, filename) 104 deps=getGlobalDepsNoQt(absPath) 105 for dep in deps: 106 shortName=re.sub('^.*\/','',dep) 107 if(os.path.exists(libFolder+'/'+shortName)): 108 log(shortName+" already copied") 109 else: 110 log("Copying"+shortName) 111 myCopy(dep,libFolder) 112 copied+=1 113 return copied 114# 115# 116# Copy used library coming from /opt/local 117# 118def copyQtDeps(components,libFolder): 119 copied=0 120 for modul in components: 121 absPath='/usr/local/opt/qt5/lib/'+modul+'.framework/Versions/5/'+modul 122 print("Copy deps for "+modul+" ("+absPath+")") 123 deps=getGlobalDepsNoQt(absPath) 124 for dep in deps: 125 shortName=re.sub('^.*\/','',dep) 126 if(os.path.exists(libFolder+'/'+shortName)): 127 print(shortName+" already copied") 128 else: 129 print("Copying:"+shortName) 130 myCopy(dep,libFolder) 131 copied+=1 132 # copy plugins deps too 133 copyFiles(qtPluginFolder+'/imageformats',libFolder) 134 return copied 135## 136def changeSymbol(target,oldName,newName): 137 cmd="/usr/bin/install_name_tool -change "+oldName+" "+newName+" "+target 138 log(cmd) 139 subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 140# 141def changeId(target,newId): 142 cmd="/usr/bin/install_name_tool -id "+newId+" "+target 143 log(cmd) 144 subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 145# 146# 147def renameSymbols(libs): 148 for qt in libs: 149 print "Processing "+qt 150 # Change binding 151 for otherQt in allSymbols: 152 newname=re.sub(r'^.*\/',r'@executable_path/../lib/',otherQt) 153 exc="install_name_tool -change "+otherQt+" "+newname+" libToProcess" 154 print(exc) 155# 156# 157# 158def changeGlobalLinkPathForOne(f): 159 deps=getGlobalDepsNoQt(f) 160 for d in deps: 161 shortName=getShortName(d) 162 shortName="@executable_path/../lib/"+shortName 163 changeSymbol(f,d,shortName) 164def changeLocalLinkPathForOne(f): 165 deps=getLocalDeps(f) 166 for d in deps: 167 shortName="@executable_path/../lib/"+re.sub("^.*\/","",d) 168 changeSymbol(f,d,shortName) 169def changeLibLinkPath(folder): 170 for dirname, dirnames, filenames in os.walk(folder): 171 for filename in filenames: 172 absPath=os.path.join(dirname, filename) 173 changeGlobalLinkPathForOne(absPath) 174 changeLocalLinkPathForOne(absPath) 175 changeQtLinkPathForOne(absPath) 176 shortName="@executable_path/../lib/"+re.sub("^.*\/","",absPath) 177 changeId(absPath,shortName) 178# 179def changeQtPlatformLinkPath(folder): 180 for dirname, dirnames, filenames in os.walk(folder): 181 for filename in filenames: 182 absPath=os.path.join(dirname, filename) 183 changeGlobalLinkPathForOne(absPath) 184 changeLocalLinkPathForOne(absPath) 185 changeQtLinkPathForOne(absPath) 186 shortName="@executable_path/../../plugins/platforms/"+re.sub("^.*\/","",absPath) 187 changeId(absPath,shortName) 188def changeQtPluginLinkPath(folder): 189 for dirname, dirnames, filenames in os.walk(folder): 190 for filename in filenames: 191 absPath=os.path.join(dirname, filename) 192 changeGlobalLinkPathForOne(absPath) 193 changeLocalLinkPathForOne(absPath) 194 changeQtLinkPathForOne(absPath) 195 shortName="@executable_path/../../plugins/imageformats/"+re.sub("^.*\/","",absPath) 196 changeId(absPath,shortName) 197def changeBinLinkPath(folder): 198 for dirname, dirnames, filenames in os.walk(folder): 199 for filename in filenames: 200 absPath=os.path.join(dirname, filename) 201 changeGlobalLinkPathForOne(absPath) 202 changeLocalLinkPathForOne(absPath) 203 changeQtLinkPathForOne(absPath) 204 shortName="@executable_path/bin/"+re.sub("^.*\/","",absPath) 205 changeId(absPath,shortName) 206 207def changePluginLinkPath(folder,relFolder): 208 for dirname, dirnames, filenames in os.walk(folder): 209 for filename in filenames: 210 absPath=os.path.join(dirname, filename) 211 changeGlobalLinkPathForOne(absPath) 212 changeQtLinkPathForOne(absPath) 213 shortName="@executable_path/lib/"+relFolder+re.sub("^.*\/","",absPath) 214 changeId(absPath,shortName) 215# 216# 217# 218def myChmod(dst): 219 log("chmod <"+dst+">") 220 cmd="/bin/chmod" + " -R 755 "+dst 221 log("Exec <"+cmd+">") 222 subprocess.call(cmd, shell=True) 223 224# 225def myCopy(src,dst): 226 shutil.copy(src,dst) 227 myChmod(dst) 228 229# 230def changeQtFileSelfLinkPath(fl,modu): 231 shortName="@executable_path/../../Frameworks/"+modu+".framework/Versions/5/"+modu 232 cmd="/usr/bin/install_name_tool -id "+shortName+" "+fl 233 log(cmd) 234 subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 235def changeQtLinkPathForOne(f): 236 deps=getGlobalDepsQtOnly(f) 237 for d in deps: 238 shortName=getShortName(d) 239 shortName="@executable_path/../../Frameworks/"+shortName+".framework/Versions/5/"+shortName 240 changeSymbol(f,d,shortName) 241 deps2=getRpathDepsOnly(f) 242 for d in deps2: 243 shortName2=re.sub('@rpath','@executable_path/../../Frameworks/') 244 changeSymbol(f,d,shortName2) 245 246# 247def myMkDir(target): 248 if(os.path.exists(target)): 249 return 250 os.makedirs(target) 251# 252def myCopyTree(src,dst): 253 log(src+"->"+dst) 254 if(not os.path.exists(src)): 255 return 256 shutil.copytree(src,dst) 257 myChmod(dst) 258def myCopyFile(src,dst): 259 if(not os.path.exists(src)): 260 return 261 myCopy(src,dst) 262## 263def copyQtFiles(targetFolder): 264 myMkDir(targetFolder) 265 for q in qts: 266 print q 267 if(os.path.exists(targetFolder+'/'+q+'.framework')): 268 log(q+" already copied") 269 else: 270 log("Copying"+q+' to '+targetFolder) 271 src='/usr/local/opt/qt5/lib/'+q+'.framework' 272 dst=targetFolder+'/'+q+'.framework' 273 myMkDir(dst) 274 src=src+'/Versions/5/' 275 dst=dst+'/Versions/' 276 myMkDir(dst) 277 dst=dst+'/5/' 278 myMkDir(dst) 279 print "Copying "+dst+'Resources' 280 myCopyTree(src+'Resources',dst+'Resources') 281 print "Copying "+dst+q 282 myCopyFile(src+q,dst+q) 283 changeQtFileSelfLinkPath(dst+q,q) 284 changeQtLinkPathForOne(dst+q) 285 changeGlobalLinkPathForOne(dst+q) 286 # Also copy plugins 287 myMkDir(qtPluginFolder) 288 myCopyTree('/usr/local/opt/qt5/plugins/imageformats',qtPluginFolder+'/imageformats') 289 myCopyTree('/usr/local/opt/qt5/plugins/platforms',qtPluginFolder+'/platforms') 290################################################################# 291# Step 1 : Copy system files so we have a standalone package 292# 293################################################################# 294print "Copying Qt framework" 295copyQtFiles(frameWorkFolder) 296print "Copying Qt framework dependencies" 297copyQtDeps(qts,libFolder) 298print "Copying system files" 299#copyFiles(binFolder,libFolder) 300processed=1 301# Copy file until all of them are there 302while not processed == 0: 303 processed=copyFiles(libFolder,libFolder) 304 305 306