Linux 下編譯鏈結動靜態庫

2021-07-11 01:20:07 字數 3108 閱讀 4544

linux 版本是 red hat 9 ,核心版本是 2.4.18

輸入 which gcc 檢視 gcc 的位置在 /usr/bin/gcc

gcc -v 檢視 gcc 編譯前的配置資訊

--prefix=/usr 說明了安裝目錄

沒有 --with-headers 說明預設的 include 就在安裝目錄下

所以 gcc 預設的 include 目錄是 /usr/include ,要包含另乙個目錄,

可以用 -i dir 選項包含該目錄,想要更方便的可以

在 /etc/profile 中新增乙個環境變數 c_include_path

c_include_path="your include path"

export c_include_path

gcc 預設的 lib 目錄很多,一般是 /lib 和 /usr/lib

可以輸入 gcc -print-search-dirs 檢視

同樣可以在編譯時通過 -l dir 來新增,也可以在 /etc/profile 中新增

ld_library_path="your ldlib path"

export ld_library_path

還有就是可以/etc/ld.so.conf中新增目錄,這對於安裝別的庫很方便

當然修改了庫檔案後需要執行一下ldconfig

自己製作交叉編譯工具太複雜了,直接下乙個arm-linux-gcc-3.4.1.tar.bz2 

tar jxvf arm-linux-gcc-3.4.1.tar.bz2 -c /          解壓縮到根目錄下 

其實由於壓縮包帶的目錄是 usr/local/arm/3.4.1

所以實際還是在 /usr/local/arm/3.4.1 目錄下

在bin中可以看到各個工具 arm-linux-gcc ...

輸入 ./arm-linux-gcc -v 可以看到配置資訊

有 --with-headers=/usr/local/arm/3.4.1/arm-linux/include 說明了預設的include目錄

輸入 ./arm-linux-gcc -print-search-dirs 檢視搜尋的 lib 目錄,主要的庫檔案還是在

/usr/local/arm/3.4.1/arm-linux/lib目錄下.

arm-linux-gcc 3.4.1 可以用來編譯2.6的核心

而編譯bootloader還是用原來的2.95.2版的 arm-linux-gcc

程式的預處理、編譯、鏈結都可以由gcc完成,gcc會自動呼叫cpp來做預處理,ld來進行鏈結。其中對庫的鏈結是很重要的一部分,有靜態庫和動態庫兩種,靜態庫以 .a 為字尾,ld會把靜態庫中的**拷到待鏈結的程式中,形成完整的可執行的程式。而鏈結動態庫生成可執行程式又分為靜態呼叫和動態呼叫,靜態呼叫是在程式中包含標頭檔案直接呼叫庫函式,也叫顯式呼叫,程式被載入的同時也載入了庫,在載入時完成真正的位址鏈結。而動態呼叫則不需要包含標頭檔案,在程式中使用庫載入函式dlopen來載入庫,使用dlsym來獲取所需函式的位址,所以是在需要時才載入動態庫,也是隱式呼叫。這樣編譯時和庫就沒有關係,不需要鏈結了。

對各種方式都給個例項就比較好理解了

使用庫主要是為了實現**的共享,所以一些能共用的函式放在一起寫成庫就最好了。

靜態鏈結庫

一、先vi add.c **為

int add(int x,int y)

int sub(int x,int y)

然後 vi add.h **為

int add(int x,int y);

int sub(int x,int y);

二、需要把 add.c 編譯成.o檔案,然後再用 ar 命令生成靜態庫

gcc -c add.c

ar -rc libadd.a add.o 遵循靜態庫命名的規則 lib + 名字 + .a

三、下來可以編寫測試檔案test.c

#include

#include "add.h"

void main()

$nm libtest.a //nm工具可以列印出庫中的涉及到的所有符號,庫既可以是靜態的也可以是動態的。nm列出的符號有很多, 常見的有三種:

一種是在庫中被呼叫,但並沒有在庫中定義(表明需要其他庫支援),用u表示;

一種是庫中定義的函式,用t表示,這是最常見的;

另外一種是所謂的"弱態」符號,它們雖然在庫中被定義,但是可能被其他庫中的同名符號覆蓋,用w表示。

四、$gcc -c -i/home/******xx test.c //假設test.c要使用對應的靜態庫

$gcc -o test -l/home/******xx test.o libadd.a

說明:這裡的-i/home/******xx和-l/home/******xx 是通過-i(是大i還是小l)和-l指定對應的標頭檔案和庫檔案的路徑,libadd.a就是要用的靜態庫。在test.c中要包含靜態庫的標頭檔案。

五、然後執行程式就可以看到成功了。

-------------------  靜態鏈結庫end -------------------------

動態鏈結庫

動態鏈結庫的靜態呼叫

一、把add.c編譯成動態鏈結庫

1)$gcc -fpic -o libadd.o -c add.c

2)$gcc -shared -o libadd.so libadd.o

也可以直接使用一條命令gcc -fpic -shared -o libadd.so add.c

二、編譯test.c

gcc -o test test.c ./libadd.so

或者把libadd.so copy到目錄/usr/lib中,然後執行

gcc –o test test.c libadd.so

三、執行./test

動態鏈結庫的動態呼叫

靜態庫和動態庫同時存在,首先鏈結的是動態庫,gcc有指定鏈結動靜態庫的選項。

使用ldd可以檢視程式依賴的動態庫

ldd test

下面來看看真正的動態呼叫動態鏈結庫的test.c

#include

#include

void main()

編譯:gcc -o test test.c -ldl ./libadd.so

linux下 GCC編譯鏈結靜態庫 動態庫

目錄 回到頂部 有時候需要把一組 編譯成乙個庫,這個庫在很多專案中都要用到,例如libc就是這樣乙個庫,我們在不同的程式中都會用到libc中的庫函式 例如printf 也會用到libc中的變數 例如以後 要講到的environ變數 本文將介紹怎麼建立這樣乙個庫。這些檔案的目錄結構是 tree mai...

Linux gcc 製作動 靜態鏈結庫

以 math.c為例 gcc c math.c ar rcs libmath.a math.oar命令 將多個檔案打包成乙個備份檔案 引數r 用來替換庫中已有的目標檔案,或加入新的目標檔案 引數c 表示建立乙個庫,不管庫是否存在,都將建立 引數s 用來建立目標檔案的索引,這在建立較大的庫時能夠提高速...

Linux下靜態庫編譯

linux下動態庫檔案的擴充套件名為 so shared object 按照約定,所有動態庫檔名的形式是libname.so 可能在名字中加入版本號 這樣,執行緒函式庫被稱作libthread.so。靜態庫的檔名形式是libname.a。共享archive的檔名形式是libname.sa。共享arc...