2012-07-09 127 views
1

我正在使用g ++在linux上使用C++應用程序。我的應用程序鏈接在共享庫中,公開了我需要的簡單API。該庫在內部引用大量額外的共享庫。我必須找到每一個,並將它們添加到我的Makefile以使它們鏈接。刪除鏈接器依賴關係

我假設我的應用程序必須鏈接到主庫所依賴的任何庫。解決這個鏈接需求的唯一方法是將主lib編譯到所有依賴關係的靜態庫中?這是否適用於通過dlopen/dlsym使用插件模型?

TY

回答

-1

我想我的應用程序有鏈接到任何主要的lib依賴於庫中。解決這個鏈接需求的唯一方法是將主lib編譯到所有依賴關係的靜態庫中?

當然。沒有辦法繞過:靜態鏈接,或者在庫運行時搜索路徑中使用庫(正確版本,如果不是ABI兼容的話)。

這是否適用於通過dlopen/dlsym使用插件模型?

不需要。爲此,您需要在要加載它的路徑中共享庫。

4

解決此鏈接需求的唯一方法是將主lib編譯到所有依賴關係的靜態庫中?

否。共享庫本身可以鏈接到它所依賴的共享庫。大多數連接器也會選擇這些庫,並將您的可執行文件鏈接到這些庫,而不必在鏈接器階段提及它們。

就你而言,這聽起來像共享庫沒有鏈接到它所需的庫。 ldd工具在這方面可能很有用。

舉個例子,假設你產生這種共享庫:

gcc -shared foo.o -o libfoo.so -lm 

現在libfoo.so鏈接到數學庫(libm中)。掛libfoo.so的 任何應用程序將被鏈接到libm爲好,即你只需要做

gcc -o prog main.o -lfoo 

如果在另一方面,共享庫並沒有鏈接到lib中,但只有製作

gcc -shared foo.o -o libfoo.so 

你必須明確地鏈接鏈接應用程序時到libm:

gcc -o prog main.o -lfoo -lm 

當你dlopen()的共享庫,運行時鏈接程序將加載所有共享庫的庫也被鏈接 - 除非它們已經被加載。因此,如果你的dlopen()沒有鏈接到它依賴的庫,並且你的可執行文件沒有鏈接到這些庫,dlopen()將失敗(除非你指定RTLD_LAZY,在這種情況下,以後會失敗)

1

我假設我的應用程序必須鏈接到主庫所依賴的任何庫。

這聽起來好像無論你的應用程序直接使用這些符號(不只是間接地通過API共享庫)是共享庫沒有被正確連接,所以它不掛庫這取決於。如果創建共享庫時,其依賴鏈接與-l鏈接,那麼當將應用程序鏈接到API庫時,它會導致它們自動鏈接。

解決此鏈接需求的唯一方法是將主lib在所有依賴關係的靜態庫中編譯?

這是一種方式,但不是唯一的方法。

這是否適用於通過dlopen/dlsym使用插件模型?

只要插件是正確鏈接到庫它們依賴於...沒有,在這種情況下鏈接器不可能知道什麼LIBS你會dlopen在運行時間,所以無法知道他們的依賴關係是什麼,所以你不需要在鏈接時對它們進行命名。如果事先不知道所有可能會被加載的插件,都是不可能的。

如果插件庫沒有正確鏈接,嘗試使用dlopen時會遇到同樣的問題。