標籤:
對於以壓縮包發布的軟體,在它的目錄下通常都有一個配置指令碼configure,它的作用確定編譯參數(比如標頭檔位置、串連庫位置等),然後產生Makefile以編譯器。可以進入該軟體的目錄,執行"./configure --help"命令查看使用幫。
一個程式能正確編譯、連結、運行需要滿足3個條件:預先處理時能找到標頭檔,串連時能找到庫(靜態庫或動態庫),運行時能找到庫。下面介紹標頭檔的搜尋路徑
GCC 搜尋標頭檔有三種策略:
1.內定搜尋目錄,這是編譯器自身預設的目錄。由於是內定的,一定會搜尋,所以總是最後才搜尋。
2.手動指定搜尋目錄。可以在執行配置命令configure前,通過環境變數C_INCLUDE_PATH進行設定;也可以在執行配置命令configure時,通過-I選項進行指定。
3.手動指定不進行搜尋的目錄。這是在執行配置命令時,使用-nostdin選項進行指定。
-nostdinc選項
使編譯器不在系統預設的標頭檔目錄裡面找標頭檔,一般和 -I 聯合使用,明確限定標頭檔的位置。
-nostdin C++選項
規定不在 g++ 指定的標準路經中搜尋,但仍在其他路徑中搜尋。此選項 在創libg++庫使用
GCC指定標頭檔的方式
在程式中,常用兩種方法來包含標頭檔:
#include <headerfile.h>
#include "headerfile.h"
當#include <headerfile.h> 時,編譯時間按照"編譯命令指定目錄--->--->系統預設目錄--->編譯器預設"的順序搜尋標頭檔。
當#include "headerfile.h",編譯時間按照"源檔案目前的目錄---->編譯命令指定目錄--->系統預設目錄--->編譯器預設"的順序搜尋標頭檔。
編譯命令指定目錄
"指定的"標頭檔目錄是編譯器時使用" -I "選項來指定目錄。舉個例子:
mkdir -p /work/AAA/include /*臨時目錄,測試用*/ mkdir -p /work/BBB/include /*臨時目錄,測試用*/export C_INCLUDE_PATH=/work/AAA/includeecho ‘main() {}‘ | arm-linux-gcc -I/work/BBB/include -E -v -
得到以下輸出內容,從中可以看到尋找標頭檔時的路徑及優先順序:
... #include "....." search starts here: #include <.....> search starts here:/work/BBB/include /work/AAA/include...
系統預設目錄
系統預設的標頭檔目錄是通過環境變數C_INCLUDE_PATH來設定的,這個變數的值要在執行配置命令configure之前設定。
編譯器預設目錄
編譯器預設目錄由編譯器自己決定的,由程式碼決定的,這是不需要工人設定或指定的。
可以總結出標頭檔的尋找路徑及優先順序:
1.如果源檔案中使用雙引號來包含標頭檔,則首先在源檔案目前的目錄尋找標頭檔。
2.如果編譯時間使用"-I/some/dir",則在/some/dir中尋找。
3.如果設定了環境變數C_INCLUDE_PATH,則在指定的目錄中尋找。
4.最後在編譯器預設的路徑中尋找,這是不需要指定的,編譯時間一定會在該路徑中搜尋所需的標頭檔。
所以,編譯器時如果出現了找不到標頭檔的錯誤,可以通過設定C_INCLUDE_PATH或給編譯器設定"-I"選線來指定標頭檔目錄,這可以在執行配置命令configure之前設定C_INCLUDE_PATH或CFLAGS,如果不設定CFLAGS,它的預設值為"-g -O2",比如:
export C_INCLUDE_PATH="/some/dir/1:/some/dir/2"
export CFLAGS = "-g -O2 -I/some/dir" #如果設定了C_INCLUDE_PATH,就可以不設定CFLAGS
./configure
還有更好的方法,當明確知道要使用哪個動態庫時,可以通過pkg-config命令獲知要使用這個庫時編譯時間的參數、串連時的參數。
先執行一下命令體驗一下:
export PKG_CONFIG_PATH=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib/pkgconfig
pkg-config --cflags uuid -I/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/include
.標頭檔搜尋路徑gcc 在編譯時間如何去尋找所需要的標頭檔 :
-I選項指定的目錄--->gcc的環境變數 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH--->再找編譯器內定目錄
如果裝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下的標頭檔搜尋路徑