如何判断Make目标是否为PHONY?如何过滤变量中的PHONY目标?
好的,我来帮你解决这两个Makefile相关的问题:
问题1:如何判断Make目标是否为PHONY?
Make维护着一个内置的特殊变量.PHONY,它包含了所有被声明为PHONY的目标列表。要判断某个目标是否属于PHONY,你可以用$(filter)函数来检查该目标是否存在于.PHONY的列表中。
举个具体的例子,假设你想检查目标clean是不是PHONY:
ifneq ($(filter clean,$(.PHONY)),) $(info clean is a PHONY target) else $(info clean is NOT a PHONY target) endif
如果$(filter clean,$(.PHONY))的结果非空,就说明clean是PHONY目标;反之则不是。
问题2:过滤变量中的PHONY目标,仅保留真实目标作为依赖
要实现这个需求,你可以用**$(filter-out)函数**,把.PHONY列表中的所有目标从你的变量里剔除,只留下真实目标。这样你的目标就只会依赖真实存在的文件目标,不会因为PHONY目标的执行而被触发。
假设你的变量是MY_TARGETS,里面混合了PHONY和真实目标,你可以这样处理:
# 假设你的原始变量(包含PHONY和真实目标) MY_TARGETS := clean build docs install # 过滤掉PHONY目标,得到仅包含真实目标的列表 REAL_TARGETS := $(filter-out $(.PHONY),$(MY_TARGETS)) # 让你的目标依赖过滤后的真实目标 my_target: $(REAL_TARGETS) @echo "Building only for real targets: $(REAL_TARGETS)"
注意事项:
- 确保
REAL_TARGETS的定义是在所有PHONY目标声明之后,这样.PHONY变量才包含了所有需要过滤的目标。如果后续动态添加了PHONY目标,记得重新执行过滤逻辑。 - 这种方法完全在Make的解析阶段完成,不需要在recipe里检查文件存在性,完美避免了PHONY目标触发依赖的问题。
内容的提问来源于stack exchange,提问作者Trevor
相关产品推荐
相关产品推荐

