makefile与动态链接库案例分析——动态库链接动态库

来源:互联网 发布:收视率惨淡知乎 编辑:程序博客网 时间:2024/06/05 14:28

背景:效率考虑,要重用把服务器主备机方案,以库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依赖的更多的库了。



看似工作完成了。


但是。。。

但是,Libmdphadds7600工程依赖了相同的底层库(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后,逗号和等号可以起到类似作用。




0 0
原创粉丝点击