파일이 존재하는 경우 레시피를 어떻게 실행할 수 있나요?

파일이 존재하는 경우 레시피를 어떻게 실행할 수 있나요?

특정 파일이 존재하는 경우에만 실행되어야 하는 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

쉘에 달러가 표시되도록 하려면 이를 두 배로 늘려야 하며 프로그램이 하나의 논리적 라인이 되기를 원하므로 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

관련 정보