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后,逗号和等号可以起到类似作用。

时间: 2024-10-21 12:54:49

makefile与动态链接库案例分析——动态库链接动态库的相关文章

解决遇到动态库链接静态库

场景: 二进制Link-->动态库-->第三方静态库 Linux环境中需要动态库链接第三方的静态库 错误: /usr/bin/ld: ../../3rdpart/x64/muduo/lib/libbase.a(AsyncLogging.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC ../../3rdpart/x64/mu

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

Background MSDN中对于在不同的配置下Link的LIB作了说明: C Runtime Library: 开关 对应的库 版本 /MD MSVCRT.LIB 多线程DLL的Release版本 /MDd MSVCRTD.LIB 多线程DLL的Debug版本 /MT LIBCMT.LIB 多线程静态链接的Release版本 /MTd LIBCMTD.LIB 多线程静态链接的Debug版本 /clr MSVCMRT.LIB 托管代码和非托管代码混合 /clr:pure MSVCURT.LIB

Makefile 编译动态库文件及链接动态库

本文为原创文章,转载请指明该文链接 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5 dynamiclib/Makefile 6 dynamiclib/dynamiclib_add.c 7 dynamiclib/dynamiclib_mul.c 8 dynamiclib/inc/dynamiclibs.h 9 dynamiclib/libs/ 1. dynamiclib目录 dynamic

gcc链接g++编译生成的静态库和动态库的makefile示例

使用c++开发程序或者库时,将库提供给其他人使用. 然而使用者是使用c开发的程序,链接g++编译生成的库时,于链接gcc生成的库,有所不同. 首先是静态库,以链接g++编译生成的libmylib.a为例子 mylib依赖于pthread,rt,math库,链接时必须放在mylib之后. 同时-Wl,--no-as-needed -ldl添加在末尾是必须的. arm和x86有些不同,就是arm的gcc不会自动链接数学库math,需要手动添加链接. 1 CC=arm-linux-gnueabihf-

【转】分析Linux和windows动态库

原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系统的动态库由 于格式不同,在需要不同操作系统调用时需要进行动态库程序移植.本文分析和比较了两种操作系统动态库技术,并给出了将Visual C++编制的动态库移植到Lin

Linux 静态链接库和动态连接库

(0)文件夹 VMware 下安装Ubuntu的吐血经历 零基础学习Shell编程 Linux下的makefile的妙用 Linux调试神器 -- gdb 十分钟学会Python的基本类型 Linux 静态链接库和动态连接库 一:静态链接库的应用  三步走~~~ ##g++ -c StaticMath.cpp ##ar -crv libstaticmath.a StaticMath.o ##g++ -o run test_a.cpp -L. -lstaticmath #[@sjs_37_33 l

linux学习 建立静态库,动态库,写简单的makefile

建立静态库 建立四个文件 bin(可执行文件),lib(库),include(头文件),src(放源文件) 这里的起的库明为add 在src文件中执行 1)gcc -c add.c //编译add.c源文件生成add.o目标文件 2)ar crsv ../lib/ libadd.a add.o //对目标文件*.o进行归档,生成lib*.a, 把这个生成文件放在lib里 3)gcc -o main main.c -L(大些的爱偶,放库的路径)../lib   –l(小写的爱偶,库名为add) a

线程高级应用-心得4-java5线程并发库介绍,及新技术案例分析

1.  java5线程并发库新知识介绍 2.线程并发库案例分析 1 package com.itcast.family; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 import java.util.concurrent.TimeUnit; 6 7 public class ThreadPoolTest { 8 9 /** 10 * @param args

Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别

昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [[email protected] tcpmsg]# gcc -o hello main.c -lmyhello /usr/bin/ld: cannot find -lmyhello collect2: error: ld returned 1 exit status 1 gcc链接动态库时的搜索路径 自以为在当前工程中设置好了环境变量 LD_LI