linux gcc頭文件搜索路徑

C++編譯時,教科書中寫道:#include “headfile.h”優先在當前目錄查找頭文件;#include < headfile.h >從系統默認路徑查找頭文件。先前以爲系統默認路徑是環境變量$PATH指定的路徑,在系統上一查,傻了眼:

-bash-3.2$ echo $PATH

/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/Java/j2re1.4.0/bin:/usr/atria/bin:/ccase/bin:/home/devcomp/bin

全是bin目錄,$PATH是運行可執行文件時的搜索路徑,與include頭文件的搜索路徑無關,可能不少人犯了我這樣的錯誤。

 

頭文件:

1.       #include “headfile.h”

搜索順序爲:

先搜索當前目錄

然後搜索-I指定的目錄

再搜索gcc的環境變量CPLUS_INCLUDE_PATHC程序使用的是C_INCLUDE_PATH

最後搜索gcc的內定目錄

/usr/include

/usr/local/include

/usr/lib/gcc/x86_64-redhat-Linux/4.1.1/include

 

各目錄存在相同文件時,先找到哪個使用哪個。

2.       #include <headfile.h>

先搜索-I指定的目錄

然後搜索gcc的環境變量CPLUS_INCLUDE_PATH

最後搜索gcc的內定目錄

/usr/include

/usr/local/include

/usr/lib/gcc/x86_64-redhat-linux/4.1.1/include

 

與上面的相同,各目錄存在相同文件時,先找到哪個使用哪個。這裏要注意,#include<>方式不會搜索當前目錄!

 

這裏要說下include的內定目錄,它不是由$PATH環境變量指定的,而是由g++的配置prefix指定的(知道它在安裝g++時可以指定,不知安裝後如何修改的,可能是修改配置文件,需要時再研究下)

-bash-3.2$ g++ -v

Using built-in specs.

Target: x86_64-redhat-linux

Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux

Thread model: posix

gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)

 

在安裝g++時,指定了prefix,那麼內定搜索目錄就是:

Prefix/include

Prefix/local/include

Prefix/lib/gcc/--host/--version/include

編譯時可以通過-nostdinc++選項屏蔽對內定目錄搜索頭文件。

 

庫文件:

編譯的時候:

gcc會去找-L

再找gcc的環境變量LIBRARY_PATH

再找內定目錄 /lib /usr/lib /usr/local/lib 這是當初compile gcc時寫在程序內的(不可配置的?)

 

運行時動態庫的搜索路徑:

動態庫的搜索路徑搜索的先後順序是:

編譯目標代碼時指定的動態庫搜索路徑(這是通過gcc 的參數"-Wl,-rpath,"指定。當指定多個動態庫搜索路徑時,路徑之間用冒號""分隔)

環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑(當通過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號""分隔)

配置文件/etc/ld.so.conf中指定的動態庫搜索路徑;

默認的動態庫搜索路徑/lib

默認的動態庫搜索路徑/usr/lib

應注意動態庫搜尋路徑並不包括當前文件夾,所以當即使可執行文件和其所需的so文件在同一文件夾,也會出現找不到so的問題,類同#include <header_file>不搜索當前目錄

C/C++程序在linux下被編譯和連接時,GCC/G++會查找系統默認的include和link的路徑,以及自己在編譯命令中指定的路徑。自己指定的路徑就不說了,這裏說明一下系統自動搜索的路徑。

【1】include頭文件路徑
除了默認的/usr/include, /usr/local/include等include路徑外,還可以通過設置環境變量來添加系統include的路徑:
# C

export C_INCLUDE_PATH=XXXX:$C_INCLUDE_PATH

# CPP

export CPLUS_INCLUDE_PATH=XXX:$CPLUS_INCLUDE_PATH

以上修改可以直接命令行輸入(一次性),可以在/etc/profile中完成(對所有用戶生效),也可以在用戶home目錄下的.bashrc或.bash_profile中添加(針對某個用戶生效),修改完後重新登錄即生效。

【2】link鏈接庫文件路徑
鏈接庫文件在連接(靜態庫和共享庫)和運行(僅限於使用共享庫的程序)時被使用,其搜索路徑是在系統中進行設置的(也可以在編譯命令中通過 -l -L 來指定,這裏講的是使用系統默認搜索路徑)。
一般 Linux 系統把 /lib /usr/lib /usr/local/lib 作爲默認的庫搜索路徑,所以使用這幾個目錄中的鏈接庫文件可直接被搜索到(不需要專門指定鏈接庫路徑)。對於默認搜索路徑之外的庫,則需要將其所在路徑添加到gcc/g++的搜索路徑之中。
鏈接庫文件的搜索路徑指定有兩種方式:1)修改/etc/so.ld.conf 2)修改環境變量,在其中添加自己的路徑

1)在環境變量中添加
動態鏈接庫搜索路徑:

export LD_LIBRARY_PATH=XXX:$LD_LIBRARY_PATH
靜態鏈接庫搜索路徑:
export LIBRARY_PATH=XXX:$LIBRARY_PATH
以上修改可以直接命令行輸入(一次性),可以在/etc/profile中完成(對所有用戶生效),也可以在用戶home目錄下的.bashrc或.bash_profile中添加(針對某個用戶生效),修改完後重新登錄即生效。

2)在/etc/ld.so.conf 中添加指定的鏈接庫搜索路徑(需要root權限),然後運行 /sbin/ldconfig,以達到刷新 /etc/ld.so.cache的效果。

以上兩種方式均可以達到指定鏈接庫搜索路徑的效果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章