linux動態庫的製做和路徑安裝

動態庫*.so在linux下用c和c++編程時常常須要使用。
一、動態庫的編譯
下面經過一個例子來介紹如何生成一個動態庫。這裏有一個頭文件:so_test.h,三個.c文件:test_a.c、test_b.c、test_c.c,咱們將這幾個文件編譯成一個動態庫:libtest.so。
------------so_test.h--------------
void test_a();
void test_b();
void test_c();mysql

--------------test_a.c---------------
#include <stdio.h>
#include <stdlib.h>
void test_a()
{
printf("this is in test_a...\n");
}
--------------test_b.c---------------
#include <stdio.h>
#include <stdlib.h>
void test_b()
{
printf("this is in test_b...\n");
}
---------------test_a.c--------------
#include <stdio.h>
#include <stdlib.h>
void test_c()
{
printf("this is in test_c...\n");
}
將這幾個文件編譯成一個動態庫:libtest.so
       $ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
而後須要安裝動態連接庫才能使用,見5
二、動態庫的連接
在一、中,咱們已經成功生成了一個本身的動態連接庫libtest.so,下面咱們經過一個程序來調用這個庫裏的函數。程序的源文件爲:test.c。
---------------test.c---------------
#include "so_test.h"
int main()
{
test_a();
test_b();
test_c();
return 0;
}
將test.c與動態庫libtest.so連接生成執行文件test:
        $ gcc test.c -L. -ltest -o test
測試是否動態鏈接,若是列出libtest.so,那麼應該是鏈接正常了
        $ ldd test
執行test,能夠看到它是如何調用動態庫中的函數的。
三、編譯參數解析
最主要的是GCC命令行的一個選項:
      -shared:該選項指定生成動態鏈接庫(讓鏈接器生成T類型的導出符號表,有時候也生成弱鏈接W類型的導出符號),不用該標誌外部程序沒法鏈接。至關於一個可執行文件
       -fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。
       -L.:表示要鏈接的庫在當前目錄中
       -ltest:編譯器查找動態鏈接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來肯定庫的名稱
       LD_LIBRARY_PATH全局變量:從新export這個環境變量指示動態鏈接器能夠裝載動態庫的路徑。固然若是有root權限的話,能夠修改/etc/ld.so.conf文件,而後調用 /sbin/ldconfig來達到一樣的目的,不過若是沒有root權限,那麼只能採用export LD_LIBRARY_PATH全局變量的方法了。
四、注意
   調用動態庫的時候有幾個問題會常常碰到,有時,明明已經將庫的頭文件所在目錄 經過 「-I」 include進來了,庫所在文件經過 「-L」參數引導,並指定了「-l」的庫名,但經過ldd命令察看時,就是死活找不到你指定連接的so文件,這時你要做的就是經過修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。一般這樣作就能夠解決庫沒法連接的問題了linux

五、共享庫的安裝
安裝在3種不一樣的路徑下:
1) 庫文件放在系統默認庫收索路徑下:若是共享庫文件安裝到了/lib或/usr/lib目錄下(複製到該目錄下), 那麼需執行一下ldconfig命令。ldconfig命令的用途, 主要是在默認搜尋目錄(/lib和/usr/lib)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下, 搜索出可共享的動態連接庫(格式如lib*.so*), 進而建立出動態裝入程序(ld.so)所需的鏈接和緩存文件. 緩存文件默認爲/etc/ld.so.cache, 此文件保存已排好序的動態連接庫名字列表.c++

#ldconfig
2) 庫文件放在任意目錄下,並配置/etc/ld.so.conf文件(永久安裝):若是共享庫文件安裝到了/usr/local/lib(不少開源的共享庫都會安裝到該目錄下)或其它"非/lib或/usr/lib"目錄下, 那麼在執行ldconfig命令前, 還要把新共享庫目錄加入到共享庫配置文件/etc/ld.so.conf中, 以下:
# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
# echo "/usr/local/lib" >> /etc/ld.so.conf
# ldconfig
3) 庫文件放在任意目錄下,使用export導出庫路徑(臨時安裝):若是共享庫文件安裝到了其它"非/lib或/usr/lib" 目錄下,  可是又不想在/etc/ld.so.conf中加路徑(或者是沒有權限加路徑). 那能夠export一個全局變量LD_LIBRARY_PATH,告訴loader在哪些目錄中能夠找到共享庫,而後運行程序的時候就會去這個目錄中找共享庫.
    好比安裝了一個mysql到/usr/local/mysql目錄下, 其中有一大堆庫文件在/usr/local/mysql/lib下面, 則能夠在.bashrc或.bash_profile或shell里加入如下語句便可:
#export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH   
這只是一種臨時的解決方案, 在沒有權限或臨時須要的時候使用.
4)向下兼容庫版本的方法:若是程序須要的庫文件比系統目前存在的村文件版本低,能夠作一個連接
好比:
error while loading shared libraries: libncurses.so.4: cannot open shared
object file: No such file or directorysql

#ls /usr/lib/libncu*
/usr/lib/libncurses.a   /usr/lib/libncurses.so.5
/usr/lib/libncurses.so  /usr/lib/libncurses.so.5.3shell

可見雖然沒有libncurses.so.4,但有libncurses.so.5,是能夠向下兼容的
建一個連接就行了
#ln -s  /usr/lib/libncurses.so.5.3  /usr/lib/libncurses.so.4編程

相關文章
相關標籤/搜索