天天看點

gcc和交叉編譯頭檔案包含問題

eclipse開發環境下,同一個工程,使用gcc成功編譯,但是使用交叉編譯,提示找不到頭檔案,這是因為兩者預設的頭檔案包含路徑不一樣。

轉:http://blog.csdn.net/rebirthme/article/details/48549387

在LINUX程式設計當中,經常會遇到頭檔案包含的問題,那麼這些頭檔案到底在哪個路徑下?具體的頭檔案路徑依賴于程式性質(應用程式還是和核心相關的程式)和編譯器,下面分别叙述。
機器環境如下:UBUNTU10LTS,自己另外安裝的LINUX核心源碼目錄為/usr/src/kernel,交叉連結器arm-linux-gcc安裝目錄為/usr/lcoal/arm//
【如果是應用程式,并且使用GCC進行普通編譯】,如果編譯時沒有使用-I選項指定包含目錄的話,那麼預設的頭檔案目錄在/usr/include下,可以在shell下輸入如下指令

echo 'main(){}'|gcc -E -v -
看到如下輸出内容


Using built-in specs.
Target: i486-Linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version  (Ubuntu -ubuntu5) 
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i486'
 /usr/lib/gcc/i486-linux-gnu//cc1 -E -quiet -v - -D_FORTIFY_SOURCE= -mtune=generic -march=i486 -fstack-protector
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu//include
 /usr/lib/gcc/i486-linux-gnu//include-fixed
 /usr/include
End of search list.
# 1 ""
# 1 ""
# 1 ""
# 1 ""
main(){}
COMPILER_PATH=/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/i486-linux-gnu//../../../:/lib/:/usr/lib/:/usr/lib/i486-linux-gnu/
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i486'

這就是内定的include檔案搜尋路徑

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu//include
 /usr/lib/gcc/i486-linux-gnu//include-fixed
 /usr/include
End of search list.
實際上,這些内定的include檔案搜尋路徑,是存放在specs檔案中

【如果是應用程式,采用交叉編譯】,編譯時沒有使用-I選項指定包含目錄的話,那麼預設的頭檔案搜尋路徑為/usr/local/arm//arm-linux/include,即交叉編譯器的安裝目錄下的include目錄,執行如下指令


echo 'main(){}'|arm-linux-gcc -E -v -
看到如下輸出内容

Reading specs from /usr/local/arm//lib/gcc-lib/arm-linux//specs
gcc version   (release)
 /usr/local/arm//lib/gcc-lib/arm-linux//cpp0 -lang-c -v -D__GNUC__= -D__GNUC_MINOR__= -Dunix -D__arm__ -Dlinux -D__ELF__ -D__unix__ -D__arm__ -D__linux__ -D__ELF__ -D__unix -D__linux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm) -D__CHAR_UNSIGNED__ -D__ARM_ARCH_3__ -D__APCS_32__ -
GNU CPP version   (release) (ARM GNU/Linux with ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm//lib/gcc-lib/arm-linux//include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/sys-include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/include
End of search list.
The following default directories have been omitted from the search path:
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../include/g++-
End of omitted list.
# 1 ""
main(){}
這就是内定的include檔案搜尋路徑

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm//lib/gcc-lib/arm-linux//include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/sys-include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/include
End of search list.
即在采用交叉編譯時,應用程式所包含的頭檔案是在交叉編譯器的安裝目錄下。

【如果是和核心相關的程式】,比如驅動程式,那麼所包含的頭檔案是在核心源碼的安裝目錄下,即/usr/src/kernel/include,這時一般要在Makefile檔案中指定核心源碼目錄,在編譯時指定INCLUDE目錄,可參考“http://blogold.chinaunix.net/u3//showart_2342316.html文章中Makefile檔案内容

【總結】:
nclude的header檔案,連結資料庫,系統定義,總共有下列來源指定編譯器去那找。
當初在編譯時指定的(在~gcc/gcc/collect2.c:locatelib() ,寫在specs内的 
後來用-D -I -L指定的 
gcc環境變量設定(編譯的時候) 
ld.so的環境變量(這是run time的時候)
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version  (Ubuntu -ubuntu5) 
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i486'
 /usr/lib/gcc/i486-linux-gnu//cc1 -E -quiet -v - -D_FORTIFY_SOURCE= -mtune=generic -march=i486 -fstack-protector
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu//include
 /usr/lib/gcc/i486-linux-gnu//include-fixed
 /usr/include
End of search list.
# 1 ""
# 1 ""
# 1 ""
# 1 ""
main(){}
COMPILER_PATH=/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//:/usr/lib/gcc/i486-linux-gnu//../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/i486-linux-gnu//../../../:/lib/:/usr/lib/:/usr/lib/i486-linux-gnu/
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i486'

這就是内定的include檔案搜尋路徑

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i486-linux-gnu//include
 /usr/lib/gcc/i486-linux-gnu//include-fixed
 /usr/include
End of search list.
實際上,這些内定的include檔案搜尋路徑,是存放在specs檔案中

【如果是應用程式,采用交叉編譯】,編譯時沒有使用-I選項指定包含目錄的話,那麼預設的頭檔案搜尋路徑為/usr/local/arm//arm-linux/include,即交叉編譯器的安裝目錄下的include目錄,執行如下指令


echo 'main(){}'|arm-linux-gcc -E -v -
看到如下輸出内容

Reading specs from /usr/local/arm//lib/gcc-lib/arm-linux//specs
gcc version   (release)
 /usr/local/arm//lib/gcc-lib/arm-linux//cpp0 -lang-c -v -D__GNUC__= -D__GNUC_MINOR__= -Dunix -D__arm__ -Dlinux -D__ELF__ -D__unix__ -D__arm__ -D__linux__ -D__ELF__ -D__unix -D__linux -Asystem(unix) -Asystem(posix) -Acpu(arm) -Amachine(arm) -D__CHAR_UNSIGNED__ -D__ARM_ARCH_3__ -D__APCS_32__ -
GNU CPP version   (release) (ARM GNU/Linux with ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm//lib/gcc-lib/arm-linux//include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/sys-include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/include
End of search list.
The following default directories have been omitted from the search path:
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../include/g++-
End of omitted list.
# 1 ""
main(){}
這就是内定的include檔案搜尋路徑

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm//lib/gcc-lib/arm-linux//include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/sys-include
 /usr/local/arm//lib/gcc-lib/arm-linux//../../../../arm-linux/include
End of search list.
即在采用交叉編譯時,應用程式所包含的頭檔案是在交叉編譯器的安裝目錄下。

【如果是和核心相關的程式】,比如驅動程式,那麼所包含的頭檔案是在核心源碼的安裝目錄下,即/usr/src/kernel/include,這時一般要在Makefile檔案中指定核心源碼目錄,在編譯時指定INCLUDE目錄,可參考“http://blogold.chinaunix.net/u3//showart_2342316.html文章中Makefile檔案内容

【總結】:
nclude的header檔案,連結資料庫,系統定義,總共有下列來源指定編譯器去那找。
當初在編譯時指定的(在~gcc/gcc/collect2.c:locatelib() ,寫在specs内的 
後來用-D -I -L指定的 
gcc環境變量設定(編譯的時候) 
ld.so的環境變量(這是run time的時候)
           

繼續閱讀