0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux下動態(tài)鏈接庫管理方式

冬至子 ? 來源:技術(shù)鋪子 ? 作者:chasenzhang ? 2023-01-18 12:35 ? 次閱讀

由一個問題談起,linux下的動態(tài)鏈接庫的名字后綴是so,但是我們有時候也會遇到下面的報錯

./a.out: error while loading shared libraries: libtest.so.1: cannot open shared object file: No such file or directory

動態(tài)鏈接庫的后綴不是so嗎?怎么會提示鏈接不到libtest.so.1呢?再看第一個例子,在linux下查看下bash的依賴庫,可以發(fā)現(xiàn)bash依賴的動態(tài)庫是libxxx.so.x的,不是常見的libxxx.so。

$ ldd /bin/bash
  linux-vdso.so.1 (0x00007ffedb129000)
  libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f135ae6b000)
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f135ac43000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f135b018000)

第二個例子,再比如OpenCV的so,可以看到,libopencv_aruco.so是libopencv_aruco.so.4.5的軟鏈接,libopencv_aruco.so.4.5是libopencv_aruco.so.4.5.4的軟鏈接,為什么會這樣設(shè)計呢?

$ ls -alh libopencv_*
lrwxrwxrwx 1 root root   22  9月 16 00:41 libopencv_aruco.so -> libopencv_aruco.so.4.5
lrwxrwxrwx 1 root root   24  9月 16 00:41 libopencv_aruco.so.4.5 -> libopencv_aruco.so.4.5.4
-rw-r--r-- 1 root root 428K  9月 16 00:41 libopencv_aruco.so.4.5.4
lrwxrwxrwx 1 root root   24  9月 16 00:41 libopencv_barcode.so -> libopencv_barcode.so.4.5
lrwxrwxrwx 1 root root   26  9月 16 00:41 libopencv_barcode.so.4.5 -> libopencv_barcode.so.4.5.4
-rw-r--r-- 1 root root 124K  9月 16 00:41 libopencv_barcode.so.4.5.4
lrwxrwxrwx 1 root root   23  9月 16 00:41 libopencv_bgsegm.so -> libopencv_bgsegm.so.4.5
lrwxrwxrwx 1 root root   25  9月 16 00:41 libopencv_bgsegm.so.4.5 -> libopencv_bgsegm.so.4.5.4

其實這是linux下的動態(tài)庫的版本管理方式引起的,這篇文章簡單討論下。根據(jù)網(wǎng)上查的資料,linux下的動態(tài)鏈接庫有下面三種:

第一個,real name,字如其名意思就是鏈接的真實的so名字,一般形式為:libname.so.x.y.z,具體的解釋引用鏈接的解釋

x是主版本號(Major Version Number),y是次版本號(Minor Version Number),z是發(fā)布版本號(Release Version Number), 并且它們具有以下要求。

主版本號(不兼容):重大升級,不同主版本的庫之間的庫是不兼容的,所以如果要保證向后兼容就不能刪除舊的動態(tài)庫的版本。

次版本號(向下兼容): 增量升級,增加一些新的接口但保留原有接口,高次版本號的庫向后兼容低次版本號的庫。

發(fā)布版本號(相互兼容):庫的一些諸如錯誤修改、性能改進(jìn)等,不添加新接口,也不更改接口,主版本號和次版本號相同的前提下,不同發(fā)布版本之間完全兼容。

第二個,soname就是linux版本管理的重要機(jī)制了。在編譯動態(tài)鏈接庫的時候,可以設(shè)置一個soname參數(shù)(通過-Wl,-soname設(shè)置),通過這個參數(shù),編譯器在鏈接的時候會根據(jù)這個SONAME去找對應(yīng)的動態(tài)庫。以庫的形式如下libtest.so.x.y.z來舉例,如果兩個庫可以兼容,,那么他們的x是一樣的,比如說libtest.so.1.0.0、libtest.so.1.0.1、libtest.so.1.1.1它們?nèi)齻€動態(tài)庫是互相兼容的,而libtest.so.1.0.0、libtest.so.2.0.1則是不兼容的。

設(shè)置soname的方式以及查看某個庫是否設(shè)置soname的方法, 如下命令

