2009-10-04 58 views
4

我有一個Cocoa應用程序,它使用otool查找應用程序需要正常工作所需的共享庫。例如,假設我在使用QTKit.framework的應用程序上運行otool -L。我得到的程序(包括像Cocoa.framework和AppKit.framework的基本框架)中使用的共享庫的列表:使用otool(遞歸)來查找應用程序所需的共享庫

/System/Library/Frameworks/QTKit.framework/Versions/A/QTKit (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.0.0) 
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.0.0) 

..... and so on for a bunch of other frameworks 

這表明應用程序使用QTKit.framework。但是,如果我使用「otool -L」再次上的二進制文件QTKit.framework(/System/Library/Frameworks/QTKit.framework/Versions/A/QTKit)我得到這樣的:

/System/Library/Frameworks/QTKit.framework/Versions/A/QTKit (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/PrivateFrameworks/CoreMedia.framework/Versions/A/CoreMedia (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/PrivateFrameworks/MediaToolbox.framework/Versions/A/MediaToolbox (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/PrivateFrameworks/VideoToolbox.framework/Versions/A/VideoToolbox (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/PrivateFrameworks/CoreMediaIOServices.framework/Versions/A/CoreMediaIOServices (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.0.0) 
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1038.0.0) 
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) 
/System/Library/Frameworks/QuickTime.framework/Versions/A/QuickTime (compatibility version 1.0.0, current version 1584.0.0) 
/System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.6.0) 
/System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface (compatibility version 1.0.0, current version 1.0.0) 
/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox (compatibility version 1.0.0, current version 435.0.0) 
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0) 
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0) 
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0) 
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 44.0.0) 
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.0.0) 
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 38.0.0) 
/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 1.6.0) 

這表明負載應用程序二進制文件中原始otool輸出顯示的更多框架。 有沒有辦法讓otool以遞歸方式運行,這意味着它抓住了應用程序需要的框架,然後進入並搜索每個框架的依賴關係?

回答

8

不,您將不得不重複運行otool,或合併其解析代碼(here)。不要忘記處理@executable_path

這在Python(沒有@executable_path,規範化,或文件名與 - 空間支持),因爲這不是試圖調試僞代碼更容易:

import subprocess 

def otool(s): 
    o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE) 
    for l in o.stdout: 
     if l[0] == '\t': 
      yield l.split(' ', 1)[0][1:] 

need = set(['/Applications/iTunes.app/Contents/MacOS/iTunes']) 
done = set() 

while need: 
    needed = set(need) 
    need = set() 
    for f in needed: 
     need.update(otool(f)) 
    done.update(needed) 
    need.difference_update(done) 

for f in sorted(done): 
    print f 
+0

我想運行它一再將可能是最好的。這將是一個合乎邏輯的方式去做這件事?讓它進入一個無限循環...... – indragie 2009-10-04 23:29:18

+0

兩套(NSMutableSet)應該這樣做:一套用於已經處理的路徑,另一套用於需要處理的路徑。首先通過在應用上運行otool來填充第二組。然後製作第二套的副本,將其清空並在副本中的每個項目上運行otool。不要忘記在解析@executable_path之後,在添加到集合之前(您可以使用realpath(3))來規範化路徑。 – 2009-10-04 23:55:36

+0

這個解決方案的工作原理是:-)謝謝 – indragie 2009-10-06 19:13:06