簡體   English   中英

我如何知道要鏈接哪些庫?

[英]How do I know which libraries to link against?

有沒有辦法(在Linux中)確定哪些庫必須鏈接到C / C ++程序? 即使在程序啟動時未檢測到未定義符號的情況下,我也不想錯過庫。 另外,我當然希望避免不必要的依賴。

我總體上提出了這個問題,但這里有一個特別的,非常重要的例子:直到最近,我認為我需要鏈接libpython用於使用Boost.Python開發的Python模塊。 但是,事實並非如此:使用Boost.Python編寫模塊; 它甚至可能使用Python C API中的函數,而不僅僅是Boost.Python。 鏈接libboost_python就足夠了! 這根本不是很明顯 - 我至少沒有找到它的文檔,而且還有Boost.Python模塊,它們不必要地鏈接到libpython 此外,這很難檢測,因為libboost_python.so沒有將libpython列為ldd報告的依賴項。 (我相信在這個實例中動態加載Python庫。)

[ 后來添加:這與Boost.Python無關。 此外,如果使用低級Python C API,則可以編譯Python模塊,而不是與libpython鏈接,它將起作用。 但是,請參閱下面的評論和答案,說明應該鏈接到libpython

那么,我怎么能系統地發現不必要的鏈接而不是使用反復試驗呢? 什么是一個很好的通用程序,不僅僅是這個例子?

[ 后來補充:這是我從評論中學到的問題。 當我發布這個問題時,下面的事實對我來說並不清楚,所以我現在將它們拼出來,以便將來訪問此討論的人受益,即使這些事情對於有用的評論者來說是顯而易見的。 (謝謝!)

解析符號在Linux中以傳遞方式工作(如用戶MvG和millimoose所指出的)。 假設程序A需要解析來自libBlibC的符號。 進一步假設A是針對libB相連,libB是對的libC鏈接。 然后可以加載即使它沒有直接提及到libc執行。

然而,正如評論者指出的那樣,依靠這種傳遞性是不好的做法。 對於用C / C ++編寫的Python模塊,這意味着應該鏈接libpython 對於一般情況下,我們的目標應該是確定的鏈接和執行,為我的一部開拓創新的問題在某種程度上暗示,但真正提供鏈接必要的庫,以便所有的符號可以直接解決需要的庫的最小列表。

總結Salgar的答案,這些信息通常只能從所用庫的文檔中獲得。 此外,GCC鏈接器標志-Wl,--as-needed對於識別真正不必要的庫非常有用。

沒有辦法神奇地知道要包含哪些庫,就像沒有辦法神奇地知道要包含哪些頭。

可能有10個不同的庫,它們都具有相同名稱的功能,所有這些都完全不同。 由您決定要使用哪一個。

通常情況並非如此,但它是一個示范點。

通常,如果您使用的是boost庫或其他類似的庫,那么他們的文檔會告訴您需要鏈接哪個庫。

正如上面所說的那樣,你可以過度包含和使用標志--as-needed,但很多人都有問題,因為通常當你鏈接到一個庫時,它會在啟動時被拉入並且來自該庫的所有全局變量初始化。 是否需要這些全局變量對於鏈接器來說可能是一件令人困惑的事情。

簡而言之,答案通常是閱讀文檔。 或者編譯代碼並查看您獲得的鏈接器錯誤,然后從那里開始工作以確定您需要哪些庫。

沒有任何/瑣碎的方法,但你可以通過使用像CMake或AutoConf這樣的構建管理工具讓自己變得更容易。

構建Boost時,您可以選擇構建已編譯的庫的靜態或動態版本。 自從我構建了boost之后已經有一段時間了,但是如果我記得它可以構建兩種風格,如果你只是簡單的構建。

這包含在:

關於boost.python,這里記錄了靜態或動態庫鏈接之間的選項:

動態庫是最安全,最通用的選擇:

  • 使用給定工具集構建的所有擴展模塊都使用庫代碼的單個副本。該庫包含類型轉換注冊表。 因為一個注冊表在所有擴展模塊之間共享,所以在一個動態加載的擴展模塊中暴露給Python的類的實例可以傳遞給在另一個這樣的模塊中公開的函數。

在以下任何一種情況下使用靜態Boost.Python庫可能是合適的:

  • 您正在擴展 python,並且動態加載的擴展模塊中公開的類型不需要被任何其他Boost.Python擴展模塊使用,並且您不關心核心庫代碼是否在它們之間重復。

  • 您正在應用程序中嵌入python並且:

    • 您的目標是除MacOS或AIX之外的Unix變體操作系統,其中動態加載的擴展模塊可以“查看”作為可執行文件一部分的Boost.Python庫符號。

    • 或者,您已將某些Boost.Python擴展模塊靜態鏈接到您的應用程序中,並且您不關心任何動態加載的Boost.Python擴展模塊是否能夠使用由靜態鏈接的擴展模塊公開的類型(反之亦然) )。

所以,如果被授予,這並不能解釋你如何知道通用意義上的鏈接。 只是那個具體情況。

我認為關於boost.python如何工作以及人們在鏈接方面評論的不同體驗的困惑可能會讓你更有意義,至少你看一下這個鏡頭。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM