foo.o
두 가지 "주요" 목표인 과 가 있는 Makefile이 있다고 가정해 보겠습니다 clean
. 전자에는 파일을 생성하는 방법이 있습니다 foo.o
. 후자는 모든 임시 파일을 삭제합니다.
종속성을 수동으로 지정할 필요성을 없애기 위해 종속성의 형식을 지정하는 유효한 makefile을 foo.o
목표로 삼고 있습니다 . 이 종속성 파일은 makefile에 포함되어 있습니다.foo.d
foo.o foo.d : dep1 dep2 depn
생성된 파일은 다음과 같습니다.
;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with C-x C-f and enter text in its buffer.
foo.o: foo.c
cc -c -o $@ $<
foo.d: foo.c
sh deps.sh $< > $@
include foo.d
.PHONY: clean
clean:
rm …
내가 만들고 싶을 때 foo.o
모든 것이 작동합니다. foo.d
(다시) 만들어지고, 포함되고, 만들어집니다 foo.o
. 문제는 clean
목표를 설정하고 싶을 때 foo.d
목표가 포함되거나 설정되기까지 한다는 것입니다.
foo.d
make가 타겟을 만드는 데 걸리는 시간을 포함하지 않게 하려면 어떻게 해야 하나요 ? clean
(아니면 foo.o
제작시에만 어떻게 포함시키나요?)
이 솔루션은 GNU Make의 기능을 사용합니다.
답변1
해결책은 매우 간단하지만 Makefile 코드를 다소 읽을 수 없게 만듭니다.
include
먼저, 지시문이 파일을 포함하려고 시도하고 파일이 없으면 실패한다는 점을 알아야 합니다 . 또한 -include
(또는 sinclude
) 파일이 존재하지 않는 경우에는 파일이 전혀 포함되지 않습니다. 그러나 그것은 우리가 원하는 것이 아닙니다. 가능하다면 포함된 makefile을 다시 생성하려고 시도하기 때문입니다.
이를 방지하는 방법은 두 가지입니다. Makefile이 포함 파일을 생성할 수 없다고 생각하도록 include 지시문 매개변수를 변경하거나(예: 상대 경로 대 절대 경로 등), 파일에 포함되지 않은 경우 매개변수를 생략하는 것입니다. 그것. 존재하다. 이 작업은 여러 가지 방법으로 수행할 수 있습니다.
-include $(wildcard foo.d*)
하지만 문제가 있습니다. 다른 파일과도 일치합니다. 그래서 우리는 다음과 같이 쓸 수 있습니다:
-include $(filter foo.d,$(wildcard foo.d*))
아니면 이것도:
-include $(filter foo.d,$(wildcard *))
또 다른 문제가 있습니다. foo.d
구현되지 않고 있다는 것입니다. 이 문제는 다른 대상으로 추가하여 해결할 수 있습니다 foo.o
.
foo.o: foo.c foo.d
또는 명령으로 추가하십시오.
foo.o: foo.c
$(MAKE) foo.d
cc …
또는 전화하지 않고 직접 make
:
foo.o: foo.c
sh script.sh …
cc …