makefile與動態連接庫案例分析——動態庫連接動態庫

http://blog.csdn.net/huqinwei987/article/details/50517780服務器

背景:效率考慮,要重用把服務器主備機方案,以庫Libmdpha(高可用)的形式加進主工程dds(調度數據服務器)。工具

 

 

有源代碼,打算直接編譯Libmdpha.so.xxx,加入主工程dds。複製動態庫libmdpha.so.xxx到主工程相關路徑,並改makefile,makefile中主要加複製命令和創建軟鏈接的命令,庫名注意統一:spa

引用庫中加入Libmdpha.net

同時加blog

        cp -f $(INTERFACES_PATH)/libmdpha/$(VER_libmdpha)/lib/libmdpha.so.$(VER_libmdpha).$(VER_libmdpha_SUB) ../lib/接口

        ln -sf ../lib/libmdpha.so.$(VER_libmdpha).$(VER_libmdpha_SUB) ../lib/libmdpha.so開發

Libmdpha庫放在dds主工程中,創建動態連接。編譯

 

WARNING

憑回憶寫,懶得復現了過於繁瑣,好比剛加入主工程時編譯的WARNING,好像是libmdpha中的so.2和so.3之類的,在主工程沒有,因此WARNING找不到那些動態庫別名。效率

而後就是在主工程中作那些相應的別名。file

本着負責的原則,重現了下,路徑不對的後果以下,須要同級的lib下,其實在主工程中庫全在同級路徑

 

 

 

會碰到兩個工程的路徑設置兼容問題

Libmdpha的makefile指定了libmdpha.so依賴的庫和路徑../lib

可是在dds主工程中,倒是同級關係,因此兩個編譯腳本和路徑設置必須有個妥協,因此把Libmdpha的依賴庫路徑改了,源與目的在一塊兒,看起來亂一點,這樣卻是不用主工程dds以及dds依賴的更多的庫了。

 

 

 

看似工做完成了。

 

可是。。。

可是,Libmdpha和dds7600工程依賴了相同的底層庫(log庫、工具庫、初始化庫等),版本卻不同(由於他們開發高可用庫的時候用的是那個時候的庫,如今dds用的新版本的庫)。

有兩種解決思路:

第一種方案:

庫文件全複製進去,主工程dds和主備庫Libmdpha各鏈接各的,xxx.so指向dds依賴的新版底層庫,xxx.so.1指向libmdpha依賴的舊版底層庫。互不干擾,缺點是兩個版本的底層庫都複製進去,臃腫,並且也混亂,久而久之,愈來愈亂,別人也會看不懂關聯這麼多怎麼回事。

 

第二種方案:

libmdpha換了依賴庫(和dds統一),從新編譯,好在有源代碼。

隱患是可能會錯,畢竟底層庫版本不一樣了,希望接口沒區別。

 

用了第二種方案:把和主工程同版本的底層庫放進去編譯,而後再把libmdpha往主工程裏放,而後用個和庫libmdpha的makefile設置相同的別名*.so.3或者*.so.2,而主工程原來依賴的別名爲*.so,由於已經統一了版本,實際上是同一個文件。


 

 

 

最後,編譯成功。

可是仔細看仍然有問題

#ldd

能夠看到

libmdpha庫依賴的這四個庫其實鏈空了,雖然編譯成功了,可是動態庫缺失可能會致使程序運行失敗。

 解決方法是繼續改libmdpha庫的makefile,加上rpath:

左圖是主工程的參考,右圖是未加rpath的libmdpha庫。

加後

 LFLAGS          = -w -shared -Wl,-soname,$(SO_NAME),-rpath=../lib

LFLAGS          = -w -shared -Wl,-soname,$(SO_NAME),-rpath,../lib

 

在GNU環境下,有-Wl後,逗號和等號能夠起到相似做用。

相關文章
相關標籤/搜索