# 設(shè)置soname參數(shù)
$ g++ -fPIC b.cpp -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0
# 查看so是否有soname
$ readelf -d libtest.so.1.0 | grep SONAME
0x000000000000000e (SONAME)             Library soname: [libtest.so.1]

第三個,link name,就是用gcc或者g++編譯的時候,-l指定的so名字,比如說下面例子的-ltest

g++ main.cpp -L. -ltest

上面介紹了三類so,那么我們再來看下他們之間的關(guān)系,以及編譯器如何鏈接的。假如我們編譯一個OpenCV的程序,編譯命令

# 編譯出可執(zhí)行文件 a.out
$ g++ main.cpp -o a.out -I /usr/local/include/opencv4/ -L /usr/local/lib \\
  -lopencv_core -lopencv_videoio \\
  -lopencv_imgproc -lopencv_objdetect -lopencv_highgui


# 查看a.out的OpenCV依賴
$ ldd a.out | grep opencv
  libopencv_core.so.4.5 => /usr/local/lib/libopencv_core.so.4.5 (0x00007fe5d629c000)
  ......
# 查看opencv_core.so.4.5.4的soname
$ readelf -d /usr/local/lib/libopencv_core.so.4.5.4 | grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libopencv_core.so.4.5]

以opencv_core.so為例,core.so的軟鏈接是這樣的

libopencv_core->libopencv_core.4.5->libopencv_core4.5.4

編譯階段,編譯的時候制定鏈接的so,-lopencv_core.so(link name),鏈接的時候會根據(jù)軟鏈接關(guān)系找到libopencv_core4.5.4,讀取soname寫入到可執(zhí)行文件中。

運行時候,鏈接器讀取可執(zhí)行文件的soname,就是libopencv_core.4.5,再根據(jù)軟鏈接的關(guān)系,最終找到libopencv_core4.5.4(real name)

如果使用了這種動態(tài)庫管理方式,以O(shè)penCV為例,如果小版本升級,比如說4.5.4要升級到4.5.5,可以直接把libopencv_core.so.4.5重新指向libopencv_core.so.4.5.5,不需要重新編譯庫。如果大版本升級,因為大版本的接口可能不兼容,所以大版本升級要重新編譯。

如果一些比較簡單的so,可以不用soname這種機(jī)制,直接編譯出libtest.so鏈接上,這樣做事很方便,但是缺點是看不出版本的信息。

