Makefile을 만들어서 확인해 보셨는지요? 여하튼 편하자고 나온 툴이기 때문에 손에 익으시면 반드시 편할 수 밖에 없는 Makefile 입니다. 이번 시간에는 이전 내용에 살을 보태서 이해를 돕고 더 편리한 내용을 소개해 드릴까 합니다.

암시적 규칙

  암시적이라는 말이 좀 무엇인가가 대단하게 느껴집니다만 설명보다는 바로 예제부터 보겠습니다. 아래의 Makefile은 링크에 대한 정보만 있을 뿐 main.o, tcp.o rs232.o에 대한 컴파일에 대한 처리 내용이 없습니다.

OBJS = main.o tcp.o rs232.o
sample: $(OBJS)
   gcc -lm -o $@ $^

  그러나 make를 실행하면 main.c, tcp.c, rs232.c 를 컴파일해서 각각 .o를 구하고 링크 명령에 따라 실행파일이 만들어 집니다. 컴파일에 대한 규칙이 없는데도 어떻게 이렇게 처리가 될까요? 이렇게 처리되는 이유는 make에는 기본적으로 처리할 수 있는 규칙을 가지고 있습니다.

  위의 링크 명령 부분은 어떻게 링크해서 실행파일을 만드는지를 확실한 규칙을 make에게 주었다면 각 소스에 대한 컴파일 과정은 make에 미리 정의된 규칙에 따라 처리하게 된다는 것입니다. 이때 확실하게 알려준 규칙을 명시적 규칙이라고 하고 예제에서 처럼 컴파일 과정 처럼 생략되서 make 에 의해 보이지 않는 규칙에 따라 실행되는 것을 암시적 규칙이라고 합니다.

  혹, 어떤 Makefile을 봤더니 컴파일 과정이 생략되었다면 암시적 규칙에 따르고 있고, 또한 가능한 것이라는 점을 이해하실 수 있을 것입니다.

레이블

  이전 시간에 dep: 라는 레이블을 사용했는데, 이 레이블을 잘 이용하시면 매우 편리합니다. 예로 make로 주욱 컴파일해 왔는데, 때때로 이전 컴파일된 파일을 모두 삭제하고 새로 make 하고 싶을 때는 어떻게 하십니까?

]$ rm *.o
]$ rm 실행파일이름
]$ make

  이렇게 하시면 되는데, 매번 이렇게 하신다면 불편하실 거에요. 아예 Makefile에 집어 넣도록 하죠.

TARGET = sample
OBJS = main.o tcp.o rs232.o
SRCS = $(OBJS:.o=.c)
CC = -I/home/jwjw/prjs/include -g -c
$(TARGET): $(OBJS)
    gcc -lm -o $@ $^

.c.o:
    gcc $(CC) $<

clean:
    rm $(OBJS) $(TARGET)


dep :
    gccmakedep $(SRCS)
# DO NOT DELETE

  Makefile 중간에 clean: 레이블을 만들고 밑에 OBJS 파일과 TARGET 파일이름을 삭제하는 명령을 두었습니다. 이제 아래와 같이 입력하면 make는 clean: 레이블로 이동해서 그 부분부터 파일의 끝이나 다른 레이블이 만나기 전까지의 명령을 차례로 실행합니다 . 아래와 같이 make 를 실행하면 컴파일해서 나온 오브젝트 파일과 실행파일을 삭제하게 됩니다.

]$ make clean    -> 파일 삭제
]$ make    -> 컴파일 실행

  레이블 밑에 여러 실행 명령을 넣으시려면 각 행 앞에 탭 문자를 넣으시고 입력하시면 됩니다.

clean:
    rm $(OBJS) $(TARGET)

    echo "파일을 삭제했습니다."

명령 행 앞에 @를 붙이면

  위의 clean:을 실행하면,

]$ make clean
rm main.o tcp.o rs232.o sample
echo "파일을 삭제했습니다."         <- 요렇게 실행하려는 명령도 보입니다.
파일을 삭제했습니다.

  이럴 때, 화면 출력을 원하지 않는 명령행은 앞에 @를 붙여 줍니다.

clean:
    rm $(OBJS) $(TARGET)
    @ echo "파일을 삭제했습니다."

  이제는 실행하려는 명령 행이 보이질 않습니다.

]$ make clean
rm main.o tcp.o rs232.o sample
파일을 삭제했습니다.

 

태그: *makefile *C언어 *초보