C/C++ 頭文件以及庫的搜索路徑


關鍵點: 1. #include <...> 不會搜索當前目錄
     2. 使用 -I 參數指定的頭文件路徑僅次於 搜索當前路徑。
     3. gcc -E -v 可以輸出頭文件路徑搜索過程

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_PATH(C程序使用的是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>不搜索當前目錄)

參考資源:http://my.oschina.net/alphajay/blog/4953?from=rss


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM