GCC编译
1.gcc编译的步骤
2.编译相关参数
-I :指定头文件所在目录
-c: 只做预处理,编译,汇编.得到二进制文件!!!
-g: 编译时添加调试语句.主要支持gdb调试.
-Wall: 显示所有警告信息
-D: 向程序中"动态"注册宏定义.
-l : 指定动态库库名
-L:指定动态库路径
静态库制作及使用步骤
1. 将.c生成.o文件-> e.g : gcc -c add.c -o add.o
2. 使用ar 工具制作静态库-> ar rcs lib库名.a add.o
3. 编译静态库到可执行文件中: gcc test.c lib库名.a -o a.out
头文件守卫:防止头文件被重复包含
#ifndef _ABC_
#define _ABC_
......
#endif
动态库制作及使用
1. 将.c生成.o文件,(生成与位置无关的代码 -fPIC)
gcc -c add.c -o add.o -fPIC
2. 使用gcc -shared 制作动态库
gcc -shared -o lib库名.so add.o
3.编译可执行程序时,指定所使用的动态库.-l :指定库名 -L:指定库路径
gcc test.c -o a.out -l+库名 -L+路径
4. 执行可以执行程序 ./a.out 出错!!!!
原因:
链接器: 工作于链接阶段,工作时需要-l和-L
动态链接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置
解决方式:
1.通过环境变量: export LD_LIBRARY_PATH=动态库路径
./a.out 成功!!! (临时生效,终端重启环境变量失效)
2. 永久生效:写入终端配置文件. .bashrc 建议使用绝对路径
2-1: vi ~/.bashrc
2-2: 写入export LD_LIBRARY_PATH=动态库路径 保存
2-3: . .bashrc // source .bashrc //->重启 终端--->让修改后的.bashrc生效
2-4 ./a.out 成功!!
gcc调试
gdb调试工具: 大前提:程序是你自己写的。
- -g:使用该参数编译可以执行文件,得到调试表。
e.g : gcc -g main.c -o main
gdb a. out - l list: list l 列出源码。根据源码指定行号设置断点。
- b: b 20 在20行位置设置断点。
- run/r: 运行程序
- n/next: 下一条指令(会越过函数)
- s/slstep:下一条指令(会进入函数)
- p/print: p i查看变量的值。
- continue:继续执行断点后续指令。
- quit:退出gdb当前调试。
- 其他指令:
run:使用run查找段错误出现位置。
finish:结束当前函数调用。
set args:设置main函数命令行参数
run字串1字串2…:设置main函数命令行参数
info b:查看断点信息表
b 20 if i = 5:设置条件断点。
ptype :查看变量类型
bt:列出当前程序正存活的栈帧.(栈帧:随着函数调用而在stack上开辟的一片内存空间。用于存放函数调用时产生的局部变量和临时值。)
frame: 根据栈帧编号,切换栈帧.
display: 设置跟踪变量.
undisplay:取消设置跟踪变量.使用跟踪变量的编号.
makefile
命名: makefile Makefile
1个规则:
目标:依赖条件
(一个tab缩进)命令
1.目标的时间必须晚于依赖条件的时间,否则更新目录
2.依赖条件如果不存在,找寻新的规则去产生依赖。
ALL:指定makefile的终极目标
2个函数:
src =$(wildcard ./*.c):匹配当前工作目录下的所有.c文件.将文件名组成列表,赋值给变量src.
obj=$(patsubst %.c, %.o,$(src)):将参数3中,包含参数1的部分,替换为参数2.
clean: (没有依赖)
-rm -rf $(obj) a.out “-”:作用->删除不存在文件时,不报错.顺序执行结束.
3个自动变量:
$@:在规则的命令中,表示规则中的目标。
$^︰在规则的命令中,表示所有依赖条件。
$<︰在规则的命令中,表示第一个依赖条件。如果将该变量应用在模式规则中,它可将依赖条件列表中的依赖依次取出,套用模式规则.
模式规则:
%.o:%.c
gcc -c $< -o %@
静态模式规则:
$(obj):%.o:%.c
gcc -c $< -o %@
伪目标:不管条件是否满足,命令都会执行
语法-> .PHONY: clean ALL(一般放这两个)
参数:
-n :模拟执行make,make clean命令
-f : 指定文件执行make命令.