gcc编译器搜索Linux下头文件路径

gcc编译器搜索头文件路径linux

    本文介绍在linux下gcc编译器是如何找到程序中的头文件的。头文件是一种文本文件,使用文本编辑器将代码编写好以后,以扩展名.h保存就好了。头文件中通常放一些重复使用的代码,例如函数声明、变量声明、常数定 义、宏的定义等等。当使用#include语句将头文件引用时,至关于将头文件中全部内容,复制到#include处。#include有两种写法形式, 分别是:shell

#include <>   : 直接到系统指定的某些目录中去找某些头文件。bash

#include “” : 先到源文件所在文件夹去找,而后再到系统指定的某些目录中去找某些头文件。编辑器

    #include文件可能会带来一个问题就是重复应用,如a.h引用的一个函数是某种实现,而b.h引用的这个函数倒是另一种实现,这样在编译的时候将会出现错误。因此,为了不由于重复引用而致使的编译错误,头文件常具备:函数

#ifndef    LABELspa

#define    LABEL命令行

    //代码部分orm

#endif编译器

的格式。其中LABEL为一个惟一的标号,命名规则跟变量的命名规则同样。常根据它所在的头文件名来命名,例如,若是头文件的文件名叫作hardware.h,那么能够这样使用:it

#ifndef    __HARDWARE_H__

#define    __HARDWARE_H__

  //代码部分

#endif

这样写的意思就是,若是没有定义__HARDWARE_H__,则定义__HARDWARE_H__,并编译下面的代码部分,直到遇到#endif。这样当重复引用时,因为__HARDWARE_H__已经被定义,则下面的代码部分就不会被编译了,这样就避免了重复定义。

    一句话,头文件事实上只是把一些经常使用的命令集成在里面,你要用到哪方面的命令就载入哪一个头文件就能够了。

默认状况下,gcc在下面目录中搜索头文件:

/usr/local/include/
/usr/include/
在下面目录中搜索库:
/usr/local/lib/
/usr/lib/
搜索头文件的目录列表常被称为include路径,而搜索库的目录列表被称为搜索路径或连接路径。
在这些路径中的目录是按次序搜索的,在上面的两个列表中从第一个到最后一个。例如,“/usr/local/include”中找到的头文件优先于“/usr/include”中的同名文件。相似的,“/usr/local/lib”

中找到的库优先于“/usr/lib”中的同名库。
当有其余库被安装到另外的目录中,为了能按序找到这些库,须要扩展搜索路径。编译器选项“-I”和“-L”用于把新目录添加到各自的include路径和库搜索路径的头上。

经过shell中的环境能够控制头文件和库的搜索路径。能够在每次开始shell会话的相应登陆文件中,好比“.bash_profile”,自动地设置它们。
可使用环境变量C_INCLUDE_PATH(针对C的头文件)或CPP_INCLUDE_PATH(针对C++的头文件)把其余目录添加到include路径中。
例如,当编译C程序时,下面的命令会把“/opt/gdbm-1.8.3/include”添加到include路径中:
$ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include
$ export C_INCLUDE_PATH
该目录将在命令行上用选项“-I”指定的任何目录以后,但在标准默认目录“/usr/local/include”和“/usr/include”以前被搜索。
Shell命令export是必要的,以便shell之外的程序也能得到该环境变量,好比象编译器----对每一次shell会话的每个变量来讲,只须要设一次,也能够在相应的登陆文件中设置。
相似的,使用环境变量LIBRARY_PATH能够把另外的目录添加到连接路径中去。例如,下面的命令会把“/opt/gdbm-1.8.3/lib”添加到连接路径中:
$ LIBRARY_PATH=/opt/gdbm-1.8.3/lib
$ export LIBRARY_PATH
该目录将在命令行上用选项“-L”指定的任何目录以后,但在标准默认目录“/usr/local/lib”和“/usr/lib”以前被搜索。
环境变量被设置好之后,程序能够不用带“-I”和“-L”选项就能成功被编译,
$ gcc -Wall dbmain.c -lgdbm
由于如今默认路径包括了在环境变量C_INCLUDE_PATH和LIBRARY_PATH中指定的目录。

遵循标准Unix搜索路径的规范,搜索目录能够在环境变量中用冒号分隔的列表形式一块儿指定:
DIR1:DIR2:DIR3:...
这些目录被依次从左到右搜索。单个点“.”能够用来指示当前目录。7
例如,下面的设置把安装软件包的当前目录,及在“/optgdbm-1.8.3”和“/net”目录下各自的“include”,“lib”目录放到默认的include和连接路径中去:
$ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include
$ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib
在命令行上能够重复使用“-I”和“-L”选项来指定多个搜索路径的目录。例如,下面的命令,
$ gcc -I. -I/opt/gdbm-1.8.3/include -I/net/include -L. -L/opt/gdbm-1.8.3/lib -L/net/lib .....
等同于上面在环境变量中设置的。
当环境变量和命令行选项被同时使用时,编译器按下面的次序搜索目录:
1. 从左到右搜索由命令行“-I”和“-L”指定的目录
2. 由环境变量,好比C_INCLUDE_PATH和LIBRARY_PATH指定的目录

3. 默认的系统目录

    gcc还有一个参数:-nostdinc,它使编译器再也不系统缺省的头文件目录里面找头文件,通常和-I联合使用,明确限定头文件的位置。在编译驱动模块时,因为非凡的需求必须强制GCC不搜索系统默认路径,也就是不搜索/usr/include要用参数-nostdinc,还要本身用-I参数来指定内核 头文件路径,这个时候必须在Makefile中指定。