9.1 Makefile 脚本
一、GCC 指令
1、预处理:gcc -E test.c -o text.i
2、编译:gcc -S test.i -o test.s
3、汇编:gcc -c test.s -o test.o
4、链接:gcc test.o -o test
警告处理:
gcc -w test.c -o test :忽略警告
gcc -wall test.c -o test :编译后显示所有警告
gcc -werror test.c -o test :在产生警告的地方停止编译
二、什么是 Makefile?它的主要作用是什么?
Makefile 是一种用于自动化编译和构建软件的工具,它定义了一系列的规则来指定源文件如何被转换成目标文件。主要作用包括:
- 自动化构建:根据依赖关系自动编译需要更新的文件
- 管理依赖关系:跟踪源文件之间的依赖,确保正确的编译顺序
- 增量编译:只重新编译发生变化的文件,节省编译时间
- 定义构建流程:包括预处理、编译、链接等步骤
- 提供项目管理:支持多目标构建、条件编译等高级功能
三、基本语法结构
1)规则:定义目标文件、依赖文件和命令。
target: prerequisites #多个依赖文件之间用空格隔开。
command
2)变量:存储和重用值
CC = gcc CFLAGS = -Wall -O2
3)注释:以 # 开头
4)包含:引入其他的 Makefile
include common.mk
5)条件语句:根据条件执行不同的操作
ifeq ifneq ifdef ifndef
ifeq ($(DEBUG), yes)
CFLAGS += -g
endif
6)函数:内置函数,用于文本处理等
# $(函数名 参数集合) SRC = $(wildcard *.c) OBJ = $(patsubst %.c, %.o, $(SRC))
7)自定义函数
# 定义一个生成编译规则的函数 define compile-rule $(OBJDIR)/$(1)/%.o: $(SRCDIR)/$(1)/%.c @mkdir -p $$(dir $$@) $(CC) $(CFLAGS) -c $$< -o $$@ endef # 使用函数 $(foreach dir,core utils net,$(eval $(call compile-rule,$(dir))))
四、自动变量
自动化变量可以不用括号,直接用 $ 引用得到值。
@:表示当前规则的目标文件的完整名称 <:表示当前规则的第一个依赖文件的完整名称 ^:表示当前规则的所有依赖文件,去除重复项 +:表示当前规则的所有依赖文件,保留重复项 *:表示当前规则中,目标文件的主文件名(不包括扩展名) ?:代表所有时间戳比目标文件新的依赖文件列表,用空格隔开 $(@D):表示目标文件的目录部分 $(@F):表示目标文件的文件名部分
五、系统预定义变量
CC:C 编译程序,默认是“cc” CXX:C++ 编译程序,默认是“g++” CPP:C 程序的预处理器,默认是“$(CC) -E” RM:删除命令,默认是“rm -f” CFLAGS:执行 CC 编译器的命令行参数
六、隐式规则
隐式规则是 Makefile 预定义的一些规则,省略某些重复的规则定义,从而简化 Makefile 的编写。
1)常见隐式规则:.c.o、.cpp.o、.S.o
2)自定义规则:使用模式规则
CC = gcc
# 自定义模式规则
%.bar: %.foo
$(CC) -o $@ $< #命令必须用至少一个制表符开头
# 目标规则
all: test.bar
test.bar: test.foo
# 清理规则
clean: #伪目标没有依赖文件。一个makefile不应只有伪目标,还应有目标,否则make时,伪目标也会执行。
rm -f *.bar
.PHONY:clean
七、Makefile 如何处理文件依赖关系?如何自动生成依赖?
Makefile 通过规则来定义文件之间的依赖关系。当运行 make 命令时,它会检查目标文件是否存在,以及目标文件的修改时间是否比所有依赖项的修改时间旧。如果目标文件不存在或者某个依赖项的修改时间比目标文件新,make 就会执行规则中的命令来重新生成目标文件。
自动生成依赖:
# 使用GCC的-MM选项生成依赖,-MM 选项会生成不包含系统头文件的依赖信息。
%.d: %.c
$(CC) -MM $< > $@
# 包含生成的依赖文件
-include $(SRC:.c=.d)
八、Makefile 中变量的类型有哪些?
变量类型:简单变量(:=):立即展开,在赋值时就已经确定下来,后续不再发生变化;递归变量(=):使用时才展开,动态展开;条件变量(?=):仅在变量未定义时赋值;:向已有变量追加值。
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
一名985硕,在25年秋招中斩获多个C++/嵌入式开发Offer。本专栏将分享我的面经,涵盖C/C++、操作系统、计算机网络、ARM体系与架构、Linux应用/驱动开发、Qt、通信协议及开发工具链等核心内容。