2015-09-30 225 views
0

我正在一個非常大的C++項目中創建一個大的共享對象,我們在這裏使用一個外部SDK,其中有幾個頭文件和幾個共享庫,它們都屬於對方。這意味着SDK類的聲明在頭文件中,但它們的定義在共享對象中。將共享對象鏈接到其他共享對象C++項目

據我所知,由於頭文件中的聲明我可以編譯這段代碼。

但我不明白的是什麼時候我必須明確指定鏈接器使用的共享對象?

即如果我指定它(例如,在與target_link_libraries命令cmake的),則鏈接器可以檢查一個符號將在共享庫或沒有。但是如果我沒有指定它會發生什麼(即鏈接中沒有任何-l [shared_object_name]標誌)?我的經驗是(令我感到驚訝的)是正常工作(即整個建築過程已完成)。它怎麼可能?

+0

一些編譯器,如Microsoft-VC有一個'#pragma',它允許你在源代碼中指定編譯器和鏈接器選項。 Boost使用它根據編譯器宏自動選擇正確的共享庫。 – rodrigo

+0

我們在linux下使用GCC,不使用#pragma :( –

回答

3

在POSIX共享庫中,您可以在共享庫中有未定義的符號,並且所有鏈接都可以很好地鏈接。只要可執行文件完全鏈接,就不會有鏈接程序錯誤。

這樣做是因爲動態庫模仿靜態庫的行爲,而靜態庫可能有未定義的符號(靜態庫沒有鏈接,開始)。

如果你來自Windows的背景,那麼它會讓你感到意外,因爲Windows DLL不能有未定義的符號。

如果您擔心這一點,您可以檢查鏈接選項--no-undefined--no-allow-shlib-undefined

+0

這意味着在可執行文件中它必須鏈接我的共享對象和共享對象中使用的共享對象?相反,我的共享對象無法找到使用的符號的主體。 –

+0

@TiborTakács:是的。您的共享對象不是_trying_來查找其他共享對象中的符號。這一切都得到解決時,你建立一個實際的可執行文件 –

+0

@TiborTakács:如果第二個SO中的第一個SO鏈接,它會在第一個SO頭中添加一個「NEEDED」條目,這樣當該exe鏈接到第一個SO時,第二個SO將自動鏈接。但是如果你連接第一個SO而沒有第二個SO,那麼EXE將需要鏈接到兩者,否則它將失敗。 – rodrigo

2

我的經驗是(令我感到驚訝的)工作正常(即整個建築過程完成)。

這似乎不太可能。

實際上...... hellip;

這怎麼可能?

不是。

唯一的解釋是你使用的符號在不是這些庫文件中定義的符號。它們或者只在第三方代碼的標頭部分,或者根本不屬於第三方代碼。

或者您正在構建您自己的共享庫。不過,最終的可執行文件仍然需要鏈接第三方庫。

+1

我也在創建一個共享庫,這是一個原因嗎? –

+0

@TiborTakács:是的,這是一個至關重要的細節,應該從一開始就在問題中現在,我的答案的原始最後一段是你要找的。 –