
一、make和makefile1. 什么是 make 和 Makefilemake一个命令工具用于解释 Makefile 中的指令。Makefile一个文件定义了项目的编译规则、依赖关系和命令。2. 基本使用示例myproc: myproc.c gcc -o myproc myproc.c .PHONY: clean clean: rm -f myprocmyproc是目标文件依赖于myproc.cgcc -o myproc myproc.c是生成目标的命令clean用于清理项目.PHONY表示它不生成文件总是执行3. make 的工作流程在当前目录下查找Makefile或makefile找到第一个目标文件如myproc检查目标文件是否存在或其依赖是否更新递归查找依赖链直到所有依赖都被处理执行相应命令生成最终目标如果某个依赖文件不存在make 会报错并退出。4. .PHONY 的作用被.PHONY修饰的目标总是被执行不受文件时间戳影响。典型应用clean、test等辅助操作。.PHONY: clean clean: rm -f *.o *.i *.s myproc5. Makefile 的推导过程多文件编译myproc: myproc.o gcc myproc.o -o myproc myproc.o: myproc.s gcc -c myproc.s -o myproc.o myproc.s: myproc.i gcc -S myproc.i -o myproc.s myproc.i: myproc.c gcc -E myproc.c -o myproc.i这就是一个完整的从.c到可执行文件的推导链.c→.i→.s→.o→可执行文件6. Makefile 高级语法扩展BIN proc.exe # 定义变量最终生成的可执行文件名 CC gcc # 定义变量指定编译器为 gcc SRC $(wildcard *.c) # 使用 wildcard 函数获取当前目录下所有 .c 文件保存到 SRC 变量 OBJ $(SRC:.c.o) # 模式替换将 SRC 中所有 .c 后缀替换为 .o生成目标文件列表 LFLAGS -o # 定义变量链接阶段的编译选项-o 指定输出文件名 FLAGS -c # 定义变量编译阶段的选项-c 表示只编译不链接 RM rm -f # 定义变量删除命令-f 表示强制删除不提示 $(BIN): $(OBJ) # 规则proc.exe 依赖于所有 .o 文件 $(CC) $(LFLAGS) $ $^ # 执行链接gcc -o proc.exe 所有.o文件 echo Linking ... $^ to $ # 输出链接信息 表示不显示命令本身 %.o: %.c # 静态模式规则所有 .o 文件依赖于同名的 .c 文件 $(CC) $(FLAGS) $ # 执行编译gcc -c 对应的.c文件 echo Compiling ... $ to $ # 输出编译信息 .PHONY: clean # 声明伪目标clean 不是一个真实文件 clean: # 清理规则 $(RM) $(OBJ) $(BIN) # 删除所有 .o 文件和可执行文件 .PHONY: test # 声明伪目标test 也不是真实文件 test: # 测试规则 echo $(SRC) # 打印所有 .c 源文件 echo $(OBJ) # 打印所有 .o 目标文件语法说明示例定义变量BIN proc.exe$(变量名)引用变量$(CC)$(wildcard 模式)查找匹配的文件$(wildcard *.c)→ 返回所有.c文件$(变量:.旧后缀.新后缀)后缀替换$(SRC:.c.o)→ 将.c换成.o%通配符匹配任意字符串%.o: %.c→ 所有.o依赖同名.c$自动变量目标文件名在规则中代表目标$^自动变量所有依赖文件在规则中代表所有依赖$自动变量第一个依赖文件在规则中代表第一个依赖命令前缀静默执行echo→ 不显示echo命令本身.PHONY声明伪目标防止与同名文件冲突二、git提交的流程# 1. 初始化仓库或克隆现有项目 git init # 或 git clone 仓库地址 # 2. 编辑文件后查看变更 git status # 3. 将文件添加到暂存区准备提交 git add 文件名 # 添加单个文件 git add . # 添加所有变更 # 4. 提交到本地仓库并附上说明 git commit -m 修改了某个功能 # 5. 推送到远程仓库如GitHub、GitLab git push origin main # 6. 拉取他人最新提交 git pull origin main三、gbd/cgbd使用1. 调试版本的编译默认gcc编译出的程序是release 模式不支持调试。必须加上-g选项生成debug 版本# 不支持调试默认 gcc mycmd.c -o mycmd # 支持调试debug 模式 gcc mycmd.c -o mycmd -g使用file mycmd查看是否包含debug_info。2. GDB 常用命令速查表命令作用示例l/list显示源代码l mainb/break设置断点b 10或b maininfo b/info breakpoints查看所有断点信息info bd/delete删除所有断点deleted 断点编号删除指定编号的断点delete 2disable禁用所有断点disabledisable 断点编号禁用指定编号的断点disable 1enable启用所有断点enableenable 断点编号启用指定编号的断点enable 1r/run开始执行程序runn/next单步执行不进入函数nexts/step单步执行进入函数stepc/continue继续执行到下一断点continuep/print打印变量或表达式p resultset var修改变量值set var flag1watch监视变量变化watch resultfinish执行到当前函数返回finishuntil执行到指定行until 14info locals查看当前局部变量info localsbt/backtrace查看函数调用栈backtracequit退出 GDBquit3. 高级调试技巧加餐1. 使用cgdb提升体验# Ubuntu sudo apt install cgdb # CentOS sudo yum install cgdbcgdb兼顾 GDB 的命令行能力 代码窗口调试更直观。2.watch监视变量变化watch result当result被修改时GDB 会自动暂停并提示旧值/新值非常适合定位“不该变却变了”的变量。3.set var动态修改变量快速验证问题p flag # 查看当前值 set var flag14. 条件断点条件断点允许我们只在某个条件满足时才触发断点非常适合调试循环体或频繁调用的函数。1. 添加条件断点语法格式break 行号 if 条件表达式 break 函数名 if 条件表达式实战示例假设我们想在Sum函数的第 9 行循环体内部设置断点并且只有当i 30时才暂停(gdb) b 9 if i 30 Breakpoint 2 at 0x555555555156: file mycmd.c, line 9.2. 查看条件断点使用info b可以看到条件断点的特殊标记(gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20 breakpoint already hit 1 time 2 breakpoint keep y 0x0000555555555156 in Sum at mycmd.c:9 stop only if i 30 # ← 条件断点的标识可以看到断点 2 后面多了stop only if i 30表示这是一个条件断点。3. 条件断点的执行效果当程序运行时GDB 会自动检查条件条件为false如i1,2,3...29→ 断点不触发程序继续执行条件为true如i30→ 断点触发程序暂停这样我们就不需要手动按几百次n来追踪循环直接精准定位到i 30的时刻。4. 其他条件断点操作# 为现有断点添加条件 condition 2 i 50 # 修改已有断点的条件 condition 2 i 100 # 删除断点的条件变为普通断点 condition 2 # 设置条件断点的另一种写法 break mycmd.c:9 if i 30