// filename:hello.c
#include <stdio.h>
void hello(const char* name)
{
printf("hello %s, welcom to our world!n", name);
}
由于改动较小,我们编译动态库时仍然指定相同的soname
gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.2
将新的动态库拷贝到运行目录,此时运行目录结构如下
├── libhello.so.0 -> libhello.so.0.0.1 ├── libhello.so.0.0.1 ├── libhello.so.0.0.2 └── main
此时目录下有两个版本的动态库,但libhello.so.0指向的是老本版,运行ldconfig -n .后我们发现,链接指向了新版本,如下
├── libhello.so.0 -> libhello.so.0.0.2 ├── libhello.so.0.0.1 ├── libhello.so.0.0.2 └── main
再运行程序
$ ./main hello Handy, welcom to our world!
没有重新编译就使用上了新的动态库, wonderful!
同样,假如我们的动态库有大的改动,编译动态库时指定了新的soname,如下
gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0.0
将动态库文件拷贝到运行目录,并执行ldconfig -n . ,目录结构如下
├── libhello.so.0 -> libhello.so.0.0.2 ├── libhello.so.0.0.1 ├── libhello.so.0.0.2 ├── libhello.so.1 -> libhello.so.1.0.0 ├── libhello.so.1.0.0 └── main
这时候发现,生成了新的链接libhello.so.1,而main程序还是使用的libhello.so.0,所以无法使用新版动态库的功能,需要重新编译才行
总结
在实际生产环境中,程序的编译和运行往往是分开的,但只要搞清楚这一系列过程中的原理,就不怕被动态库的版本搞晕。简单来说,按如下方式来做
-
编译动态库时指定
-Wl, -soname ,libxxx.so.a,设置soname为libxxx.so.a,生成实际的动态库文件libxxx.so.a.b.c,
编译可执行程序时保证libxx.so存在,如果是软链,必须指向实际的动态库文件libxxx.so.a.b.c
运行可执行文件时保证libxxx.so.a.b.c文件存在,通过ldconfig生成libxxx.so.a链接指向libxxx.so.a.b.c
设置环境变量LD_LIBRARY_PATH,运行可执行程序
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。








