linux編程頭文件所在路徑的問題


一、問題引入

1、頭文件與庫

      當我們在PC主機linux環境下(如ubuntu),編寫linux應用程序,然后利用gcc來編譯。在源代碼的開始位置會寫入頭文件,那是因為我們使用了系統提供的庫函數,例如printf、open、read、write等等。我們會寫入類似的內容:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
......

      我們的應用程序代碼編譯過程大概是這樣的:編譯器根據頭文件提供的庫函數接口形式,來編譯我們的代碼(如果不知道調用庫函數的形式,eg:參數個數、形式、返回值類型等,將無法對庫函數調用的代碼進行編譯),然后生成目標文件;然后,再使用鏈接器將這個目標文件與系統庫鏈接;最終生成我們需要的應用程序。所以,其實我們的代碼包含了自己寫的內容,還有系統為我們提供好的現成的庫函數,整個結合起來才形成一個完整的程序。

      庫函數的頭文件,在編譯的時候被使用,而庫函數的代碼段(庫文件),在鏈接的時候被使用。

example:

      應用程序代碼在使用一個系統調用的時候,例如printf()函數,需要指定包含的頭文件stdio.h;另外,在鏈接的時候對應的鏈接libc.a(筆者電腦文件所在目錄:/usr/lib/i386-linux-gnu/libc.a)。

      總結一下,我們編寫應用程序,需要使用linux系統提供的庫函數。具體實現起來,需要頭文件和庫文件。頭文件是需要我們編寫應用程序的時候,在源文件開頭添加的;而庫文件則需要配置編譯環境進行指定搜索目錄。

2、頭文件和庫文件在哪兒?

     編寫linux本機的應用程序、目標開發板的應用程序以及目標開發板的驅動,都會使用庫函數,那么這些情況的頭文件和庫文件在哪兒放着呢?

     不知道這個問題,在編寫代碼時會有疑惑。比如說,編寫目標開發板的應用程序時,使用了open、read、write等函數。於是,想在linux內核開發的源碼包(驅動開發環境)里邊找到這些函數的完整代碼,或者降低要求,查看頭文件里的函數聲明。結果令人失望,找不到需要的頭文件能提供這樣的函數聲明。這樣造成我們不知道該如何使用這些庫函數。

     事實情況是,上邊列出常見的3種編程情況,所使用的頭文件和庫文件位置都不一樣。也就是說,上述3種編程情況,所使用的庫函數調用有可能是相同的,但是庫函數所在的頭文件以及對應的庫,所在的位置卻不一樣。所以,編寫目標開發板的應用程序時,在內核開發的源碼包(驅動開發環境)中,找不到我們需要的頭文件。

     下面,根據不同的編程情況,進行說明。

 二、編寫linux本機的應用程序

      查看命令

#echo 'main(){}'|gcc -E -v -

      顯示結果

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

    可見頭文件的搜索路徑如下(具體搜索路徑,要看個人的實際情況,以命令運行的結果為准):

 /usr/lib/gcc/i686-linux-gnu/4.6/include /usr/local/include /usr/lib/gcc/i686-linux-gnu/4.6/include-fixed /usr/include/i386-linux-gnu /usr/include

三、目標開發板的應用程序

      查看命令

#echo 'main(){}'|arm-linux-gcc -E -v -

      顯示結果

Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: /scratch/maxim/arm-lite/src-4.3-arm-none-linux-gnueabi-lite/gcc-4.3/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --with-specs='%{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables}' --enable-languages=c,c++ --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery G++ Lite 2009q1-176' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc --with-build-sysroot=/scratch/maxim/arm-lite/install-4.3-arm-none-linux-gnueabi-lite/arm-none-linux-gnueabi/libc --with-gmp=/scratch/maxim/arm-lite/obj-4.3-arm-none-linux-gnueabi-lite/host-libs-2009q1-176-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr --with-mpfr=/scratch/maxim/arm-lite/obj-4.3-arm-none-linux-gnueabi-lite/host-libs-2009q1-176-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/maxim/arm-lite/install-4.3-arm-none-linux-gnueabi-lite/arm-none-linux-gnueabi/bin --with-build-time-tools=/scratch/maxim/arm-lite/install-4.3-arm-none-linux-gnueabi-lite/arm-none-linux-gnueabi/bin
Thread model: posix
gcc version 4.3.3 (Sourcery G++ Lite 2009q1-176) 
COLLECT_GCC_OPTIONS='-march=armv4t' '-E' '-v' '-funwind-tables'
 /opt/EmbedSky/4.3.3/bin/../libexec/gcc/arm-none-linux-gnueabi/4.3.3/cc1 -E -quiet -v -imultilib armv4t -iprefix /opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/ -isysroot /opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc - -march=armv4t -funwind-tables
ignoring nonexistent directory "/opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/usr/local/include"
ignoring duplicate directory "/opt/EmbedSky/4.3.3/bin/../lib/gcc/../../lib/gcc/arm-none-linux-gnueabi/4.3.3/include"
ignoring duplicate directory "/opt/EmbedSky/4.3.3/bin/../lib/gcc/../../lib/gcc/arm-none-linux-gnueabi/4.3.3/include-fixed"
ignoring duplicate directory "/opt/EmbedSky/4.3.3/bin/../lib/gcc/../../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/include"
#include "..." search starts here:
#include <...> search starts here:
 /opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include
 /opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include-fixed
 /opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/include
 /opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
main{}
COMPILER_PATH=/opt/EmbedSky/4.3.3/bin/../libexec/gcc/arm-none-linux-gnueabi/4.3.3/:/opt/EmbedSky/4.3.3/bin/../libexec/gcc/:/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ LIBRARY_PATH=/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/armv4t/:/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/lib/armv4t/:/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/:/opt/EmbedSky/4.3.3/bin/../lib/gcc/:/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/lib/:/opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/armv4t/lib/:/opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/armv4t/usr/lib/
COLLECT_GCC_OPTIONS='-march=armv4t' '-E' '-v' '-funwind-tables'

      可見頭文件的搜索路徑如下(具體搜索路徑,要看個人的實際情況,以命令運行的結果為准):

/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include
/opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include-fixed /opt/EmbedSky/4.3.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/include /opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/usr/include

四、linux內核開發(如驅動)

      在參考文章《gcc 和 arm-linux-gcc 編譯器的默認搜索頭文件路徑》中,指出由內核編譯的Makefile等編譯規則指定。我個人覺得編譯的頭文件得搜索路徑,還是應在linux內核開發的源碼包中,例如主要集中區include目錄下。

 

參考資料:gcc 和 arm-linux-gcc 編譯器的默認搜索頭文件路徑


免責聲明!

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



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