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,好像是libmdpha中的so.2和so.3之類的,在主工程沒有,因此WARNING找不到那些動態庫別名。效率
而後就是在主工程中作那些相應的別名。file
本着負責的原則,重現了下,路徑不對的後果以下,須要同級的lib下,其實在主工程中庫全在同級路徑
在Libmdpha的makefile指定了libmdpha.so依賴的庫和路徑../lib
可是在dds主工程中,倒是同級關係,因此兩個編譯腳本和路徑設置必須有個妥協,因此把Libmdpha的依賴庫路徑改了,源與目的在一塊兒,看起來亂一點,這樣卻是不用主工程dds以及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後,逗號和等號能夠起到相似做用。