特定のファイルが存在する場合にのみ実行する必要がある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
レシピにシェル部分を書いてください。
clean:
F="$MF_NAMES_LIST" ;\
if [ -e "$$F" ] ; then \
for mfn in $$(cat "$$F") ; do \
$(MAKE) -f mfd/$${mfn} clean;\
done ; \
fi
シェルにドルが表示されるようにするには、それを2倍にする必要があり、プログラムが1つの論理行になりたいので、makeはそれを単一のシェルに提供します。
GNUmakeには、単一のシェルで完全なレシピを実行できる拡張機能があります。
catを使用してforループでファイルを読み取るのはベストプラクティスではありません。たとえば、ファイルにスペースがあるとエラーが発生しますが、コードをソースに近づけるためにここでは修正しません。
答え2
これはシェルをシミュレートするための可能でシンプルなソリューションです。
$(eval mfn_lstf := $(shell cat ${MFN_LSTF}))
$(foreach mfn, ${mfn_lstf}, $(MAKE) -f mfd/${mfn} clean;)
また、以下はシェルをエミュレートすることなく機能します。
if [ -s "$${MFN_LSTF}" ]; then \
while IFS= read -r mfn; do \
$(MAKE) -f "mfd/$${mfn}" clean; \
done < "$${MFN_LSTF}"; \
fi