2014-10-21 2 views
0

Gnu Make 3.81을 사용하고 있으며 변수가있는 패턴 규칙과 일치시키려는 오류가 발생합니다.타겟에 변수가있는 Makefile 패턴 규칙

는 여기에 내가 가지고 올 수있는 작은 예입니다 : 내가 make atarget을 실행할 때

YYMMDD:=$(shell date +%y%m%d) 
TMP_DIR:=/tmp/$(YYMMDD) 

# create a temporary directory, and put a "source" file in it 
$(TMP_DIR): 
    mkdir $(TMP_DIR) 
    echo something > $(TMP_DIR)/somefile.orig 

# to build an "object" file in the temp dir, process the "source" file 
$(TMP_DIR)/%.new: $(TMP_DIR)/%.orig 
    wc -l $< > [email protected] 

atarget: $(TMP_DIR) $(TMP_DIR)/somefile.new 

그럼, 내가 얻을 :

mkdir /tmp/141021 
echo something > /tmp/141021/somefile.orig 
make: *** No rule to make target `/tmp/141021/somefile.new', needed by `atarget'. Stop. 

이 일을해야하지? 그것은 패턴 규칙이 잘 일치해야 같은 것 같습니다.

답변

1

make가 .orig 파일이 있다는 것을 모르기 때문에 : $(TMP_DIR)을 빌드하는 규칙이 있지만이 규칙이 $(TMP_DIR)/somefile.orig을 빌드한다는 것을 알지 못합니다. 따라서 make가 패턴 규칙과 일치 시키려고 할 때 .orig 파일이 존재하지 않으며 패턴 작성 방법을 알지 못하기 때문에 패턴이 일치하지 않는 것을 볼 수 있습니다. .new 파일을 만들 방법이 없습니다.

당신이 작성해야 :

$(TMP_DIR)/%.orig: 
     mkdir -p $(TMP_DIR) 
     echo $* > [email protected] 

다음이 작동합니다.

+1

내가 이해할 수없는 것이 있다고 생각합니다. ".orig"파일이 실제로 존재하는지 확인하지 않는 이유는 무엇입니까? – brooks94

+0

성능상의 이유로 Make에는 파일이있는 캐시가 있습니다. 캐시는 make가 어떤 파일이 생성되었음을 알 때 업데이트됩니다. 이 경우 해당 파일을 작성할 것이라는 규칙이 실행되지 않았습니다. 또한, make가'$ (TMP_DIR)'빌드를 시작한 다음 바로 다음 대상을 찾으려고 시작할 것이므로 ('-j') 병렬 처리를 활성화하면 makefile이 유효하지 않습니다. '$ (TMP_DIR)'빌드가 완료되지 않았습니다. 일반적으로 명시 적 전제 조건보다는 규칙의 "부작용"에 의존하는 것이 좋지 않습니다. – MadScientist

+0

이것이 사실이라면 왜 기본 "% .o : % .c"규칙이 작동합니까? – brooks94