歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux動態庫文件 soname realname linkname 詳解

先明白動態庫文件的3個名字
soname  :通過gcc/g++ -soname,libtest2.so.1 設置他是程序中連接文件的時候找的文件,本身為一個連接,他包含大版本,如果任何小版本的變化,直接替換到
          realname,然後ln -s 建立同樣的soname 到新的realname文件即可,不需要重新編譯程序。
realname:是動態庫文件的真實的名字及-o libtest2.so.1.1 生成的,sonanme 軟連接指向它,雖然程序連接的時候找到的soname但是通過連接找到實際的
          realname,他包含大版本和小版本。
linkname:這個可有可無,但是如果要,他不包含版本信息,在g++的時候應該使用這個名字,避免版本改動重新編譯makefile,如果哪天大版本也發生了變化
          使用linkname是版本無關的任然能夠編譯通過。我們只需要重新建立linkname的指向到新版本即可
 比如:
libtest2.so.1.1 為realname
 libtest2.so.1  為soname
 libtest2.so    為linkname
編譯或者使用makefile的時候應該盡量使用linkname,而不是使用realname

g++ main.cpp libtest2.so

 1、生成目標文件,二進制機器碼未連接,使用-c,-g為可以調試
 g++ -fPIC -c -g t2.cpp {可以多個} 
  生成.o的機器碼文件沒有連接 -fPIC代碼位置無關
2、生成動態庫文件
 g++ -shared -Wl,-soname,libtest2.so.1 -o libtest2.so.1.1 t2.o {可以多個}
  生成soname為libtest2.so.1真實名字為libtest2.so.1.1的動態庫文件文件名字為relname
  1.1為主版本和發行版
 readelf -d libtest2.so.1.1
  可以查看soname和relname
 3、生成soname軟連接
 /etc/ld.so.conf 加入一行 /home/linuxidc/CPLUSPLUS/part9
  執行ldconfig自動生成soname
  同時搜索庫文件文件也會搜索/etc/ld.so.conf的新配置的目錄下的soname
 
  或者指定目錄生成soname
  ldconfig -n /home/linuxidc/CPLUSPLUS/part9
  生成連接連接實際上就是soname指向realname
  或者
 也可以使用ln -s 來建立soname
  ln -s /home/linuxidc/CPLUSPLUS/part9/libfu.so.1.1 /home/linuxidc/CPLUSPLUS/part9/libfu.so.1
  後兩種方式需要修改
 LD_LIBRARY_PATH環境變量指向這個目錄/home/linuxidc/CPLUSPLUS/part9/
  因為默認不會再自定義的目錄下面早除非指定了
 /etc/ld.so.conf並且ldconfig生效了
4、
 g++ main.cpp libtest2.so.1.1 不推薦這種方式應該使用linkname見下面
5、
ldd a.out
查看程序需要的庫文件,這裡表示出來的是soname位置,而不是rename或者linkname
程序動態連接實際上如果有soname就會找到soname

建立linkname
如 lns -s  libtest2.so.1.1 libtest2.so
這裡的libtest2.so 就是一個link name
那麼我們編譯的時候
 就是
g++ main.cpp libtest2.so 代替掉第四步

 用戶的soname和realname文件及linkname文件全部放到 /usr/lib下,這種情況下只要有soname正確的指向了,就
 不需要修改,當然也可以隨意
 這裡使用soname放到/usr/lib下其他放到當前目錄
 當前realname文件在目錄/home/linuxidc/CPLUSPLUS/part9/
生成soname,使用ln -s方法
sudo ln -s /home/linuxidc/CPLUSPLUS/part9/libfu.so.1.1 /usr/lib/libfu.so.1
 sudo ln -s /home/linuxidc/CPLUSPLUS/part9/libfu2.so.1.10 /usr/lib/libfu2.so.1
生成linkname,使用ln -s
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ ln -s libfu.so.1.1 libfu.so
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ ln -s  libfu2.so.1.10 libfu2.so
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ g++ main.cpp libfu.so libfu2.so 
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ ldd a.out
        linux-vdso.so.1 =>  (0x00007ffccb799000)
        libfu.so.1 => /usr/lib/libfu.so.1 (0x00007f1be882e000)
        libfu2.so.1 => /usr/lib/libfu2.so.1 (0x00007f1be862c000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1be8328000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1be7f63000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1be7c5d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1be8a31000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1be7a47000)

如果mv任何一個realname文件出錯
linuxidc@linuxidc:~/CPLUSPLUS/part9$ mv libfu.so.1.1 libfu.so.1.1bak
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ ./a.out
 ./a.out: error while loading shared libraries: libfu.so.1: cannot open shared object file: No such file or directory
 linuxidc@linuxidc:~/CPLUSPLUS/part9$ ldd a.out
        linux-vdso.so.1 =>  (0x00007ffcedde5000)
        libfu.so.1 => not found                  ---這裡soname就找不到了
        libfu2.so.1 => /usr/lib/libfu2.so.1 (0x00007fd86e4f1000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd86e1ed000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd86de28000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd86db22000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd86e6f3000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd86d90c000)
       
當然soname也可以放到任何目錄,如我隨意放了一個目錄為
/home/linuxidc/CPLUSPLUS/part9/lib

realname文件在
/home/linuxidc/CPLUSPLUS/part9
那麼顯然在/usr/lib下找不到這個soname,那麼我們需要做的就是
export LD_LIBRARY_PATH=/home/linuxidc/CPLUSPLUS/part9/lib
讓g++程序能夠找到這個soname,或者修改/etc/ld.so.conf並且ldconfig生效了


 但是一般情況下linkname soname realname都在同一個目錄下,這裡只是想說明
 程序執行的時候要找的只是soname的位置,而soname指向了realname
       
最後
  g++ t2.cpp -fPIC -shared -o libtest2.so.1.10 不生成soname 的方式,不推薦這種方式,這種方式

Copyright © Linux教程網 All Rights Reserved