一、gcc编译过程
gcc -E hello.c -o hello.s //预处理
gcc -S hello.s -o hello.i //编译
gcc -c hello.i -o hello.o //汇编
gcc hello.o -o hello //链接
1)预处理,C编译器对各种预处理命令进行处理,包括文件包含、宏定义的扩展、条件编译的选择等;
2)编译,将预处理得到的源代码文件,经过“翻译转换”,产生机器程序,得到机器语言的汇编文件;
3)汇编,将汇编代码翻译成机器码,但是还不能运行;
4)链接,处理可重定向文件,把各种符号引用和符号定义转换成为可执行文件中的合适信息,通常是虚拟地址。
二、gcc常用命令参数
1、gdb调试 -g
gcc test.c -o test -g //生成的test可以使用gdb命令进行调试
2、指定所使用到的函数库 -l(小写l);指定函数库所在的文件夹 -L;指定头文件所在的文件夹 -I(大写i);
gcc test.c -L/path/lib -lxxx -I/path/include //使用顺序不分先后
3、编译优化
gcc -O test.c //编译器对代码自动优化编译,默认不优化
gcc -o1 test.c //设置优化级别为1;一般选择2,3会有很多bug风险
4、设置警告为错误
gcc -Werror test.c -o test
5、将所有警告信息全开
gcc -Wall test.c
6、编译时设置宏
gcc test.c -o test -DTRUE //相等于在代码第一行定义 #define TRUE 1
gcc test.c -o test -Dmacro=string //代码第一行定义 #define macro string
7、gcc编译标准
gcc test.c -o test //默认gcc test.c -o test -std=gun89
GCC -std编译标准一览表c.biancheng.net三、静态库和动态库
一、静态链接库搜索路径顺序:
- ld会去找gcc命令中的参数-L
- 环境变量LIBRARY_PATH
- 默认路径/lib、/usr/lib、/usr/local/lib
LIBRARY_PATH和LD_LIBRARY_PATH区别与使用:
- 开发时,设置LIBRARY_PATH,以便gcc能够找到编译时需要的动态链接库。
- 发布时,设置LD_LIBRARY_PATH,以便程序加载运行时能够自动找到需要的动态链接库。
二、动态链接时、执行时搜索路径顺序:
1)ld.so动态共享库搜索顺序
- ELF可执行文件中动态段DT_PATH指定;gcc加入连接参数“-Wl,-rpath”指定动态库搜索路径,多个路径之间用冒号分隔;
- 环境变量LD_LIBRARY_PATH指定路径;
- /etc/ld.so.cache中缓存的动态库路径。通过配置文件/etc/ld.so.conf增删路径(修改后需要运行ldconfig命令);
- /lib/
- /usr/lib/
2)与动态库链接相关的命令
- ld是gcc的链接程序;
- ldd是查看可执行文件中所依赖的库,eg:ldd a.out;
- ldconfig用来更新/etc/ld.so.conf文件;
- nm查看.so库中的函数名字,标记是T的就是动态库里面生成的名字;eg:nm -C test|grep static //在程序文本段查找static
3)动态库搜索路径顺序
- 编译目标代码时指定的动态库搜索路径;
- 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
- 配置文件/etc/ld.so.conf中指定的动态库搜索路径;/etc/ld/so.conf第一行有个引用命令:include ld.so.conf.d/*.conf;因此最优雅的方式是在ls.so.conf.d目录下创建一个自己的程序依赖的配置文件,配置文件内容为程序依赖的动态库路径,一个路径一行;最后ldconfig更新配置文件;
- 默认动态库搜索路径/lib/
- 默认动态库搜索路径/usr/lib/
4)动态库路径设置方法
- LD_LIBRARY_PATH环境变量指定,也可以放到.bashrv中固化下来,可也以放到当前用户的.bashrc只对当前用户有效;
- 如果启用ls.so.cache的话,系统会在/etc/ld.so.cache中存储所有可引用的动态链接库。这个文件内容可以通过/etc/ls.so.conf来指定;这是比较固定的机制,对全局用户有效;设置后需要root调用ldconfig刷新;
- 默认的标准库路径,如果是64位,还包括/lib64/、/usr/lib64/
- 如果只想对某个特定程序起作用,可以在编译时指定搜索路径。gcc的 -Wl和-rpath参数
- /usr/local/lib/和/usr/local/lib64/不在标准路径之列
ldconfig作用是在ld.so.conf和默认路径(/lib/、/usr/lib/)中所列出目录下搜索动态库;
编译时,ld链接器指定链接什么库,编译程序的最后一步是运行ld;
程序运行时,ld.so动态连接器,根据指定的路径加载库;
缓存文件/etc/ld.so.cahche,保存已经排好序的动态链接库名字列表;