# 预处理:头文件包含、去注视、宏替换、条件编译
gcc -E test.c -o test.i
# 编译(翻译成汇编语言)
gcc -S test.i -o test.s
# 汇编,生成目标二进制文件
cc -c test.s -o test.o
# 链接,形成可执行程序(默认动态链接)
gcc test.o -o mytest
ldd mytest
:可以查看mytest可执行程序的链接方式(动/静)
改为静态链接方式
gcc test.c -o mytest -static
通过加
-static
file mytest
可以查看文件属性,其中就有动静态
1、gdb调试
默认生成的可执行程序是release版本的是动态链接的,不可以被调试
1、
gcc test.c -o test -g
: -g表示以debug发布,这样才能调试
(readily -S mytest_debug | grep debug:可以查看debug信息)
2、gdb + <可执行程序>:
gdb mytest
3、list + n:显示第n行,n也可以是函数名,那就显示该函数,
list
可以简写为
l
,按enter可以继续往下显示
4、b + n:将第n行打断点
5、info b:查看断点
6、r:开始运行,到打的断点行停下;r后再r可以重新开始
7、n(next):单步执行,逐过程
8、p + 变量:查看一次显示变量的值
9、display + 变量:跟踪查看一个变量,每一步都显示该变量的值
10、underplay + n:取消对编号n的变量的显示
11、c(continue):跳到下一个断点处(从当前位置开始连续而非单步执行程序)
12、d + n:取消编号为n的断点
13、s(step):在一个函数处可以进入函数执行,逐语句
14、bt:查看调用堆栈
15、until + x:从当前位置开始跳转至第n行
16、finish:跑完当前正在执行的非main函数
until、finish、continue调试三剑客
17、enable/disable + n:启用/禁用第n号断点
18、delete breakpoints:一次性删除所有断点
19、set var <变量调整>:
set var i = 10
->将i变量修改为10
2、make & makefile
依赖关系 + 依赖方法 缺一不可
1 mytest:mytest.c # 表明依赖关系
2 gcc mytest.c -o mytest # 表明依赖方法
3 .PHONY:clean # 定义伪目标:clean总是可以执行的(与make后对比,make只能在第一次执行的时候被执行,而make clean可以一直执行,改为最前面写.PHONY mytest后,make也可以一直执行)
4 clean: # clean不依赖于任何文件
5 rm -rf mytest # clean的依赖方法
简写:
1 mytest:mytest.c
2 gcc $^ -o $@
分开写:
1 mytest:mytest.o # mytest依赖于mytest.o
2 gcc mytest.o -o mytest
3 mytest.o:mytest.s # mytest.o依赖于mytest.s
4 gcc -c mytest.i -o mytest.o
5 mytest.s:mytest.i # mytest.s依赖于mytest.i
6 gcc -S mytest.i -o mytest.s
7 mytest.i:mytest.c #mytest.i依赖于mytest.c
8 gcc -E mytest.c -o mytest.i
mytest.o没有就先生成mytest.o,可是生成mytest.o需要mytest.s,那就先生成mytest.s …以此往下推导到mytest.c存在,因此是反着写的,但是执行时是正着执行的
多文档项目构建:
1 mytest:mytest.c main.c
2 gcc $^ -o $@
终极版本模版: