gcc指定標頭檔案和動態庫的方法

2021-07-10 20:33:03 字數 4369 閱讀 5858

本文詳細介紹了linux 下gcc標頭檔案指定方法,以及搜尋路徑順序的問題。另外,還總結了,gcc動態鏈結的方法以及路徑指定,同樣也討論了搜尋路徑的順序問題。本文包含了很多的例子,具有很強的操作性,希望讀者自己去走一遍。

一.#include <>與#include 「」

#include <>直接到系統指定的某些目錄中去找某些標頭檔案。

#include 「」先到原始檔所在資料夾去找,然後再到系統指定的某些目錄中去找某些標頭檔案。

二.gcc指定標頭檔案的三種情況:

1.會在預設情況下指定到/usr/include資料夾(更深層次的是乙個相對路徑,gcc可執行程式的路徑是/usr/bin/gcc,那麼它在實際工作時指定標頭檔案頭徑是一種相對路徑方法,換算成絕對路徑就是加上/usr/include,如#include 就是包含/usr/include/stdio.h)

2.gcc還使用了-i指定路徑的方式,即

gcc -i 標頭檔案所在資料夾(絕對路徑或相對路徑均可) 原始檔

舉乙個例子:

設當前路徑為/root/test,其結構如下:

include_test.c

include/include_test.h

有兩種方法訪問到include_test.h。

1. include_test.c中#include 「include/include_test.h」然後gcc include_test.c即可

2. include_test.c中#include 或者#include 然後gcc –i include include_test.c也可

3. 引數:-nostdinc使編譯器不再系統預設的頭檔案目錄裡面找標頭檔案,一般和-i聯合使用,明確限定標頭檔案的位置。

在編譯驅動模組時,由於非凡的需求必須強制gcc不搜尋系統預設路徑,也就是不搜尋/usr/include要用引數-nostdinc,還要自己用-i引數來指定核心標頭檔案路徑,這個時候必須在makefile中指定。

標頭檔案搜尋順序:

1.由引數-i指定的路徑(指定路徑有多個路徑時,按指定路徑的順序搜尋)

2.然後找gcc的環境變數 c_include_path, cplus_include_path, objc_include_path

3.再找內定目錄

/usr/include

/usr/local/include

/usr/lib/gcc-lib/i386-linux/2.95.2/include

/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3

/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include

庫檔案,但是如果裝gcc的時候,是有給定的prefix的話,那麼就是

/usr/include

prefix/include

prefix/***-***-***-gnulibc/include

prefix/lib/gcc-lib/***x-***-***-gnulibc/2.8.1/include

三.linux指定動態庫路徑

1.在配置檔案/etc/ld.so.conf中指定動態庫搜尋路徑。

可以通過編輯配置檔案/etc/ld.so.conf來指定動態庫的搜尋路徑,該檔案中每行為乙個動態庫搜尋路徑。每次編輯完該檔案後,都必須執行命令ldconfig使修改後的配置生效。

舉乙個例子:

所有原始檔:

原始檔1: lib_test.c

#include 

void prt()

原始檔2: main.c

void prt();

int main()

操作過程:

我們通過以下命令用源程式lib_test.c來建立動態庫 lib_test.so。

# gcc –o lib_test.o -c lib_test.c

# gcc -shared -fpic -o lib_test.so lib_test.o

#或者直接一條指令:

#gcc –shared –fpic –o lib_test.so lib_test.c

#注意:

-fpic引數宣告鏈結庫的**段是可以共享的,

-shared引數宣告編譯為共享庫。請注意這次我們編譯的共享庫的名字叫做

lib_test.so,這也是linux共享庫的乙個命名的慣例了:字尾使用so,而名稱使用lib***x格式。

接著通過以下命令編譯main.c,生成目標程式main.out。

# gcc -o main.out -l. –l_test main.c

#請注意為什麼是-l_test?

然後把庫檔案移動到目錄/root/lib中。

# mkdir /root/lib

# mv lib_test.so /root/lib/ lib_test.so

#最後編輯配置檔案/etc/ld.so.conf,在該檔案中追加一行/root/lib。

執行程式main.out:

# ./main.out

./main.out: error while loading shared libraries: lib_test.so: cannot open shared object file: no such file or directory

#出錯了,系統未找到動態庫lib_test.so。找找原因,原來在編輯完配置檔案/etc/ld.so.conf後,沒有執行命令ldconfig,所以剛才的修改還未生效。我們執行ldconfig後再試試。

# ldconfig

# ./main.out

you found me!!!

#程式main.out執行成功,並且列印出正確結果。

2.通過環境變數ld_library_path指定動態庫搜尋路徑。

通過設定環境變數ld_library_path也可以指定動態庫搜尋路徑。當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號」:」分隔。下面通過例2來說明本方法。

舉乙個例子:

這次我們把上面得到的檔案lib_test.so移動到另乙個地方去,如/root下面,然後設定環境變數ld_library_path找到lib_test.so。設定環境變數方法如下:

# export ld_library_path=/root

#然後執行:

#./main.out

you found me!!!

#注意:設定環境變數ld_library_path=/root是不行的,非得export才行。

3.在編譯目標**時指定該程式的動態庫搜尋路徑。

還可以在編譯目標**時指定程式的動態庫搜尋路徑。-wl,表示後面的引數將傳給link程式ld(因為gcc可能會自動呼叫ld)。這裡通過gcc 的引數」-wl,-rpath,」指定

舉乙個例子:

這次我們還把上面得到的檔案lib_test.so移動到另乙個地方去,如/root/test/lib下面,

因為我們需要在編譯目標**時指定可執行檔案的動態庫搜尋路徑,所以需要用gcc命令重新編譯源程式main.c(見程式2)來生成可執行檔案main.out。

# gcc -o main.out -l. –l_test -wl,-rpath,/root/test/lib main.c

#執行結果:

# ./main.out

you found me!!!

#程式./main.out執行成功,輸出的結果正是main.c中的函式prt的執行結果。因此程式main.out搜尋到的動態庫是/root/test/lib/lib_test.so。

關於-wl,rpath的使用方法我再舉乙個例子,應該不難從中看出指定多個路徑的方法:

gcc -wl,-rpath,/home/arc/test,-rpath,/lib/,-rpath,/usr/lib/,-rpath,/usr/local/lib test.c

以上介紹了三種指定動態庫搜尋路徑的方法,加上預設的動態庫搜尋路徑/lib和/usr/lib,共五種動態庫的搜尋路徑,那麼它們搜尋的先後順序是什麼呢?讀者可以用下面的方法來試驗一下:

(1) 用前面介紹的方法生成5個lib_test.so放在5個不同的資料夾下面,要求每乙個lib_test.so都唯一對應乙個搜尋路徑,並注意main.out程式輸出的不同。

(2) 執行main.out,即可看出他是那個搜尋路徑下的,然後刪除這個路徑下的lib_test.so,然後再執行。依此類推操作,即可推出搜尋順序。

可以得出動態庫的搜尋路徑搜尋的先後順序是:

1.編譯目標**時指定的動態庫搜尋路徑;

2.環境變數ld_library_path指定的動態庫搜尋路徑;

3.配置檔案/etc/ld.so.conf中指定的動態庫搜尋路徑;

4.預設的動態庫搜尋路徑/lib;

5.預設的動態庫搜尋路徑/usr/lib。

gcc指定標頭檔案及動態鏈結庫路徑

在利用源 進行軟體編譯的過程中,經常會出現以下錯誤 include 直接到系統指定的某些目錄中去找某些標頭檔案。include 先到原始檔所在資料夾去找,然後再到系統指定的某些目錄中去找某些標頭檔案。那麼gcc如何確定標頭檔案搜尋路徑呢?q 檔案路徑有多種,那麼先後順序如何?i 指定的路徑 gcc ...

gcc和 的包含標頭檔案庫檔案方法

l引數就是用來指定程式要鏈結的庫,l引數緊接著就是庫名,那麼庫名跟真正的庫檔名有什麼關係呢?就拿數學庫來說,他的庫名是m,他的庫檔名是libm.so,很容易看出,把庫檔名的頭lib和尾.so去掉就是庫名了。好了現在我們知道怎麼得到庫名,當我們自已要用到乙個第三方提供的庫名字libtest.so,那麼...

gcc指定標頭檔案路徑及動態鏈結庫路徑

include 直接到系統指定的某些目錄中去找某些標頭檔案。include 先到原始檔所在資料夾去找,然後再到系統指定的某些目錄中去找某些標頭檔案。1.會在預設情況下指定到 usr include資料夾 更深層次的是乙個相對路徑,gcc可執行程式的路徑是 usr bin gcc,那麼它在實際工作時指...