linux 动态库 版本号,软链接SONAME的编译选项

摘自:https://www.csdn.net/tags/MtTaEgysMzQ2MDMtYmxvZwO0O0OO0O0O.html

Linux下动态库有三个名字:real name、so name、link name。

  • real name:共享库本身的名字,命名格式为libname.so.x.y.z,lib是前缀,name是共享库的名字,so是后缀,x是主版本,y是次版本号,z是发布版本号。

         主版本号、次版本号和发布版本号的意义如下:

  1. 主版本号:表示库的重大升级,比如改变了原有的接口。不同主版本号的库是不兼容的,要保证向下兼容就不能删除旧版本的动态库。
  2. 次版本号:表示库的增量升级,比如增加了新的接口,但原有接口保持不变。高的次版本号的库向下兼容低的次版本号的动态库,原有的版本库是可以不保留的。
  3. 发布版本号:表示指示改正了一些错误或者是性能优化等,接口没有增加,也没有改变,因此也是向下兼容的。
  • so name:是通过ldconfig命令,来创建的指向真正的动态库(real name)的链接,so name的命名规则是,real name去掉次版本号和发布版本号,格式为libname.so.x。
  • link name:是so name的软链接,命名规则是,real name去掉主版本号、次版本号和发布版本号,格式为libname.so,编译时,通过参数-lname来链接。

下面通过实际的例子来说明动态库的编译和链接:

首先,建立hello.c和hello.h两个文件,然后将他们编译成动态链接库。

hello.c文件:

#include <stdio.h>

void hello (void)
{
    printf("Hello, library world.\n");
}

hello.h文件:

#ifndef __HELLO_H__
#define __HELLO_H__

void hello (void);

#endif

执行如下命令,编译生成共享库

$gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0

编译完成后,只生成了libhello.so.0.0.0,并未生成libhello.so.0,若要生成libhello.so.0需要做如下操作:

在/etc/ld.so.conf文件中指定库的路径,在文件中添加:libhello.so.0.0.0这个库所在的绝对路径。

执行如下命令生成libhello.so.0:

$sudo ldconfig

下面需要为libhello.so.0建立一个软链接,方便编译应用程序是链接,执行如下命令:

$ln -s libhello.so.0 libhello.so

然后,编写应用程序来调用动态库。

main.c文件:

#include "hello.h"

int main(void)
{
    hello();
    
    return 0;
}

执行下面的命令编译生成main的可执行文件:

$gcc main.c -L. -lhello -o main

注:没有重大升级(主版本号未更改),编译新版本的动态库后,执行$sudo ldconfig就可以进行动态库的升级。如果进行重大升级(更改主版本号),编译新版本的动态库后,执行$sudo ldconfig,生成新的so name文件,再执行$ln -s libhello.so.1 libhello.so(主版本号升级为1).如果想重新恢复为旧版本的动态库,只需要执行$ln -s libhello.so.0 libhello.so

posted @ 2022-11-10 16:37  LiuYanYGZ  阅读(983)  评论(0编辑  收藏  举报