GNU Make中.PHONY目标check_dep仅执行一次的问题及解决方案咨询
问题原因
Make的核心机制是避免重复执行相同目标——哪怕目标被标记为.PHONY,在一次构建流程中只要该目标已经执行过,后续依赖它的规则就会直接跳过。你的Makefile中,dep1和dep2都依赖check_dep,但Make只会执行一次check_dep,因此只有第一个触发时的folder1被创建,folder2的创建逻辑被跳过。
解决方案
以下是几种可行的解决方式:
方式1:使用模式目标(推荐)
将check_dep改为带参数的模式目标,让不同目录对应不同的独立目标,确保每个目录的创建逻辑都会被执行:
NAME = file1 all: $(NAME) $(NAME): dep1 dep2 touch $(NAME) dep1: check_dep-folder1 touch dep1 dep2: check_dep-folder2 touch dep2 check_dep-%: mkdir -p $* .PHONY: check_dep-%
这里check_dep-%是模式目标,$*会匹配-后的部分(即目标目录名),dep1和dep2分别依赖不同的模式实例,因此两个目录都会被创建。
方式2:内联依赖逻辑
如果创建目录的逻辑简单,直接将mkdir命令内联到dep1和dep2的规则中,避免依赖共享目标:
NAME = file1 all: $(NAME) $(NAME): dep1 dep2 touch $(NAME) dep1: mkdir -p folder1 touch dep1 dep2: mkdir -p folder2 touch dep2
这种方式最直接,没有额外的依赖管理成本。
方式3:递归调用Make
通过启动子Make进程执行check_dep,让每个依赖都拥有独立的执行上下文,确保各自的DEP变量生效:
NAME = file1 all: $(NAME) $(NAME): dep1 dep2 touch $(NAME) dep1: DEP := folder1 dep1: $(MAKE) check_dep touch dep1 dep2: DEP := folder2 dep2: $(MAKE) check_dep touch dep2 check_dep: mkdir -p $(DEP) .PHONY: check_dep
每次调用$(MAKE) check_dep都会启动一个新的Make进程,各自使用对应的DEP值,从而创建两个目录。
内容的提问来源于stack exchange,提问作者Atti
相关产品推荐
相关产品推荐

