我正在编写一个 Makefile 配方,当且仅当某个文件存在时才需要执行......
这是我所拥有的:
clean:
$(if $(shell test -s ${MFN_LSTF}), \
$(foreach mfn, $(shell cat ${MFN_LSTF}), \
$(MAKE) -f mfd/${mfn} clean;), )
.PHONY: clean
${MFN_LSTF} 保存一个文件名,其中包含一列 makefile 名称列表,假定这些名称与此 makefile 配方位于同一本地目录。
我遇到的问题是,该foreach
语句总是执行。我希望它仅在文件名${MFN_LSTF}
存在时执行。
我也尝试过这个:
clean:
[ test -s ${MFN_LSTF} ] &&
for mfn in $(shell cat ${MFN_LSTF}); do
$(MAKE) -f mfd/${mfn} clean
done
.PHONY: clean
答案1
您可以将 shell 部分写在 recipie 中。
clean:
F="$MF_NAMES_LIST" ;\
if [ -e "$$F" ] ; then \
for mfn in $$(cat "$$F") ; do \
$(MAKE) -f mfd/$${mfn} clean;\
done ; \
fi
需要注意的是,如果您希望 shell 看到一美元,则需要将其加倍,并且您希望程序成为一个逻辑行,因此 make 将其提供给单个 shell。
GNUmake 有一个扩展,允许您在单个 shell 中运行整个食谱。
使用 cat 将文件读入 for 循环并不是最佳实践,例如,如果文件中存在空格,就会出错,但我不会在此处修复该问题以保持代码接近原始代码。
答案2
这可能是一个可能且更简单的解决方案,模拟 shell:
$(eval mfn_lstf := $(shell cat ${MFN_LSTF}))
$(foreach mfn, ${mfn_lstf}, $(MAKE) -f mfd/${mfn} clean;)
并且,以下工作无需模拟 shell:
if [ -s "$${MFN_LSTF}" ]; then \
while IFS= read -r mfn; do \
$(MAKE) -f "mfd/$${mfn}" clean; \
done < "$${MFN_LSTF}"; \
fi