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


http://blog.csdn.net/huqinwei987/article/details/50517780

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

 

 

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

引用庫中加入Libmdpha

同時加

        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找不到那些動態庫別名。

然后就是在主工程中做那些相應的別名。

本着負責的原則,重現了下,路徑不對的后果如下,需要同級的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后,逗號和等號可以起到類似作用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM