2009-03-12 4 views
7

최근 메이크 기반 빌드 프로세스의 종속성에 대해 .d 파일을 처리하는 방법에 대한 논의가 있습니다. 빌드가 중단 될 때 .d 파일이 손상 될 수있는 문제가 제기되었습니다.오류 발생시 추가 파일을 삭제하는 방법 얻기

우리는 .DELETE_ON_ERROR 타겟을 사용하여 빌드가 중단되거나 실패 할 경우 생성 과정에 있던 오브젝트 파일이 삭제되도록합니다. 그러나 우리는 또한 GCC를 사용하여 컴파일시에 .d 파일을 생성하는데,이 파일 또한 삭제해야합니다. 이 사실을 알리는 간단한 방법이없는 것처럼 보입니다.

그래서 문제가 발생하면 우리의 객체와 의존성 파일을 모두 삭제할 수있는 방법이 있습니까? .d 및 .o 파일이 동시에 생성되고 오류가 있으면 삭제해야한다는 것을 알 수 있도록 규칙을 설정할 수있는 방법이 있습니까?

번갈아 손상된 .d 파일의 문제를 해결하기 위해 할 수있는 다른 방법이 있습니까? 이 줄을 따르는 한 가지 제안은 .d 파일을 임시 이름으로 생성하고 올바른 이름으로 파일을 복사하는 파일마다 별도의 사후 컴파일 단계를 수행하는 것입니다.

답변

6

일반적으로 말하면 GNU make는 다중 출력이있는 타겟을 지원하지 않습니다. 그러나 규칙에는 예외가 있습니다. 패턴 규칙. 메이크 파일을 패턴 규칙을 사용하여 오브젝트 파일을 생성하도록 구조화 할 수 있다면 목표를 달성 할 수 있습니다. 예를 들면 : "오류"가 규칙에 감지되면

.DELETE_ON_ERROR: 

all: foo.o 

%.o %.d: %.c 
    @touch $*.d 
    @touch $*.o 
    @exit 1 

당신은 .D과 .o 인 파일을 모두 삭제이 메이크와 것을 볼 수 있습니다. 이 접근법의 장점은 .d 파일을 생성하는 방법과 생성 할 규칙을 기술함으로써 종속성 그래프를보다 정확하게 표현한다는 것입니다.

이 경우 일반적인 패러다임은 제안한 것과 같습니다. GCC에서 .d 파일을 임시 파일 이름으로 생성하고 GCC 명령이 성공적으로 완료된 후에 만 ​​제자리로 옮깁니다. 일반적으로이 쉘의 속임수로 이루어집니다 여기에 "마술"트릭

all: foo.o 

%.o: %.c 
    gcc -o [email protected] -MMD -MF $(basename [email protected]).d.tmp -c $< \ 
     && mv $(basename [email protected]).d.tmp $(basename $@).d 

, 편집의 부작용으로 종속 파일을 생성하는 GCC 플래그 -MMD의 사용, 그리고 -MF하는 종속성 파일의 출력 이름을 지정할 수 있습니다. 쉘 cmd1 && cmd2 구문을 사용하면 cmd1이 성공적으로 종료 될 경우 셸에서 cmd2 만 실행됩니다.

+0

makefile 맨 위에있는'.DELETE_ON_ERROR :'는 모든 임시 파일을 없애 버립니다. 감사! –

+0

패턴 규칙 "% .o : % .c"에 대한 레서피에서 두 번째 줄로 mv를 넣는 것이 좋습니다.나는 쉘에서 '&&'를 사용하여 행동을 바꾸거나 이익을 얻지 못한다. –

+0

@RichardPerrin gmake가'-i' (오류 무시) 옵션과 함께 호출되면 제안서가 잘못된 동작을 일으킬 수 있습니다. 이 경우, 당신의 버전은'gcc'에 에러가 있는지 없는지에 관계없이'mv' 명령을 실행합니다. –

-1

저는 Eric의 예제 중 어느 것도 제대로 작동하지 않습니다. GCC (버전 4.4)는 -MM 스위치를 전달할 때 아무 것도 컴파일하지 않으므로 .d를 한 번에 컴파일하고 작성할 수있는 것처럼 보이지 않습니다. 여기에 내가했던 일이야 :

%.o: %.c 
    @rm -f [email protected] $(patsubst %.o,%.d,[email protected]) 
    gcc -c $< -o [email protected] 
    @$(CXX) -MM -MG > $(patsubst %.o,%.d,[email protected]) 

그것은 기존 .D 파일, 두 번째 명령, 실제 컴파일 단계가 성공하면 새로운에만 실행 생성하는 세 번째 줄을 삭제하여 시작 (에릭의 & & 트릭 필요하지 않습니다. make가 자동으로이 작업을 수행합니다). 컴파일에 실패하면 기존 .o 파일이 자동으로 삭제되지 않지만 어떤 이유에서든 [email protected]을 첫 번째 rm에 추가하면 쉽게 해결할 수 있습니다.

+0

'-MM' 만 지정하면 gcc는 실제로 파일을 컴파일하지 않습니다. 또한 원래의 대답에 설명 된대로'-MF'를 사용해야합니다. –

+0

@ Eric -MF 스위치도 추가했지만 전처리 기는 gcc의 컴파일러 부분에 출력을 보내지 않는 것 같습니다. 그래서 0 바이트 오브젝트 파일로 끝납니다 ... – Wim

+0

죄송합니다. 실수를했습니다. '-MM'이 아니라'-MMD'를 원한다. 나는 원래의 답을 바로 잡았다. –

관련 문제