審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    625

    瀏覽量

    41218
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    316

    瀏覽量

    21608
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3348
收藏 人收藏

    評論

    相關(guān)推薦

    Linux動態(tài)鏈接庫的基本概念

    學(xué)習(xí)Linux動態(tài)鏈接庫是一個繞不開的話題,我們今天就一起來看一什么是動態(tài)鏈接庫
    發(fā)表于 09-27 14:31 ?1508次閱讀

    關(guān)于使用動態(tài)鏈接庫及圖像采集的問題

    我用的是方誠科技的工業(yè)相機(jī),里面提供了一些動態(tài)鏈接庫,包括了相機(jī)初始化,采集圖像,顏色處理等函數(shù),我以前都是用VB做的,買相機(jī)的時候他會提供VB的模塊,所以用VB比較方便。現(xiàn)在我想用LABVIEW做
    發(fā)表于 05-26 18:05

    labview調(diào)用動態(tài)鏈接庫問題

    本帖最后由 ZHZJK 于 2014-7-15 11:07 編輯 本人使用動態(tài)鏈接庫一直沒成功過,這次準(zhǔn)備調(diào)用讀卡器的dll來讀卡用了其中 打開串口 和讀取卡號 兩函數(shù)總是有錯希望大家?guī)兔纯?/div>
    發(fā)表于 07-15 11:01

    LabVIEW之動態(tài)鏈接庫

    問一大家,如何利用動態(tài)鏈接庫調(diào)用LabVIEW官方不支持的攝像頭?求高手指教!
    發(fā)表于 03-13 09:59

    關(guān)于labview'的動態(tài)鏈接庫的問題

    最近使用labview調(diào)用動態(tài)鏈接庫,使用vs2017生成dll文件,然后調(diào)用,但是為什么輸入數(shù)組的情況輸出一直為0呢,我使用公式節(jié)點調(diào)用同樣的c語言,就沒問題?請教大佬們怎么解決?還有我想問一
    發(fā)表于 03-14 11:26

    基于動態(tài)鏈接庫技術(shù)的感應(yīng)器非線性特性校正

    提出一種基于動態(tài)鏈接庫技術(shù)的傳感器非線性特性校正新方法。將傳感器是數(shù)據(jù)采集程序與傳感器的非線性特性校正算法置于同一個動態(tài)鏈接庫中,這樣應(yīng)用程序從動態(tài)
    發(fā)表于 06-25 09:55 ?26次下載

    C++中動態(tài)鏈接庫的創(chuàng)建和調(diào)用

    動態(tài)連接的創(chuàng)建步驟: 一、創(chuàng)建Non-MFC DLL動態(tài)鏈接庫 1、打開File —> New —> Project選項,選擇Win32 Dynamic-Link Library
    發(fā)表于 11-24 18:13 ?7次下載

    LINUX環(huán)境CLIPS動態(tài)鏈接庫的實現(xiàn)方法

    LINUX環(huán)境,為了簡便、快捷地制作出CLIPS動態(tài)鏈接庫,本文采用了CNU AUTOTOOLS把CLIPS嵌入式高級語言編譯成動態(tài)
    發(fā)表于 04-14 21:18 ?30次下載

    虛擬儀器中動態(tài)鏈接庫的應(yīng)用

    本文在闡述了動態(tài)鏈接庫技術(shù)和虛擬儀器中的 動態(tài)鏈接 機(jī)制的基礎(chǔ)上,詳述了基于DLL的USB接口虛擬儀器的設(shè)計的關(guān)鍵內(nèi)容。
    發(fā)表于 07-05 17:17 ?27次下載
    虛擬儀器中<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>的應(yīng)用

    VC++動態(tài)鏈接庫編程深入淺出

    靜態(tài)鏈接庫動態(tài)鏈接庫都是共享代碼的方式,如果采用靜態(tài)鏈接庫,則無論你愿不愿意,lib中的指令都被直接包含在最終生成的EXE文件中了。但是若
    發(fā)表于 10-21 17:03 ?0次下載
    VC++<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>編程深入淺出

    由MATLAB的.m文件生成動態(tài)鏈接庫的方法說明

    由MATLAB的.m文件生成動態(tài)鏈接庫的方法說明
    發(fā)表于 08-16 18:54 ?0次下載

    英創(chuàng)信息技術(shù)WinCE設(shè)備動態(tài)鏈接庫的制作與調(diào)用

    在使用英創(chuàng)ARM9系列主板做開發(fā)時,用戶可能希望將自己一部分代碼封裝起來,隱藏代碼的實現(xiàn)過程,只提供接口供其他程序調(diào)用。使用動態(tài)鏈接庫(Dynamic Link Library)可以很好實現(xiàn)這個要求
    的頭像 發(fā)表于 01-15 14:33 ?1105次閱讀
    英創(chuàng)信息技術(shù)WinCE設(shè)備<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>的制作與調(diào)用

    C++基礎(chǔ)語法梳理之Windows 的動態(tài)鏈接庫

    [], TCHAR *envp[]); Windows 的動態(tài)鏈接庫(Dynamic-Link Library) 部分知識點來自《Windows 核心編程(第五版)》 用處 (1)擴(kuò)展了應(yīng)用程序的特性 (2)簡化了項目管理 (3
    的頭像 發(fā)表于 11-02 09:21 ?1757次閱讀
    C++基礎(chǔ)語法梳理之Windows 的<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>

    單片機(jī)高階技能之動態(tài)鏈接庫技術(shù)實現(xiàn)

    單片機(jī)高階技能之動態(tài)鏈接庫技術(shù)實現(xiàn)
    發(fā)表于 11-17 12:21 ?13次下載
    單片機(jī)高階技能之<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>技術(shù)實現(xiàn)

    Linux的靜態(tài)鏈接庫動態(tài)鏈接庫的區(qū)別是什么?

    學(xué)習(xí)Linux動態(tài)鏈接庫是一個繞不開的話題,我們今天就一起來看一什么是動態(tài)鏈接庫
    的頭像 發(fā)表于 02-17 10:49 ?1208次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>下</b>的靜態(tài)<b class='flag-5'>鏈接庫</b>和<b class='flag-5'>動態(tài)</b><b class='flag-5'>鏈接庫</b>的區(qū)別是什么?