linux動態庫及動態庫的版本管理

Linux下動態庫有三個名字:real name、so name、link name。

  • real name:共享庫本身的名字,命名格式爲libname.so.x.y.z,lib是前綴,name是共享庫的名字,so是後綴,x是主版本,y是次版本號,z是發佈版本號。

         主版本號、次版本號和發佈版本號的意義如下:

         主版本號:表示庫的重大升級,比如改變了原有的接口。不同主版本號的庫是不兼容的,要保證向下兼容就不能刪除舊版本的動態庫。

          次版本號:表示庫的增量升級,比如增加了新的接口,但原有接口保持不變。高的次版本號的庫向下兼容低的次版本號的動態庫,原有的版本庫是可以不保留的。

發佈版本號:表示指示改正了一些錯誤或者是性能優化等,接口沒有增加,也沒有改變,因此也是向下兼容的。

  • 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章