如何为多个独立源文件动态生成Makefile目标?
嘿,这个问题用Makefile的模式规则+自动化变量就能完美解决,不用手动写每个目标,批量生成完全没问题!
先给你直接上能跑的完整Makefile,再一步步解释:
# 第一步:把所有需要处理的文件前缀列在这里 FILES = foo bar baz # 第二步:把这些前缀标记为伪目标,避免和同名文件冲突 .PHONY: $(FILES) # 第三步:定义模式规则——每个前缀目标(比如foo)依赖对应的.c目标,触发构建 %: %.c $(MAKE) $@.c # 第四步:定义.c目标的执行命令,用自动化变量拿到前缀名 %.c: run build $*
关键部分解释:
模式规则
%: %.c:%是通配符,会匹配FILES里的每个前缀(foo、bar、baz)- 当你执行
make foo时,Make会自动把%替换成foo,规则就变成foo: foo.c,然后执行命令make foo.c,正好满足你“触发make foo.c”的需求 $@是自动化变量,代表当前正在构建的目标名字(比如执行make foo时,$@就是foo)
模式规则
%.c::- 同样用
%匹配前缀,$*是另一个自动化变量,代表%匹配到的内容(比如处理foo.c时,$*就是foo) - 所以命令
run build $*会自动变成run build foo、run build bar,完全对应每个文件的需求
- 同样用
.PHONY: $(FILES):- 把foo、bar这些标记为伪目标,确保即使你的目录里有一个叫
foo的实体文件,Make还是会执行我们定义的构建规则,不会因为文件存在就跳过
- 把foo、bar这些标记为伪目标,确保即使你的目录里有一个叫
为什么你之前的写法不行?
你之前写的$(FILES): $(FILES)会让每个目标都依赖所有FILES里的项,而不是各自对应的.c文件;而且$(FILE)这种变量是无效的,Make里没有这个内置变量,必须用自动化变量来动态获取当前目标的名字。
现在试试这个Makefile,执行make foo就会自动触发make foo.c,然后执行run build foo,完全符合你的需求,新增文件的话只要在FILES里加前缀就行,不用改其他规则!
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

