gcc指定頭文件路徑及動態連接庫路徑

gcc指定頭文件路徑及動態連接庫路徑

 

本文詳細介紹了linux 下gcc頭文件指定方法,以及搜索路徑順序的問題。另外,還總結了,gcc動態連接的方法以及路徑指定,一樣也討論了搜索路徑的順序問題。本文包含了不少的例子,具備很強的操做性,但願讀者本身去走一遍。
一.#include <>與#include 「」linux

#include <>直接到系統指定的某些目錄中去找某些頭文件。
#include 「」先到源文件所在文件夾去找,而後再到系統指定的某些目錄中去找某些頭文件。app

二.gcc指定頭文件的三種狀況:函數

1.會在默認狀況下指定到/usr/include文件夾(更深層次的是一個相對路徑,gcc可執行程序的路徑是/usr/bin/gcc,那麼它在實際工做時指定頭文件頭徑是一種相對路徑方法,換算成絕對路徑就是加上/usr/include,如#include 就是包含/usr/include/stdio.h)blog

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中指定。get

頭文件搜索順序:
1.由參數-I指定的路徑(指定路徑有多個路徑時,按指定路徑的順序搜索)編譯器

2.而後找gcc的環境變量 C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATHio

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/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include

三.Linux指定動態庫路徑

衆所周知,Linux動態庫的默認搜索路徑是/lib和/usr/lib。動態庫被建立後,通常都複製到這兩個目錄中。當程序執行時須要某動態庫, 而且該動態庫還未加載到內存中,則系統會自動到這兩個默認搜索路徑中去查找相應的動態庫文件,而後加載該文件到內存中,這樣程序就可使用該動態庫中的函 數,以及該動態庫的其它資源了。在Linux 中,動態庫的搜索路徑除了默認的搜索路徑外,還能夠經過如下三種方法來指定。

1.在配置文件/etc/ld.so.conf中指定動態庫搜索路徑。
能夠經過編輯配置文件/etc/ld.so.conf來指定動態庫的搜索路徑,該文件中每行爲一個動態庫搜索路徑。每次編輯完該文件後,都必須運行命令ldconfig使修改後的配置生效。

舉一個例子:
全部源文件:
源文件1: lib_test.c
#include 
void prt()
{
printf(「You found me!!!/n」);
}
源文件2: main.c
void prt();
int main()
{
prt();
return 0;
}
操做過程:
咱們經過如下命令用源程序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,而名稱使用libxxxx格式。

接着經過如下命令編譯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。

在上述一、二、3指定動態庫搜索路徑時,均可指定多個動態庫搜索路徑,其搜索的前後順序是按指定路徑的前後順序搜索的。有興趣的讀者本身驗證。

PS:此文網上搜得,原始出處已經沒法訪問,故沒法給出原文連接。

轉自:http://wdqfirst.blog.163.com/blog/static/1133474112012108114838299/