2009-11-19 56 views
2

我打算髮布一些編譯後的代碼,這些代碼將由MacOSX上的客戶端應用程序鏈接。在OSX上分發二進制庫

該分佈是某種代碼庫和一組定義庫的公共接口的頭文件。代碼是內部C++,但其公共接口(即標頭中顯示的內容)完全是C.

這些都是我的要求或至少我希望我能做到:

  • 我想我的圖書館是爲不可知 儘可能什麼OSX 的版本和GCC用戶運行。雖然有 單獨的庫爲64位和32 位是好的。
  • 我希望我的庫 可以從 支持加載C庫(例如 python或類似文件)的語言加載。
  • 我希望我的 庫的內部符號是從 鏈接到的代碼中分離出的 。我不想 重複的符號錯誤,因爲我們 恰巧以相同的方式命名內部函數 。我的C++代碼是正確命名空間的,所以這可能不是一個大問題,但我依賴的一些庫是C並且可能是一個問題(見下一點)。
  • 我想我的庫 依賴關係是安全的。我的圖書館 取決於一些庫如 的libpng,升壓和STL,我不希望 的問題,因爲許多用戶並不 一定個個安裝 或得到的問題,因爲他們已經 編譯與其他標誌或 與我有不同的版本。

在Windows上,我使用帶導出庫的DLL,並將所有依賴關係靜態鏈接到dll。它符合上述所有條件,如果我可以在OSX上得到相同的結果,那將是非常好的,但是我聽說動態庫往往不以同樣的方式在mac上隔離符號。

在OSX上有這種最佳實踐嗎?

回答

2

一個正常的OS X.dylib幾乎可以滿足你的要求,注意你需要一個導出文件,鏈接器用它來確定導出哪些符號(以防止泄漏你的內部符號)。

爲了使您自己的庫依賴性安全,您可能需要將這些庫包含在您的庫中,或將它們靜態鏈接到庫中。

編輯:爲了回答如何應用exports文件的鏈接命令的後續問題,爲ld手冊頁有以下說:

-exported_symbols_list filename 
    The specified filename contains a list of global symbol names 
    that will remain as global symbols in the output file. All 
    other global symbols will be treated as if they were marked 
    as __private_extern__ (aka visibility=hidden) and will not be 
    global in the output file. The symbol names listed in file- 
    name must be one per line. Leading and trailing white space 
    are not part of the symbol name. Lines starting with # are 
    ignored, as are lines with only white space. Some wildcards 
    (similar to shell file matching) are supported. The * 
    matches zero or more characters. The ? matches one charac- 
    ter. [abc] matches one character which must be an 'a', 'b', 
    or 'c'. [a-z] matches any single lower case letter from 'a' 
    to 'z'. 

所以,如果您的圖書館只有兩個你想要公開的函數,我們稱它們爲foobar,它們是C函數(所以符號名不會被損壞),你的輸出文件(我們稱之爲myLibrary.exports)將包含這兩行:

_foo 
_bar 

並且可能還有一些註釋等。當您執行構建庫的最後一個鏈接步驟時,您會將-exported_symbols_list myLibrary.exports標誌傳遞給鏈接器。這還有另外的好處,即如果你不提供一個導出的符號,鏈接將會失敗;這可以捕捉到很多「哎呀,我忘了把這個文件包含在構建中」的錯誤。

當然,您不需要使用命令行工具來執行所有操作。在XCode動態庫的構建設置中,您會發現Exported Symbols File(默認情況下未定義);將其設置爲您的導出文件的路徑,並將其傳遞給鏈接器。

+0

這似乎是一個很好的解決方案。關於如何創建導出文件,您有沒有很好的參考? – Laserallan 2009-11-19 23:52:34

+0

我添加了一些關於如何使用導出文件的細節;關於如何創建一個,如果庫不是太大,我通常使用nm來獲取所有符號的列表,然後刪除那些我想保持私有的。對於大型項目,這不是一個真正可行的方法,所以我通常編寫腳本來爲我生成文件。 – 2009-11-20 01:42:54

+2

另請注意,不需要單獨的32位和64位庫; OS X允許支持多種體系結構的dylib。從命令行看起來有些複雜,但如果你使用XCode,它應該是Just Work。 – 2009-11-20 01:45:08

1

您需要的關鍵詞是'框架'。您需要創建一個獨立的「通用」框架。 ('通用'是蘋果易於'編譯多次並封裝到一個庫中。)它不像封裝那樣直接在Windows上,但必要的鏈接器選項就在那裏。