Windows、Mac OS X和Linux的動态連結庫/共享庫各有千秋。在這裡簡單介紹下Mac OS X的共享庫。Mac OS X的核心是BSD和Mach混合而成的。由于Mach核心處理CPU相關的最核心的任務,包括線程排程等,是以Mac OS X的原生可執行檔案是Mach-O(O是Object的縮寫)格式。是以Mac OS X的共享庫也一般基于該格式。
Mac OS X除了有架構和包羅架構(又譯傘狀架構,兩者的擴充名都為.framework的包,在此不多做介紹)之外,還有兩種共享庫格式。一種的擴充名為.dylib,被稱為MH_DYLIB格式,是一種僅僅在記憶體中共享代碼的簡單的動态庫,它不能被其它代碼顯式的載入。一般在XCode直接建立的BSD、Carbon或Cocoa動态庫并進行編譯,就能得到這種庫。
另外有一種能被代碼(一個程式或另一個共享庫)顯式載入的“插件”庫,它是.so的單一格式檔案,或者為.bundle的包(如果有相關資源的話,實際上包中的主程式也是.so格式的庫)。它被稱為MH_BUNDLE。比如ODBC Driver在Mac上一般應該被編譯為這種格式,這樣它才能被ODBC Driver Manager(也是一個共享庫,請參見軟體開發技術科普之一)顯式載入。MS Office的Mac版中的一些.bundle包也是這種格式的動态庫。
用XCode 2.2以上版本編譯MH_BUNDLE有些麻煩,曾一度被懷疑為Bug,并在國外一些知名蘋果軟體開發論壇或郵件清單中有相關的讨論,做法如下:
1、輕按兩下Targets中的項目
2、彈出Target Info對話框,切換到Build頁籤以修改其中的選項(每個選項均對應一個GCC 4的編譯選項)
3、将Mach-O Type改為bundle
4、此時如在XCode 2.2以上(我用的是2.4)中編譯會遇到編譯器錯誤:-compatibility_version only allowed with -dynamiclib,無法link。
5、打開Target Info對話框,在build面闆中找到Current Library Version項,預設值為1,單擊Edit,清空随後彈出的下拉對話單(sheet window)中的内容,注意直接将1删除是沒用,XCode還會把它改回來。
6、再次編譯,遇到錯誤-current_version only allowed with -dynamiclib
7、回到Target Info對話框,找到并用同樣的辦法清空Compatibility Version。
8、第三次編譯,會顯示-single_module or -multi_module flags can only be used when -dylib is also specified錯誤。
9、再次回到Target Info對話框,在build面闆中找到Perform Single-Object Prelink,将其選中。
10、這次編譯應該能通過了,在編譯前,最好将Executable Extension(檔案擴充名)改為.so。
11、可以在Build Results視窗(單擊主視窗右下角──狀态欄最右邊的連結)中,将編譯設定改為release,編譯之——成功!
原載:http://www.3exware.com/home/default.asp?id=22