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后,逗号和等号能够起到相似做用。