Linux GCC編譯使用動態 靜態鏈結庫

2021-06-03 06:40:42 字數 1908 閱讀 8742

在windows下動態鏈結庫是以.dll字尾的檔案,二在linux中,是以.so作字尾的檔案。

動態鏈結庫的好處就是節省記憶體空間。

1、linux下建立動態鏈結庫

在使用gcc編譯程式時,只需加上-shared選項即可,這樣生成的執行程式即為動態鏈結庫。

例如有檔案:hello.c x.h main.c

編譯:gcc hello.c -fpic -o libhello.so

所以動態載入時是通過**拷貝的方式來滿足不同的呼叫,而不能達到真正的**段共享的目的.

將main.c與hello.so動態庫

gcc main.c -l. -lhello -o main

一、動態鏈結庫

1.建立hello.so動態庫

#include void hello()

編譯:gcc -fpic -shared hello.c -o libhello.so

2.hello.h標頭檔案

void hello();

3.鏈結動態庫

#include #include "hello.h"

int main()

編譯:gcc main.c -l. -lhello -o main

這裡-l的選項是指定編譯器在搜尋動態庫時搜尋的路徑,告訴編譯器hello庫的位置。"."意思是當前路徑.

in function `main':

main.c:(.text+0x1d): undefined reference to `hello'

collect2: ld returned 1 exit status

這是因為在鏈結hello動態庫時,編譯器沒有找到。

解決方法:

sudo cp libhello.so /usr/lib/
這樣,再次執行就成功輸入:

call hello()

二、靜態庫

檔案有:main.c、hello.c、hello.h

1.編譯靜態庫hello.o: 

gcc hello.c -o hello.o  #這裡沒有使用-shared

2.把目標文件歸檔

ar -r libhello.a hello.o  #這裡的ar相當於tar的作用,將多個目標打包。
程式ar配合引數-r建立乙個新庫libhello.a,並將命令列中列出的檔案打包入其中。這種方法,如果libhello.a已經存在,將會覆蓋現在檔案,否則將新建立。

3.鏈結靜態庫

gcc main.c -lhello -l. -static -o main
這裡的-static選項是告訴編譯器,hello是靜態庫。

或者:

gcc main.c libhello.a -l. -o main
這樣就可以不用加-static

4.執行./main

輸出:call hello()

三、借助自帶的ldd實現程式來分析動態庫搜尋情況

ldd main

結果:linux-gate.so.1 =>  (0x00efd000)

libhello.so => /usr/lib/libhello.so (0x00f6b000)

libc.so.6 => /lib/libc.so.6 (0x001a5000)

/lib/ld-linux.so.2 (0x00eb8000)

如果目標程式沒有鏈結動態庫,則列印「not a dynamic executable」

靜動態編譯

有的時候我們經常會把自己編譯執行通過的.exe檔案放到其他機子上執行,卻驚奇地發現系統提示找不到什麼相關檔案的問題,導致編寫的程式只能孤芳自賞。其實這個問題的緣由主要是編譯器預設執行動態編譯,所謂動態編譯,就是程式執行所需要的庫等相關檔案是執行時才新增上去的,由於在本機當然有那些檔案,可是到了其他機...

linux gcc 靜態編譯和動態編譯

一 編譯和鏈結選項 第一步 預編譯。gcc e hello.c o hello.i e引數 gcc在完成預處理後,停止編譯過程。預處理的巨集定義展開到 hello.i中。第二步 生成目標 gcc c hello.i o hello.o c引數 生成目標 將 hello.i編譯為目標 也可以通過原始檔...

linux gcc使用靜態庫去編譯生成動態庫

實現目標 main呼叫libmy test.so,libmy test.so呼叫libtest.a 原始檔 main.c,my test.c,test.c及相應.h 生成libtest.a gcc fpic c test.c ar rcs libtest.a test.o 由libtest.a生成l...