靜態編譯和動態編譯

靜態庫
靜態庫也就相當於是把一系列的object文件放在同一個文件中(類似windows中的.lib文件)。當你提供一個靜態庫給鏈接器時,連接器將會搜索靜態庫,從中找到他所需要的object文件,提取出他們,將他們鏈接到你的程序中,就像你直接提供那些文件一樣。
如何創建靜態庫呢?你可以使用ar命令來創建。
下面我們舉個例子:
test/lib/test1.c
#include <stdio.h>

int hello_world1()
{
    printf("hello world1/n");
    return 1;
}

test/lib/test2.c
#include <stdio.h>

void hello_world2()
{
    printf(" hello world2/n");
}

test/app.c
#include <stdio.h>

int main()
{
    hello_world1();
}

現在我們編譯他們進入目錄test/lib
$gcc -c test1.c
$gcc -c test2.c
$ls
test1.c  test1.o  test2.c  test2.o
$ar cr libtest.a test1.o test2.o
$ls
libtest.a  test1.c  test1.o  test2.c  test2.o
cr標誌告訴ar將object文件封裝(archive),我們可以使用nm -s 命令來查看.a文件的內容
$nm -s libtest.a

Archive index:
hello_world1 in test1.o
hello_world2 in test2.o

test1.o:
00000000 T hello_world1
         U puts

test2.o:
00000000 T hello_world2
         U puts

現在讓我們編譯主程序
首先退出lib目錄
$cd ..
$gcc -o app app.c -Llib -ltest
-L指定了lib的搜索路徑,-l指定了鏈接的庫的名字-ltest也就是鏈接libtest.a
$./app
hello world1
hello_world1()被從libtest.a中找到並鏈接過來了,於是整個的過程中沒有出現問題。

動態庫
動態庫(static lib)也可一也可以成爲共享庫(shared lib),一般的後綴名是.so。動態庫與靜態庫有點類似,他們都是一系列的object文件的集合,只是他們的組織方式不同。同樣他們的鏈接方式也是不同的,動態庫只在執行是鏈接使用,並不把相應的部分編譯入程序中,在使用是一個庫可以被多個程序使用故可稱爲共享庫,而靜態庫將會整合到程序中,鏈接時各程序使用自己的庫。
下面我們來介紹如何創建動態庫,還是之前的三個文件,同樣的佈局,進入lib目錄
$gcc -c -fPIC  test1.c
$gcc -c -fPIC  test2.c
-fPIC告訴gcc將源代碼編譯成共享的object文件,PIC(Position-Independent Code)非位置依賴性代碼。
$gcc -shared -fPIC -o libtest.so test1.o test2.o
將兩個文件整合爲共享庫libtest.so
退出lib目錄
$cd ..
$gcc -o app app.c -Llib -ltest
$./app
./app: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
啊哈,我們在這裏遇到一個error沒找到libtest.so,說明我們的編譯成功了,libtest.so成爲了一個shared libary。程序之所以不能運行是因爲libtest.so不在默認的搜索路徑上
怎樣才能讓他跑呢?
$LD_LIBRARY_PATH=$PWD/lib ./app
hello world1
我們在自己指定鏈接的路徑,他找到了我們的libtest.so文件,並且鏈接成功了。

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