看这个 Makefile 的语法,make all 目标有语法错误。我来分析一下:
问题分析
makefile
# 这里有语法问题
all: $(TARGETS)
实际上,这一行应该是:
makefile
all: clean c-example
但原作者可能是想通过变量来定义,但格式不正确。
正确写法应该是
makefile
# 定义变量
CC = clang
CFLAGS = -g -Wall
TARGETS = clean c-example
# 默认目标(当只输入'make'时执行)
default: c-example
# all 目标依赖于 TARGETS 变量中的目标
all: $(TARGETS)
# 编译目标
c-example: c-example.c
$(CC) $(CFLAGS) $< -o $@ # 注意:应该是 $@ 不是 $0
# 清理目标
clean:
$(RM) -rf c-example *~ *dSYM
# 声明伪目标
.PHONY: all clean default
make all 会做什么?
基于这个 Makefile(修正后):
-
依赖关系 :
all→clean→c-example -
执行顺序:
bashmake all ↓ 执行 clean 目标 ↓ $(RM) -rf c-example *~ *dSYM ↓ 执行 c-example 目标 ↓ $(CC) -g -Wall c-example.c -o c-example -
最终效果:
- 先删除所有生成的文件
- 然后重新编译
c-example
变量和特殊符号解释
makefile
# 自动变量:
$< = 第一个依赖文件的名字(这里是 c-example.c)
$@ = 目标文件的名字(这里是 c-example)
$^ = 所有依赖文件的名字
# 原文的错误:
$0 # 错误!应该是 $@
完整的正确版本
makefile
CC = clang
CFLAGS = -g -Wall
TARGETS = clean c-example
default: c-example
all: $(TARGETS)
c-example: c-example.c
$(CC) $(CFLAGS) $< -o $@
clean:
$(RM) -rf c-example *~ *dSYM
.PHONY: all clean default
运行测试
bash
# 测试 make all
$ make all
rm -rf c-example *~ *dSYM # 执行 clean
clang -g -Wall c-example.c -o c-example # 执行 c-example
# 测试默认目标
$ make # 等同于 make c-example
clang -g -Wall c-example.c -o c-example
# 测试 clean
$ make clean
rm -rf c-example *~ *dSYM
清理命令解释
makefile
$(RM) -rf c-example *~ *dSYM
$(RM):平台无关的删除命令(通常是rm)-rf:递归强制删除c-example:可执行文件*~:Emacs/Vim 等编辑器创建的备份文件*dSYM:Mac 上的调试符号目录
总结
在这个 Makefile 中,make all 会:
- 先执行
clean:删除所有生成的文件 - 再执行
c-example:重新编译程序
这是一种强制完全重新构建的模式,确保没有残留的旧文件影响新编译。