2011-03-12 16 views
13

重新編譯和Xcode 4一個C++的iPhone應用程序,我得到這個討厭的連接錯誤連接錯誤?如何使它消失將是很好過,當然:)「壞的代碼生成,指針差異」和Xcode 4

編譯&的應用程序沒有錯誤在Xcode鏈接3.

編輯:解決的辦法是設置符號隱藏的默認是項目中所有目標的所有構建設置中的。仍然沒有明智的問題是什麼。

+0

謝謝!也解決了我 - 我也不明白! –

回答

18

解決的方法是將Symbols Hidden By Default設置爲在項目中所有目標的所有構建設置中。仍然沒有明智的問題是什麼。

+0

......越來越......全球弱勢符號後衛變量......用於提升東西,而且這樣做的確有訣竅。非常感謝 – ort11

4

我遇到了這個問題,同時試圖將boost庫包含在我的一個項目中。找到這篇文章後,設置Symbols Hidden By DefaultYes也爲我解決了這個問題。而且我還必須在每個相關項目中進行相同的設置以徹底擺脫錯誤。

只是FYI - 這隻發生在我使用鏗鏘++堆棧的目標上。 GCC和LLVM + GCC目標似乎不受影響。

+0

使用GCC或LLVM + GCC也爲我工作。將'默認隱藏符號'改爲'是'似乎沒有改變任何東西。 – Andrew

5

我有同樣的問題,並最終調整可見性設置。然而,我很緊張,只是擺弄了符號的可見性,不理解問題,所以我做了一些更多的調查。

如果和我一樣,您正在使用Pete Goodliffe的腳本/包來構建boost作爲框架,該腳本會將默認可見性設置爲隱藏(== yes)。可見性選項更改編譯器標記符號的方式(默認,隱藏,內部)。鏈接器在製作共享對象elf(共享庫)時使用該信息。它不應該在這裏適用,所以我懷疑這是一個鏈接器錯誤。在boost庫內部,有一個標記爲隱藏的弱符號,然後在項目/另一個庫中標記爲默認的相同符號。鏈接器很困惑?

至於XCode 3與4,也許默認的3是隱藏符號?

在任何情況下,將默認可見性更改爲隱藏應該只對涉及到的靜態庫沒有影響,所以我覺得采用這個路由更安全。

對於那些感興趣的人,我已經在blog entry中發佈了一些更多的細節。

+0

Thx Tyler這裏有一些很棒的信息! – Stoff81

+0

+1實際描述問題的研究,而不是給貨物邪教答案! –

2

基本上,您鏈接到&您自己的代碼中的任何符號都需要使用相同的可見性級別,即如果您包含的庫中的所有符號都是隱藏的,則需要確保包含引用項目不要嘗試將其設置爲可見。最安全的做法是在整個項目中保持不變的默認可見度,對我來說,它只是成爲優化問題。

1

也許您正在使用具有隱藏符號信息的庫。如果符號尚未從庫中導出,並且您試圖在外部使用它,則會導致類似的鏈接器錯誤。正確的解決方案似乎是找到一種方法,通過GCC宏定義使外部世界可以「看得見」這個符號和/或修改庫本身以確保該特定符號真正被外部世界「隱藏起來」 - 即它不是在頭文件中被使用或暴露的東西。

但是,請謹慎行事:根據Apple文檔,您不應因多種原因隱藏某些符號信息;下面這一個上市似乎是最令人擔憂的一羣:

If your symbol uses runtime type identification (RTTI) information, exceptions, or dynamic casts for an object that is defined in another library, your symbol must be visible if it expects to handle requests initiated by the other library. For example, if you define a catch handler for a type in the C++ standard library, and you want to catch exceptions of that type thrown by the C++ standard library, you must make sure that your typeinfo object is visible.

來源:http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html

因此,如果你想趕上從你對鏈接庫中的例外,似乎隱藏符號信息是一個不好的選擇。正確的解決方案將取消隱藏您鏈接到的任何庫的符號。這可以通過省略以下GCC編譯器標誌來完成:

-fvisibility=hidden --fvisibility-inlines-hidden

(默認的知名度應該是足夠了),或者也有編譯器編譯指示,讓你做到這一點。參見:http://gcc.gnu.org/wiki/Visibility