2016-06-07 2 views
0

비록 makefile에 꽤 좋았지 만 makefile에서 명령 순서에 대해 해결할 수없는 문제가 있습니다. 세부 정보를 제공합니다.작업 순서 : 새로운 파일을 작성하기 전에 오래된 파일을 지우십시오.

"a"유형의 파일을 생성하는 프로그램이 있습니다. 수동으로 이것을 가져 와서 하나의 "a"파일을 입력하고 "b"유형의 파일을 생성하는 도구를 통해 파일을 처리하려고합니다.

A_FILES = $(wildcard *.a) 
B_FILES = $(patsubst %.a,%.b,$(A_FILES)) 

그리고 "는"파일 목록에서 구축

%.b:%.a 
    $(MYTOOL) $< >[email protected] 

내가 모든 파일이 변수 B_FILES 구축 모여 :

그래서 내 메이크는 다음과 같은 패턴 규칙을 보유하고 일반 전화 대상을 통해 호출됩니다.

build_b_files: $(B_FILES) 
    @echo "done!" 

Works 완벽한 와이.

이제 문제 : "A"파일의 다양한 수를 생성 할 수 있습니다 메인 프로그램의 각 실행, 몇 가지 일반적인 명명 체계와 (예를 들어 file_0.a, file_1.a, file_2.a, ...). 그러나 실행이 20 개의 파일을 생성하고 다음 10 개만 생성하면 나머지 10 개의 파일이 나중에 실행됩니다.

그래서 내가하고 싶은 내 build_b_files 대상이 자동으로 새로 구축 전에 모든 기존의 "B"파일 을 삭제 할 수 있습니다.

나는 order-only prerequisite을 사용하려고 시도했지만 다음과 같은 오류가 발생합니다. 모든 파일을 다시 빌드 한 다음 지울 때마다 (!) 지워집니다.

erase_all_B: 
    @rm *.b 

build_b_files: $(B_FILES) | erase_all_B 
    @echo "- Done target [email protected]" 

은 아마 "주문 전용"의 개념에 대해 뭔가를 오해하고있다.

어떻게하면이 목표를 달성 할 수 있습니까?

편집 :

$ myapp some-arguments... (will produce 4 'a' files) 
$ ls -l   (stripped) 
june 8 16:00 file_0.a 
june 8 16:00 file_1.a 
june 8 16:00 file_2.a 
june 8 16:00 file_3.a 
$ make build_b_files 
$ ls -l 
june 8 16:00 file_0.a 
june 8 16:00 file_1.a 
june 8 16:00 file_2.a 
june 8 16:00 file_3.a 
june 8 16:00 file_0.b 
june 8 16:00 file_1.b 
june 8 16:00 file_2.b 
june 8 16:00 file_3.b 
    .... (some time) .... 
$ myapp some-other-arguments... (will produce only 3 'a' files) 
$ ls -l 
june 8 17:00 file_0.a 
june 8 17:00 file_1.a 
june 8 17:00 file_2.a 
june 8 16:00 file_3.a 
june 8 16:00 file_0.b 
june 8 16:00 file_1.b 
june 8 16:00 file_2.b 
june 8 16:00 file_3.b 
$ make build_b_files 
$ ls -l 
june 8 17:00 file_0.a 
june 8 17:00 file_1.a 
june 8 17:00 file_2.a 
june 8 17:00 file_0.b 
june 8 17:00 file_1.b 
june 8 17:00 file_2.b 

(궁금해하는 사람들을 위해,이 약은 다음 (시뮬레이션) 세션 내가 (ls는 여기에 관련 파일을 표시)을 찾고 무엇을 보여주는 참조 질문을 명확히하기 graphviz, dot 파일에서 이미지를 생성합니다 ...

.PHONY: erase_all_B 
erase_all_B: ; $(RM) *.b 
$(B_FILES): erase_all_B 

시험 :)

당신은 어떤 B 파일을 리메이크하기 전에 모든 B 파일을 삭제해야 할

답변

2

, 그래서 당신이 말하고있는 것은 erase_all_B$(BFILES)의 전제 조건 자체가 아니라 build_b_files해야한다는 것입니다 .a 파일을 생성 도구가 이전 내용을 제거하면

all: bar baz 
bar baz: foo 
ba%: 
    @echo bar baz 
foo: 
    @echo foo 
+0

답변 해 주셔서 감사합니다. 그것을 시도했지만, 여기에 뭔가 잘못된 것이 있습니다. – kebs

+0

이것은 작동하지 않습니다. make 3.81을 사용하면 "B"파일의 "A"파일 (패턴 규칙)에 대한 의존성을'erase_all_B' 의존성으로 대체하는 것으로 보입니다. 따라서 "rm"이 완료되면 파일이 빌드 된 것으로 간주하지만 패턴 규칙을 호출하지 않습니다. – kebs

+0

@kebs 최소한의 테스트를 해보십시오. 작동한다면 makefile에 다른 문제가 있습니다. – user657267

1

다음은, 당신은 0의 "목록을 작성할 수와 .a 파일을 생성 도구 나이가 사람을 제거하지 않는 경우

TO_REMOVE := $(filter-out $(B_FILES),$(wildcard *.b)) 

그리고

, 왜 제거 .b 일치하는 파일 : 12,파일과 같이 쉽게 "제거하려면? .a 파일이 아직 남아 있으므로 재생성됩니다. .a 파일이 수정 된 경우 해당 파일 .b은 make (오래된 파일 임)로 재생성됩니다.

+0

답장을 보내 주셔서 감사합니다. 그래, 이건 내 질문에 약간 명확하지 않을 수 있습니다. 파일을 생성하는 응용 프로그램은 아무 것도 지우지 않고 필요한만큼 많은 파일을 현재 폴더에 덤프합니다. 그러나 나는 목표물을 실행 한 후에 "새로운"파일 만 남아 있기를 원합니다. – kebs

+0

이전의'.a' 파일을 제거하려고합니다 (시뮬레이트 된 쉘 세션에 따라)? –

+0

네, 실제로 필수는 아니지만 그렇습니다. 내가 관심을 갖는 것은 "B"파일이지만, 원하지 않는 "A"파일을 지움으로써 문제를 단순화 할 수 있습니다. – kebs

관련 문제