2012-09-27 26 views
6

我試圖找到包含一個可選類(比如ClassA)的靜態庫(讓我們稱之爲Lib1)的最佳方法),它本身需要第二個靜態庫(Lib2)。換句話說,只有在項目代碼中引用了ClassA時才需要Lib2。事情似乎沒問題,除非Lib1用於不使用ClassA的項目(因此不包含Lib2),但需要-ObjC鏈接器標誌(因爲其他項目依賴項,而不是我的)。ObjC:如何編譯包含依賴於第三方庫的可選類的靜態庫

我試圖想出了以下三種情況的一個簡單的解決方案:
1)項目包括我的靜態庫,不使用可選的類,不指定-ObjC標誌
2)項目包括我的靜態庫,不使用可選類,但需要-ObjC標誌
3)項目包括我的靜態lib +第二個靜態庫,並且使用可選類(我們不關心-ObjC標誌位於這一點)

是否有鏈接器標誌出那裏剝離我的可選類出最後的項目應用程序,以便它不需要第二個靜態庫?我想我的其他選擇是發佈我的靜態庫的多個版本,其中一個包括選項類(標準選擇),一個不支持(替代方案,用於具有-ObjC需求的項目),或者提供一個存根文件,提供第二個靜態庫所需的所有類的空實現?這似乎可能是靜態庫世界中的一個常見問題......這種情況下是否有最佳做法?

謝謝!


解決方法:

1)推薦給我的-ObjC用戶,他們使用-force_load代替。 (感謝羅布!)
2)對於用戶來說是無法做到1,我有一個備用的構建不包括ClassA的

回答

6

的最佳做法是始終有所需的所有靜態庫最終的二進制鏈接。你永遠不應該將一個靜態庫捆綁到另一個庫中您絕對不應該將知名(即開源)靜態庫捆綁到您發佈的靜態庫中。這可能會給最終用戶帶來令人難以置信的頭痛,因爲他們可以用相同代碼的多個版本結束。追蹤可能由此產生的錯誤非常困難。如果他們幸運的話,他們只會弄亂編譯器錯誤。如果它們不吉利,它們的代碼將以不可預知的方式運行並隨機崩潰。

分別運送所有靜態庫。告訴你的客戶他們需要鏈接各種配置。試圖避免這種情況只會讓他們的生活變得困難。

其他一些討論,可能是有用的:


-ObjC標誌應該防止自動剝離全部是ClassA,無論是否使用(更多詳情見TN1490)。

如果ClassA從來沒有使用,除非在某些情況下,並且您想節省空間,您應該將ClassA移動到它自己的靜態庫中。或者使用#ifdef來有條件地編譯它。

或者,您可以刪除-ObjC標誌並使用-force_load來單獨加載任何僅限類別的編譯單元(問題-ObjC用於解決此問題)。

+0

感謝您的鏈接,他們幫助我更充分地理解了靜態庫的構成! –

+0

我實際上並沒有將任何靜態庫綁定到我的靜態庫中。在我的靜態庫(稱爲Lib1)中,我有一個類(說ClassA),依賴於另一個靜態庫(Lib2)被鏈接到應用程序。除非包含Lib2,否則ClassA將永遠不會使用。看起來,編譯器/鏈接器足夠聰明,可以從最終應用程序中去除ClassA(如果未使用)。但是,如果指定了-ObjC鏈接器標誌,則編譯器/鏈接器將嘗試解析ClassA的Lib2依賴項,但不能......無論應用中是否曾引用過ClassA。我希望有一個魔術鏈接器標誌,可以去掉ClassA –

+1

更新了一些想法。解決這個問題並不容易。 ObjC是高度動態的,它在運行時以鏈接器在鏈接時無法看到的方式完全正常於引用類(以這種方式完成了nib加載)。如果您將所有內容都放在同一個文件中,而不傳遞單獨的-force_load參數而不是傳遞大的-ObjC參數,則鏈接器很難獲得此權限。 –