Makefile及gdb的使用方法介绍

  • makefile网址:跟我一起写Makefile — 跟我一起写Makefile 1.0 文档

  • makefile

    • 本质

      • 是一个工程管理文件

      • 作用

        • 简化编译流程

    • 理论基础

      • gcc 分步编译(4步)

        • 预处理->编译->汇编->链接

      • makefile

        • 将.c文件生成二进制文件.o(汇编)

        • 使用.o文件完成最后的链接过程

    • 文件的作用

      • 简化了编译流程,不需要将全部源文件重新编译

      • 如果源文件发生修改,只需要重新编译发生修改的源文件即可,节省了编译时间

      • Makefile会检查文件的时间戳,如果有文件时间戳更新(修改文件就会重新生成)

    • make工具

      • 读取make文件

        • 默认执行第一个目标

          • 只写一条规则,会自动推导前面的运行过程

        • 当目录下有Makefile和makefile 两个文件时,默认读取小写字母开头的文件

        • make的标准使用格式:

          • make 目标

          • 直接运行Makefile中指定目标的那条规则

        • make -f 指定文件

          • make -f 文件名 目标名

          • 不读入默认文件,读入指定文件的指定目标

      • makefile文件是make工具的唯一读入文件

    • Makefile文件的书写

      • 由规则,变量,条件编译及函数构成

    • 规则的构成

      • 由多条规则构成,每一条规则包含

        • 目标:依赖 <Tab>编译指令

          • 一般指令是指 依赖 生成 目标 的过程

          • 指令前不是Tab键而是四个空格则会报错

      • 一条规则中一定要有一个目标,一条规则中可以有多个依赖

      • 一条规则可以没有依赖,只执行某些指令

      • 一条规则可以没有指令,只描述目标和依赖之间的关系

    • 第一版Makefile

      • all:fun fun.o:fun.c gcc -c fun.c -o fun.o fun:fun.o main.o gcc fun.o main.o -o fun main.o:main.c gcc -c main.c -o main.o clean: rm *.o fun

        • 如果依赖的时间戳比目标的时间戳更新,目标会重新生成

        • 只写一条规则,Makefile会进行自动推导(Makefile在每次运行前,会自动生成文件依赖树)

    • make中的变量

      • 变量赋值

        • =

          • 递归赋值

            • 变量名 = 变量的值 (Makefile中赋值运算符两侧可以有空格也可以没有空格)

            • 获取变量的值为其最后一次赋值的结果

              • 调用时不管是在其最后一次赋值前还是后

        • :=

          • 立即赋值

            • 赋值为当前值

        • +=

          • 追加赋值

            • 连续赋值多次,且不覆盖

              • 将这一次的值添加在之前值的后面,并用空格隔开

        • ?=

          • 条件赋值

            • 只能被赋值一次,相当于常量,不可修改

        • 使用变量的值:${}、$()、$

          • 推荐使用$()和shell脚本做区分

    • 第二版Makefile

      • 引入变量

        • EXE=fun

          • 保存可执行文件

        • OBJs+=fun.o

        • OBJs+=main.o

        • CC=gcc

          • Makefile中表示使用的编译器的自动变量

        • CFLAGS=-c -o

          • 保存编译参数

      • EXE=FUN OBJs+= fun.o OBJs+=main.o CC=gcc CFLAGS=-c -o all:$(EXE) $(EXE):$(OBJs) $(CC) $(OBJs) -o $(EXE) fun.o:fun.c $(CC) $(CFLAGS) -c -o fun.o fun.c main.o:main.c $(CC) $(CFLAGS) -c -o main.o main.c clean: rm $(OBJs) $(EXE)

      • 引入自动变量和通配符

        • 自动变量

          • $@:所有的目标

          • $^:所有的依赖

          • $<:第一个依赖

            • 针对于一条规则而言的, 不是针对整个Makefile文件

        • EXE=FUN OBJs+= fun.o OBJs+=main.o CC=gcc CFLAGS=-c -o all:$(EXE) $(EXE):$(OBJs) $(CC) $^ -o $@ %.o:%.c $(CC) $(CFLAGS) $@ $^ clean: rm $(OBJs) $(EXE)

    • 第三版Makefile

      • 引入通配符:

        • *:通配所有情况

        • %:是一种(字符串的)模式匹配,在Makefile中的作用是,有一个.o,就匹配一个同名的.c

        • %.o:%c

          • 从上一条规则中,获取到需要两个.o文件,fun.o和main.o,使用%进行模式匹配,

          • %匹配相同的部分,有一个fun.o就能匹配到一个fun.c,有一个main.o就能匹配到一个main.c

      • EXE=FUN OBJs+= fun.o OBJs+=main.o CC=gcc CFLAGS=-c -o all:$(EXE) $(EXE):$(OBJs) $(CC) $^ -o $@ %.o:%.c $(CC) $(CFLAGS) $@ $^ clean: rm $(OBJs) $(EXE)

    • 伪目标

      • 在makefile中有些目标并不需要生成文件,也没有文件依赖,往往把这样的目标定义为伪目标,为了防止因为同名文件而不能执行目标的情况发生

      • clean

        • 直接将目标定义为伪目标 .PHONY : clean 将clean定义为伪目标

      • 伪目标的作用

        • 不会检查时间戳,直接执行规则中的内容

    • 引入函数

      • make工具内置函数是帮助程序员查找文件信息的,所以要求在查找路径下,只有程序需要的.c文件,没有其他程序的.c文件

      • wildcard(通配符)

        • 根据给定的条件,获取指定的文件名(找文件名的功能)

        • $(wildcard 指定字符串的格式)

        • $(wildcard *.c)

          • 找到当前路径下,所有.c文件的文件名

      • patsubst(字符串替换)

        • 模式匹配替换字符串

        • $(patsubst 源格式,目标格式,要替换的字符串)

        • $(patsubst %.c,%.o,1.c 2.c)

          • 获取到1.c和2.c字符串,根据模式匹配,得到1.o和2.o中字符串

        • 每一个参数之间以逗号作为分隔,要替换的字符串之间以空格作为分隔

    • 第四版Makefile

      • 引入内置函数

      • EXE=fun #保存可执行文件 FILES=$(wildcard *.c) #保存了所有.c文件的文件名 OBJs=$(patsubst %.c,%.o,$(FILES)) #使用patsubst将所有的.c字符串替换成.o字符串 CC=gcc #Makefile中表示使用的编译器的自动变量 CFLAGS=-c -o #保存编译参数 all:$(EXE) $(EXE):$(OBJs) $(CC) $^ -o $@ %.o:%.c $(CC) $(CFLAGS) $@ $^ .PHONY:clean #将clean定义为伪目标 clean: @rm $(OBJs) $(EXE) #@取消指令的回显

    • gdb调试工具

      • 用于调试代码中的逻辑错误,而非语法错误

      • gdp调试流程

        • 生成可以使用gdb调试的可执行文件

          • gcc -g xxx.c

          • 生成的a.out文件可以使用gdb调试

        • 进入gdb工具

          • gdb 可执行文件名

            • 使用gdb工具开始调试可执行文件

        • 查看源文件内容

          • l(list):查看.c文件的前10行,如果代码超出10行,再输入l

        • 工具指令

          • b 行号

            • 在指定行数打断点

          • r

            • 让程序运行,会停在断点处

          • n

            • 让程序向下执行一步 (如果碰到函数,不能进入函数内部)

          • s

            • 让程序向下执行一步 (如果碰到函数,可以进入函数内部,继续执行)

          • p 变量名

            • 打印变量的值

          • q

            • quit退出gdb工具

      • 调试core文件

        • core何时生成:当程序出现重大错误时,会生成一个临时的镜像文件,保存程序状态(段错误)

        • 由于系统的权限问题,不是每一次段错误都会生成core文件

        • ulimit -a 查看文件的权限

          • help ulimit

          • core file size如果为0该文件不会生成

          • ulimit -c unlimited 使用指令取消限制

          • 若上面的指令不能执行,则执行以下指令

          • sudo bash -c "echo core > /proc/sys/kernel/core_pattern"

        • 需要同时gdb 可执行文件和core文件

          • gdb a.out core

          • 程序会停在发生错误的一行

      • 调试正在运行的程序

        • 需要在后台终端运行可执行文件

        • ./a.out &

          • 会终端回显进程号

          • ps -ajx | grep a.out

            • 查找指定进程的进程号

        • gdb -p 进程号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值