make 로 소스 dependency 만들기

Computing 2010. 3. 27. 16:25

다음과 같은 소스코드가 있다.

hdr.h :

main.c :


1 - 100 까지의 합을 구해서 출력하는 단순한 프로그램이다. Makefile 을 조금 복잡하게 만든다면 분명 아래처럼 만들텐데 :

이처럼 Makefile 을 만든 후, make 를 하게 되면 물론, 컴파일이 성공적으로 이루어진다 :

~/work/ex$ make clean
rm -f *.o *.d core sum
~/work/ex$ make all
gcc -Wall -o main.o -c main.c
gcc -o sum main.o
~/work/ex$ ./sum
sum = 5050
~/work/ex$

당연하겠지만, main.c 를 약간 수정한 후 make 를 하면 main.c 를 다시 컴파일한다.

그렇지만, hdr.h 에 있는 LOOP_CNT 상수를 수정한 후 make 를 하면? 다음과 같이 나온다 :

~/work/ex$ sed 's/100/200/g' hdr.h > a.h; mv a.h hdr.h
~/work/ex$ cat hdr.h
#ifndef __HDR_H__

#define LOOP_CNT 200

#endif /* __HDR_H__ */
~/work/ex$ make
make: Nothing to be done for `all'.

main.c 를 다시 컴파일해야 함에도 불구하고, 컴파일을 해 주지 않는다! hdr.h 를 바꾸면 알아서 hdr.h 에 dependent 한 소스파일을 찾아서 다시 컴파일을 하도록 만들 수 없을까?


gcc 에는 -M 이라는 옵션이 존재한다. dependency 를 체크해서 이것을 Makefile 형태로 출력해 주는 옵션이다. 자세한 것은 gnu의 manual페이지를 참고하면 알 수 있다 : http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Preprocessor-Options.html#Preprocessor-Options

이것을 이용해서 아래와 같이 Makefile 을 수정하면, 헤더가 바뀌어도 알아서 그 헤더에 dependent 한 소스도 컴파일을 하도록 할 수 있다 :

gnu make 의 manual 페이지에도 위와 같은 내용이 나온다 : http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites

Makefile 에서 include 앞에 '-'를 붙인 것은, 에러가 나도 무시하라는 뜻이다. gnu make 는 두 개의 phase 를 가지고 Makefile 을 해석하는데, 첫번째 phase 에서 include 를 하려고 .d 파일을 찾으면 아직 .d 파일을 만드는 타겟이 실행되기 전이므로 .d 파일을 찾을 수 없다는 에러가 발생하는데, 보기 좋지 않다. 그래서 '-' 를 앞에 붙여서 에러를 무시하도록 한다. 두번째 phase 에 진입해서는 .d 파일이 만들어진 이후이므로 문제 없음.

어떻게 해서 이것이 가능한지 궁금하신 분들은 .d 파일의 내용을 보시면 된다. 간단하니 설명은 생략하고 넘어가겠다.

: