[make] - Makefile 中,Recipe(规则体)是指什么
A simple makefile consists of “rules” with the following shape:
`
target ... : prerequisites ...
recipe
...
...
`
A target is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out, such as ‘clean’ (see Section 4.5 [Phony Targets], page 31).
A prerequisite is a file that is used as input to create the target. A target often depends on several files.
A recipe is an action that make carries out. A recipe may have more than one command, either on the same line or each on its own line. Please note: you need to put a tab character at the beginning of every recipe line! This is an obscurity that catches the unwary.
If you prefer to prefix your recipes with a character other than tab, you can set the .RECIPEPREFIX variable to an alternate character (see Section 6.14 [Special Variables], page 80).
A recipe is an action that make carries out. A recipe may have more than one command, either on the same line or each on its own line.
(Please note: you need to put a tab character at the beginning of every recipe line! This is an obscurity that catches the unwary. If you prefer to prefx your recipes with a character other than tab, you can set the .RECIPEPREFIX variable to an alternate character (see Section 6.14 [Special Variables], page 80).)
Usually a recipe is in a rule with prerequisites and serves to create a target fle if any of the prerequisites change. However, the rule that specifes a recipe for the target need not have prerequisites. For example, the rule containing the delete command associated with the target ‘clean’ does not have prerequisites.
A rule, then, explains how and when to remake certain fles which are the targets of the particular rule. make carries out the recipe on the prerequisites to create or update the target. A rule can also explain how and when to carry out an action. See Chapter 4 [Writing Rules], page 23.
A makefle may contain other text besides rules, but a simple makefle need only contain rules. Rules may look somewhat more complicated than shown in this template, but all fit the pattern more or less.
在 Makefile 中,Recipe(规则体) 是规则(Rule)中定义如何生成目标(Target)的具体操作步骤,通常由一系列 Shell 命令 组成。其核心作用是描述 依赖文件更新后需要执行的构建动作。
1. Recipe 的基本语法
-
格式:
target: prerequisites command1 # 以 Tab 缩进 command2 -
关键特性:
-
缩进要求:每行命令必须以 Tab 字符 开头(不能用空格替代)
-
Shell 解释:命令由 Shell 执行(如 Bash),支持管道、变量替换等 Shell 语法
-
隐式规则:若未显式定义命令,Make 会尝试使用内置规则(如
.c → .o)
-
2. Recipe 的作用
-
编译代码:例如将
.c文件编译为.o文件:main.o: main.c gcc -c main.c -o main.o -
链接程序:将多个
.o文件合并为可执行文件:myapp: main.o utils.o gcc main.o utils.o -o myapp -
清理操作:删除中间文件:
clean: rm -f *.o myapp
3. Recipe 的高级特性
(1) 自动化变量
-
$@:当前目标名称。 -
$<:第一个依赖文件。 -
$^:所有依赖文件(去重后)。 -
$?:比目标更新的依赖文件列表。
示例:
%.o: %.c
$(CC) -c $< -o $@ # 使用 $< 代替第一个依赖文件
(2) 条件执行
-
忽略错误:在命令前加
-,即使命令失败也继续执行:clean: -rm -f non_existent_file -
静默模式:用
@抑制命令回显:all: @echo "Building project..."
(3) 多行命令
使用 ``换行符分割多行命令:
complex_task:
echo "Step 1"; \
mkdir build; \
cd build && make
4. 示例:完整 Makefile
CC = gcc
CFLAGS = -Wall -O2
SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o)
TARGET = myapp
.PHONY: all clean
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
5. 常见问题与最佳实践
-
缩进错误:确保命令前是 Tab 而非空格(可通过
cat -A检查) -
变量展开:在规则上下文中定义的变量会被 Shell 解释,而非 Make 处理
-
依赖管理:显式声明所有依赖,避免因遗漏导致构建错误
总结
Makefile 的 Recipe 是构建逻辑的核心,通过 Shell 命令 实现从依赖到目标的转换。合理使用自动化变量、条件判断和隐式规则,可显著提升 Makefile 的灵活性和可维护性。
posted on 2025-11-28 14:47 ENGINEER-F 阅读(0) 评论(0) 收藏 举报
浙公网安备 33010602011771号