[makefile] 규칙 실행시 make 변수 정의

GNUmakefile에서 임시 디렉토리를 사용하는 규칙을 갖고 싶습니다. 예를 들면 다음과 같습니다.

out.tar: TMP := $(shell mktemp -d)
        echo hi $(TMP)/hi.txt
        tar -C $(TMP) cf $@ .
        rm -rf $(TMP)

작성된 바와 같이, 위의 규칙은 규칙이 구문 분석 될 때 임시 디렉토리를 작성합니다 . 즉, 내가 out.tar를 만들지 않아도 많은 임시 디렉토리가 만들어집니다. / tmp가 사용되지 않는 임시 디렉토리로 흩어지는 것을 피하고 싶습니다.

변수가 정의 될 때와 달리 규칙이 실행될 때만 변수를 정의 할 수있는 방법이 있습니까?

내 주요 생각은 mktemp와 tar를 쉘 스크립트에 덤프하는 것이지만 다소보기 흉한 것 같습니다.



답변

당신의 예에서 TMP때마다 변수 설정 (임시 디렉토리 생성) 규칙 에 대해 out.tar평가됩니다. out.tar실제로 실행될 때만 디렉토리를 작성하려면 디렉토리 작성을 단계로 아래로 이동해야합니다.

out.tar :
    $(eval TMP := $(shell mktemp -d))
    @echo hi $(TMP)/hi.txt
    tar -C $(TMP) cf $@ .
    rm -rf $(TMP)

평가 가 수동으로 메이크 파일에 입력 된 것처럼 함수는 문자열을 평가한다. 이 경우 TMP변수를 shell함수 호출 결과로 설정합니다 .

의견에 대한 답변으로 편집 :

고유 한 변수를 만들려면 다음을 수행하십시오.

out.tar :
    $(eval $@_TMP := $(shell mktemp -d))
    @echo hi $($@_TMP)/hi.txt
    tar -C $($@_TMP) cf $@ .
    rm -rf $($@_TMP)

대상 이름 (이 경우 out.tar)을 변수 앞에 추가하여 name으로 변수를 생성합니다 out.tar_TMP. 바라건대, 그것은 갈등을 예방하기에 충분합니다.


답변

비교적 쉬운 방법은 전체 시퀀스를 쉘 스크립트로 작성하는 것입니다.

out.tar:
   set -e ;\
   TMP=$$(mktemp -d) ;\
   echo hi $$TMP/hi.txt ;\
   tar -C $$TMP cf $@ . ;\
   rm -rf $$TMP ;\

https://stackoverflow.com/a/29085684/86967에서 관련 팁을 통합했습니다.


답변

다른 가능성은 규칙이 실행될 때 변수 만들기를 위해 별도의 줄을 사용하는 것입니다.

예를 들어 다음은 두 가지 규칙이있는 makefile입니다. 규칙이 실행되면 임시 디렉토리가 작성되고 TMP가 임시 디렉토리 이름으로 설정됩니다.

PHONY = ruleA ruleB display

all: ruleA

ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
ruleA: display

ruleB: TMP = $(shell mktemp -d testruleB_XXXX)
ruleB: display

display:
    echo ${TMP}

코드를 실행하면 예상되는 결과가 생성됩니다.

$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile  testruleB_Y4Ow


답변

나는 “하지 마라”라는 답변을 싫어하지만 … 그렇지 않습니다.

make의 변수는 전역 변수이며 실행 단계가 아니라 makefile의 “구문 분석”단계에서 평가되어야합니다.

이 경우 단일 대상에 대한 로컬 변수 인 경우 @nobar의 답변 을 따라 쉘 변수로 만듭니다.

대상별 변수도 kati , Mozilla pymake 와 같은 다른 make 구현에서는 유해한 것으로 간주됩니다 . 이로 인해 독립형으로 빌드되었는지 또는 대상별 변수가있는 상위 대상의 종속성에 따라 대상을 다르게 빌드 할 수 있습니다. 그리고 이미 구축 된 것을 모르기 때문에 어떤 방식 인지 알 수 없습니다.


답변