天天看點

【原創】Linux下共享庫嵌套依賴問題

問題場景: 

動态庫 librabbitmq_r.so 内部依賴動态庫 libevent_core.so 和 libevent_pthreads.so ;

可執行程式 sa 依賴動态庫 librabbitmq_r.so ;

在連結生成 sa 的時候希望隻指定 librabbitmq_r.so 而不指定 libevent_core.so 和 libevent_pthreads.so 。

錯誤資訊: 

      由錯誤資訊可以看出,未找到的符号均屬于 libevent_core.so 和 libevent_pthreads.so 内部。但這兩個庫确實存在于 -l../../../../10-common/lib/release/linux 路徑下,但為什麼連結器仍舊無法找到對應的庫和符号呢? 

下面的文章讨論了這個問題(下面給出部分摘錄)

... 

you system, through ld.so.conf, ld.so.conf.d, and the system environment, ld_library_path, etc.., provides the system-wide library search paths which are supplemented by installed libraries through pkg-config information and the like when you build against standard libraries.  

there is no standard run-time library search path for custom shared libraries you create yourself. you specify the search path to your libraries through the -l/path/to/lib designation during compile and link. for libraries in non-standard locations, the library search path can be optionally placed in the header of your executable (elf header) at compile-time so that your executable can find the needed libraries. 

rpath provides a way of embedding your custom run-time library search path in the elf header so that your custom libraries can be found as well without having to specify the search path each time it is used. this applies to libraries that depend on libraries as well. as you have found, not only is the order you specify the libraries on the command line important, you also must provide the run-time library search path, or rpath, information for each dependent library you are linking against as well so that the header contains the location of all libraries needed to run. 

back to the semantics of ld. in order to produce a "good link", ld must be able to locate all dependent libraries. ld cannot insure a good link otherwise. the runtime linker must find and load, not just to find the shared libraries needed by a program. ld cannot guarantee that will happen unless ld itself can locate all needed shared libraries at the time the progam is linked. 

結論就是,像這種 a.so 依賴 b.so ,而 c 依賴 a.so 的情況,在連結過程中需要通過 -rpath-link 指定所需 .so 的位置,而不能僅僅使用 -l 指定。 

示例如下: 

【say_hello.c】 

【say_hello.h】 

【time_print.c】 

【time_print.h】 

【main.c 】 

生成兩個 .so 庫 

若不指定 -rpath-link 選項,則連結失敗 

若指定 -rpath-link 選項,則可以成功連結 

檢視一下共享庫依賴關系 

執行程式 

繼續閱讀