2016-08-28 2 views
1

make로 처리하려는 파일이 다른 프로그램의 출력에 의존하는 설정이 있습니다. 프로그램과 모든 사전 요구 사항을 빌드하는 것은 복잡한 작업이기 때문에 make도 이것을 사용하고 싶습니다. 이제 제 문제는 Makefile의 요리법에서 규칙과 전제 조건을 생성 할 수 없다는 것입니다. 다음 코드를 고려하십시오 Makefile : 레시피에서 규칙 및 전제 조건 정의하기

bar: 
    echo target1 target2 target3 > bar 

foo: bar 
    $(eval BAR := $(shell cat bar)) 

define FUN 
$(1): 
    touch a$(1) 
endef 

ifdef BAR 
$(foreach i,$BAR,$(eval $(call FUN,$(i)))) 
endif 

blub: foo $(BAR) 

나는 내가 bar 조리법에 의해 결국이 할 파일 목록의 생성으로 이어질 복잡한 조리법의 큰 세트를 교체했다. 실제로, bar의 컨텐츠를 생산하는 것은 매우 복잡하고 메이크 조리법의 집합에 의해 수행되어야하고 (위 알 수 있듯이) 만 수행 할 수 없습니다

BAR:=$(shell echo target1 target2 target3) 

나는에 foreach 루프를 넣어 싶습니다 foo에 대한 조리법하지만 그 의미가 또한 function define in makefile

설명하지만 내가 make blub을 수행 할 때 시간에 다른 값을 foo 평가의 BARblub의 전제 조건을 다시하지 않을 때 것으로 보인다됩니다 prerequisites cannot be defined in recipes 실패 - 평가.

그래서 나는 결국 내가 두 가지 일을 찾고 있어요 생각 :

  • 가 어떻게 무엇을 (이 경우 bar) 다른 조리법 출력에 따라 (과에 따라 다름), 동적 런타임 조리법 생성합니까?

  • 런타임에 다른 레서피 (여기서는 bar)가 출력하는 결과에 따라 (그리고이 결과에 따라) 대상의 전제 조건 (이 경우 blub)을 어떻게 동적으로 업데이트합니까?

고맙습니다!

편집 : 다음은 내 문제를 해결하는 것 user657267 @의 도움으로 해결

: 당신이 메이크업의 자기 리메이크 기능을 사용한다처럼

.PHONY: all 
all: blub 

-include bar.make 

.PHONY: blub 
blub: $(BAR) 
    echo $^ 

bar.make: Makefile 
    printf 'BAR=target1 target2 target3\n' > [email protected] 
    printf 'target1 target2 target3:\n' >>[email protected] 
    printf '\ttouch [email protected]' >> [email protected] 

.PHONY: clean 
clean: 
    rm -f target1 target2 target3 bar.make 
+1

FWIW,이 에코의 사용은 매우 휴대하기 어렵습니다. printf (프로그램)를 사용하여 간단한 텍스트와 그 뒤에 개행 문자를 출력해야합니다. 참고로 FYI에서는 eval을 사용하여 조리법에서 변수를 설정할 수 있지만이 규칙을 사용하여 새 규칙을 만들 수는 없습니다. 이것은 make가 모든 메이크 파일을 읽은 후 레서피를 실행하기 전에 모든 메이크 파일 데이터를 내부 그래프로 정렬하는 프로세스를 수행하기 때문입니다. 그런 일이 발생하면 새 규칙을 추가하여 그래프를 변경할 수 없습니다. – MadScientist

+0

@MadScientist 아, 감사합니다.이 질문에 대한 대답에서 당신에게 물어 보았던 다른 질문에 대한 귀하의 커밋 wrt'eval()'이 대답 할 것입니다. 즉, 이것을 포함시키기 위해서는'include '의 사용이 정말로 필요하며 존재할 수 없다는 것입니다 'eval' 전용 솔루션입니다. 여기에'echo'를 사용하는 방법 중 어느 부분이 이식성이 있지 않습니까? – josch

+0

모든 echo 명령이'\ t' 문자 시퀀스를 TAB 문자로 바꾸는 것은 아닙니다. – MadScientist

답변

3

는 소리

-include bar.make 

blub: $(BAR) 
    @echo $^ 

bar.make: 
    @echo BAR := target1 target2 target3 > [email protected] 
    @echo target1 target2 target3: ; touch [email protected] >> [email protected] 

분명히 bar.make의 요리법은 현실 세계에서 고안된 것입니다. 유효한 메이크 파일을 출력하는 스크립트

+0

이 마술은 무엇입니까 ??? 와우, 정말 고마워! 귀하의 대답은 제가 올바른 솔루션을 찾는데 도움이되었습니다 (아직 실제 문제에 적용해야 함). 나는 당신의 솔루션을 약간 변경해야만했다 : 1.'bar.make'는'Makefile' 자체에 의존해야하는데, 그렇지 않으면'Makefile'이 변경되면 다시 생성되지 않을 것입니다. 2. 'touch '의 주장 3.'-include'와'blub'의 순서가 중요합니다. 답과 같이 남겨두면 기본 목표는'target1'이되어 바람직하지 않습니다. 그러나'-blu' 다음에'-include '를 넣으면'$ (BAR)'은 – josch

+1

이 아닙니다. 자세한 내용은 https://www.gnu.org/software/make/manual/을 참조하십시오. html_node/Remaking-Makefiles.html 또한 다음과 같은 일을하는 블로그 게시물이 있습니다. http://make.mad-scientist.net/category/metaprogramming/ – MadScientist

+0

@MadScientist 감사합니다. make.mad-scientist에 대한 기사 .net은 내가 여러 번 그 문서를 읽은 후에 만든 공식적인 make docs보다 더 많은 주제를 이해하게 만들었다. 나는 궁금하다 : http://make.mad-scientist.net/the-eval-function/에서'eval()'함수는 "가장 강력한"함수라고한다. 이것은이 질문에서이 답변에서 제안한'include' 기반 기술 대신'eval()'을 사용하여 해결할 수 있다는 뜻입니까? – josch