一.#include <>与#include “”
- #include <>直接到系统指定的某些目录中去找某些头文件。
- #include ""先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件。
二.gcc指定头文件的三种情况:
1.会在默认情况下指定到/usr/include文件夹(更深层次的是一个相对路径,gcc可执行程序的路径是/usr/bin/gcc,那么它在实际工作时指定头文件头径是一种相对路径方法,换算成绝对路径就是加上/usr/include,如#include<stdio.h>就是包含/usr/include/stdio.h)
2.GCC还使用了-I(大写的i)指定路径的方式,即gcc -I 头文件所在文件夹(绝对路径或相对路径均可) 源文件
举一个例子:
设当前路径为/root/test,其结构如下:
include_test.c
include/include_test.h
有两种方法访问到include_test.h。
- include_test.c中#include “include/include_test.h”然后gcc include_test.c即可
- include_test.c中#include 或者#include 然后gcc –I include include_test.c也可
参数:-nostdinc使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头文件的位置。
在编译驱动模块时,由于非凡的需求必须强制GCC不搜索系统默认路径,也就是不搜索/usr/include要用参数-nostdinc,还要自己用-I参数来指定内核头文件路径,这个时候必须在Makefile中指定。
3.再找内定目录
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
库文件,但是如果装gcc的时候,是有给定的prefix的话,那么就是
/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include
头文件搜索顺序:
- 由参数-I指定的路径(指定路径有多个路径时,按指定路径的顺序搜索)
- 然后找gcc的环境变量 C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH
三.Linux指定动态库路径
ld是gcc的链接器
可以使用man ld来查看gcc链接器手册,其中对参数有详细的解释
首先要说明的是,指定动态库的路径其实分为两种,第一种是编译时,第二种是运行时。
编译时
编译时指定的路径是给链接器使用的,我们进行链接的文件可能依赖其他的函数,链接器在进行链接的时候需要搜索到对应的函数的确实存在才能通过链接,否者就不能通过链接。某些动态链接库需要我们手动的指定链接,某些需要我们自己指定,自定义的动态链接库都是需要自己的。
用GCC的以下参数来指定
# 将namespec指定的动态链接文件或目标文件添加到要链接的文件列表中
-l namespec
# 举例,如果我们的程序中依赖了libsys.so这个动态链接库,这个动态链接库是我们自定义的,我们就需要像下面这样
gcc main.c -lsys
我们指定的需要链接的文件,那么链接器怎么知道你这个文件对不对呢,或者存在不存在呢?他肯定要去验证一下这个文件,那他到哪去找到这个动态链接库?
这就需要我们指定了,这就是编译时指定的路径
两种方式
# 第一种 -L参数
-L <path>
# 第二种 环境变量 LIBRARY_PATH
# 当然链接器肯定不止搜索这两个路径,其肯定还存在默认路径
对于目标文件或者动态链接库,我们可以使用ldd命令来查看其依赖的动态链接库
运行时
Linux动态库的默认搜索路径是/lib和/usr/lib。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函 数,以及该动态库的其它资源了。在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定。
1.在配置文件/etc/ld.so.conf中指定动态库搜索路径。
可以通过编辑配置文件/etc/ld.so.conf来指定动态库的搜索路径,该文件中每行为一个动态库搜索路径。每次编辑完该文件后,都必须运行命令ldconfig使修改后的配置生效
2.和LD_LIBRARY_PATH
LD_LIBRARY_PATH是程序运行期间查找动态链接库时指定除了系统默认路径之外的其他路径。
注意,该环境变量是全局的,会影响所有的程序
3.编译时设置GCC参数,设置动态链接库路径
# 这种方式是比较推荐的,只会影响这一个程序
gcc main.c -Wl,-rpath=./lib
运行时动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib。
动态链接库依赖其他动态链接库的注意点
我们在生成动态链接库的时候,如果我们的动态链接库中依赖了其他动态链接库,需要在生成该动态链接库的时候,给其指定其依赖的动态链接库,否者生成的该动态链接库不能正常地使用。
生成动态链接库与生成可执行文件不一样,生成可执行文件地时候会进行符号解析,如果找不到对应地符号就会出错,但是生成动态链接库不会,所以即使我们不指定,生成的时候也不会出错,但是使用的时候就会出错了
总结
添加头文件搜索路径
gcc foo.c -I /home/xiaowp/include -o foo
添加动态库搜索路径
# -l指定要链接的库的名字
gcc foo.c -L /home/xiaowp/lib -l foo -o foo
添加静态库搜索路径
# -l指定要链接的库的名字
gcc foo.c -L /home/xiaowp/lib -static -l foo -o foo