关于文件包含命令还应说明以下几点:
1、命令中的文件名可以用双引号或尖括号括起来。 例如,允许以下写法:
#“stdio.h”
#
但这两种形式有一个区别:用尖括号表示在文件目录中查找(目录是用户在设置环境时设置的),而不是在源文件目录中查找;
使用双引号表示先在当前源文件目录中查找,如果没有找到,则在目录中查找。 用户在编程时,可以根据自己的文件所在目录选择某种命令形式。
2. 一条命令只能指定一个包含文件。 如果要包含多个文件,则需要多个命令。
3、文件包含允许嵌套,即一个包含文件中可以包含另一个文件。
A。 和“头文件名”
如:和“stdio.h”
前者(常用),要引用stdio.h文件,首先搜索标准路径,看这些文件夹中是否有头文件; 如果不是,则不会搜索当前文件所在路径,并报错。
后者(使用“”),要引用stdio.h文件,首先检索文件的当前路径; 如果没有,则搜索标准路径,看看这些文件夹中是否存在头文件。
b. 在Linux下,上述标准路径为:/usr/、/usr/local/。
C。 其中,第一个字符串(如sys、net)代表标准路径下的文件夹名,后面的字符串(如io.h、.h)代表下各文件夹下的头文件名Linux 标准路径。 比如sys文件夹下的io.h文件,即我们可以在/usr//sys目录下找到io.h文件。
Linux博大精深,需要慢慢积累。
d. 如果要检索指定路径下的头文件,请添加选项-I。 比如我的/home/目录下有一个头文件.h。 编译包含.h的test.c文件时,可以使用:gcc test.c -o test -I /root/。
1.讨论环境
*操作系统:/
*编译器:gcc 4.5.1
以下备注仅保证适用于上述环境。 在其他环境中,每个人都可以通过类比来获得灵感。
2.C语言头文件的搜索路径
C语言使用指令并包含头文件,但又细分为两种形式:
1. 表格1:#“文件1”
gcc首先在当前目录(指包含这个#指令的源文件的目录)中搜索file1。 如果找不到,则继续在 - 选项指定的目录(如果有)中搜索 file1。
例如,如果文件/usr//sys/stat.h包含指令#“types.h”,则gcc首先在/usr//sys目录中查找types.h文件。 嗯,这个目录下确实有一个 types.h 文件。 现在假设我们将此文件移动到另一个目录:mv/usr//sys/types.h /bar/foo/。 编译时,我们可以使用--选项来正常编译,无需更改stat.h。 (当然一般不推荐这样做): gcc - /bar/foo -I/usr//sys *.o
2. 表格 2:#
gcc 按以下顺序查找 file2: -Idir1 -Idir2 ...
/usr/本地/
/海湾合作委员会///
/usr//
/usr/
第一行中,-Idir1 -Idir2...是用户通过gcc的-I选项指定的目录。 值得一提的是,放在/usr/local//下的头文件也会被gcc自动检索,这与/usr/local/lib/目录下的库的处理方式不同(gcc的链接器中的库文件)运行时阶段不会自动搜索目录,下一节将提到)。
3.C语言库文件的搜索路径
C语言库文件的搜索路径分为两个阶段:链接阶段和运行时阶段。
1. 链接时间
在这个阶段,你需要告诉编译器去哪里找到库文件? 库文件是静态链接还是动态链接? 默认使用动态链接,需要存在对应的.so动态库文件。 如果不存在则查找对应的.a静态库文件。 如果编译时给gcc传递--选项,则采用静态链接,这就要求所有的库文件必须有对应的*.a静态库。
那么,是否可以让一些库使用动态链接而其他库使用静态链接呢? 不清楚,请参阅ld的用户手册。 我从来没有以这种方式使用过它。
言归正传,在链接阶段,gcc编译器是如何查找库文件的(它没有默认的搜索路径,这些搜索路径是gcc传递给它的)? 可以在编译时给 gcc 添加 -v 选项,以观察它传递给库文件的搜索路径(观察变量的值)。 通常的搜索路径如下:
-rpath-link 或 -rpath 选项指定的任何目录
(如果没有找到 -rpath 或 -rpath-link 选项)
-Ldir1 -Ldir2 ...
/usr/lib/gcc///
/usr/lib/
第一行-rpath-link和-rpath选项的区别在于-rpath选项指定的目录是硬编码到可执行文件中的,而-rpath-link选项指定的目录只在执行期间生效链接阶段。 由于这两个选项都是链接器 ld 的选项,那么如何将这两个选项从 gcc 传递给 ld 呢? 方法如下(详细参考gcc的-Wl选项):
gcc -Wl、-rpath、/usr/local/lib
这相当于将以下参数传递给 ld 指令:
ld -rpath /usr/local/lib
在第二行,如果未设置-rpath或-rpath-link选项,则搜索环境变量指定的目录并将其视为-rpath选项。 第三行-Ldir1 -Ldir2...是gcc的-L选项指定的库文件的搜索路径。 搜索顺序是根据我们传入的-L参数从左到右搜索; 第四行属于 gcc 本身。 图书馆目录; 第五行/usr/lib/是Linux系统默认系统库文件的目录。 第四行和第五行是gcc自动传递的搜索目录。 例如,在我当前的机器上,使用 gcc -v,我可以看到变量值为:
=/usr/lib/gcc/i686--linux/4.5.1/:/usr/lib/
但这还不是全部真相! 根据我自己的测试,我发现gcc在链接阶段也会使用/usr/local/lib/目录作为搜索路径。 这是问题的根源 - 我们在链接过程中使用了 /usr/local/lib/ 。 里面有一些库文件,但是在运行阶段,却说找不到库文件。
2.运行阶段()
只有当可执行程序使用动态方法链接库文件时,才会出现寻找运行时库文件的问题。 对于这种可执行程序来说,它本身只是记录了动态库的名称。 因此,在运行这个程序时,操作系统的加载器(ld.so)需要在必要的时候根据库的名称将库文件加载到内存中。
在Linux中,在运行时阶段,动态库(也称为共享库)的搜索路径如下:
-rpath 选项指定的目录(硬编码到可执行文件中)
/lib 或 /usr/lib
系统默认搜索路径
我们可以通过查看硬编码到可执行文件中的 rpath 来做到这一点:
$ -d # (如果)
不存在这样的问题,但是一般我们不建议使用这个环境变量,因为修改这个变量意味着影响所有依赖这个环境变量的程序(如果一定要使用,请在启动脚本中写入这个环境变量并让其生效)仅影响脚本内的程序)。
那么系统默认的搜索路径是什么呢? /中,ld.so通过读取/etc/ld.so.cache文件来找到库文件的位置。 如果没有找到,则继续从/etc/ld.so.conf文件指定的目录中查找。 这个ld.so.cache文件就相当于一个key-value数据库。 key是动态库的名称,value是这些库的存储路径。
那么/etc/ld.so.cache文件是如何生成的呢? 这就是这个工具程序的全部内容。 它是动态链接库的配置工具。 可以用它来更新/etc/ld.so.cache文件,还可以查看该文件中的键值信息(使用-p)。 详细使用方法请参阅其说明书。 总结一下系统默认搜索路径:
/etc/ld.so.cache
/etc/ld.so.conf 文件中指定的目录
4.参考资料
曼LD
男人
〜eagle/notes/rpath.html
本文介绍Linux中头文件的搜索路径,即Linux下的gcc编译器如何找到指定的头文件。 在此之前,我们先了解一个基本概念。
头文件是一个文本文件。 使用文本编辑器编写代码后,只需使用扩展名 .h 保存即可。 头文件一般包含一些重用的代码,如函数声明、变量声明、常量定义、宏定义等。当使用#语句引用头文件时,相当于将头文件中的所有内容复制到#中。 #有两种写法,分别是:
#:直接到系统指定的某些目录下查找某些头文件。
# "":先去源文件所在的文件夹,然后去系统指定的一些目录下找一些头文件。
#该文件可能会带来重复申请的问题。 例如,ah引用的函数是某个实现,而bh引用的函数是另一个实现,那么编译时就会出错。 因此,为了避免重复引用而导致编译错误,头文件中往往有:
#标签
#标签
//代码部分
#万一
格式。 LABEL是唯一的标签,命名规则与变量相同。 它通常根据它所在的头文件的名称来命名。 例如,如果头文件的文件名为.h,则可以这样使用:
#
#
//代码部分
#万一
这意味着如果没有定义,则定义它并编译以下代码部分,直到遇到#endif。 这样,当重复引用时,由于已经定义了,后面的代码部分就不会被编译,从而避免了重复定义。
总而言之,头文件实际上只是将一些常用的命令集成到了里面。 您可以只加载您想要使用的头文件。
gcc搜索头文件的路径(顺序为1->2->3)
1、gcc编译源文件时,通过参数-I指定头文件的搜索路径。 如果指定的路径有多个路径,则按照指定路径的顺序查找头文件。 命令形式为:“gcc -I /path/where//in .c”。 这里源文件的路径可以是绝对路径,也可以是相对路径。 例如:
假设当前路径为/root/test,如果.c想要包含头文件“/.h”,有两种方法:
1) .c 中的 # "/.h" 或 # "/root/test//.h",然后 gcc .c
2).c中的#或#,则也可以使用gcc –I .c
2.通过查找gcc环境变量//来搜索头文件位置。
3.然后在默认目录中搜索,分别是:
/usr/
/usr/本地/
/usr/lib/gcc-lib/i386-linux/2.95.2/
最后一行是gcc程序的库文件地址,在每个用户的系统上可能不同。
默认情况下,gcc会指定/usr/文件夹来搜索头文件。
gcc还有另一个参数:-,它使编译器不再在系统默认的头文件目录中搜索头文件。 一般与-I配合使用,明确限制头文件的位置。 编译驱动模块时,由于特殊需要,必须强制GCC不搜索系统默认路径,即不搜索/usr/,必须使用参数-,并且必须使用-I参数指定内核头文件路径。 这个时候就必须指定了。
4、#using相对路径时,gcc最终会根据上述路径构建头文件的位置。 例如#是包含文件/usr//sys/types.h