본문 바로가기
컴파일을 더더더 쉽게. MACRO와 SUFFIX

컴파일을 더더더 쉽게 하려면, MACRO를 이용한 방법이 있는데, 잘 살펴보면 재미있습니다. MACRO는 컴퓨터에서 이용되는 분야라면 어디든 사용되는 개념이니, Makefile에서도 예외라고 할 수 없습니다. Makefile에서는 MACRO를 이용하여, Makefile을 만드는 작업조차 간단하게 만들었는데, 이 것을 잘 모르면, Makefile을 분석하거나, 더더더 편하게 만들기
힘드니까, 이번 기회에 깔끔하게 정리할 필요가 있겠습니다.

우선 MACRO는 다음과 같이 선언합니다. 예)를 들어,

CC = tcc

선언은 이렇게 하고 사용은 어떻게 하느냐!

$(CC) 로 사용하는 거죠. 이렇게 하면, $(CC)라고 표현되어 있는 부분은 모두 tcc로 바뀌게 됩니다. 이외 여러 가지 ?=, :=, += 로 선언하는 방법들도 있긴 합니다만, 사족으로 넘깁시다.

자, 그러면 이 MACRO를 이용하여, spaghetti.mak를 조금 더 간단하게 수정해 보겠습니다.

1. 간단한 MACRO로 간단하게 만들기

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $(TARGET) $(ELF_TARGET)

$(ELF_TARGET) : spaghetti.o manupulation.o
    armlink -elf -o $(ELF_TARGET) spaghetti.o manupulation.o

spaghetti.o : spaghetti.c
    $(CC) -c spaghetti.c

manupulation.o : manupulation.c
    $(CC) -c manupulation.c

오, 먼가 조금 깜찍하게 깔끔해 진 것 같기도 합니다. 내친 김에 조금 더 간추려 볼까요?

2. Link 없애기

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $(TARGET) $(ELF_TARGET)

$(ELF_TARGET) : spaghetti.o manupulation.o
    $(CC) -o $(ELF_TARGET) spaghetti.o manupulation.o

spaghetti.o : spaghetti.c
    $(CC) -c spaghetti.c

manupulation.o : manupulation.c
    $(CC) -c manupulation.c

이번엔 Link 과정이 없어졌습니다요. 하지만, Link과정이 없어졌다기 보다는 tcc가 -o optoin을 통해서 곧바로 link까지 진행하니까 마치 없어진 것처럼 보이지만, 우리 한가지를 더 간단하게 했네요. 진전입니다. 진전 더 간단히 갈 때까지 가 볼 것입니다.

조금 더 간추려 봅시다. 점점 더 암호화 해서 가장 간단하게 만들어 내는 것이 우리 목적입니다. 자 이제부터 이용할 것이 우리 중복해서 사용하는 것들이 너무 많습니다. file name들인데, 이 녀석들도 어떻게든 줄이고 싶습니다. 특히나 만들고 싶은 output을 만들기 위해 시키고 싶은 일에는 반드시 file 이름들이 중복되고 있습니다.

이럴 때 이용하는 것이 바로 $@, $^ 들인데, 미리 약속된 Macro들입니다. $@은 현재의 만들고 싶은 output이름이고, $^는 재료들의 이름입니다. 이제부터 정신 똑바로 차리고 가보시죠. 길 잃으시면 안 되요.

3. 재료와 Output 이름도 간단하게 $@, $^

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $@ $^

$(ELF_TARGET) : spaghetti.o manupulation.o
    $(CC) -o $@ $^

spaghetti.o : spaghetti.c
    $(CC) -c @^

manupulation.o : manupulation.c
    $(CC) -c @^

어, 점점 더 간단해져 가고 있습니다. 아까 보다 훨씬 짧아지고 간단해 졌지요? 자, 우리는 make가 대단히 smart하다는 것을 익히 느껴가고 있으니까, 더 간단하게 한번 해볼까요? 재료들 이름 쓰는 것도 귀찮으니까, 자자~ 이렇게 가보겠습니다.

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
OBJECTS = spaghetti.o manupulation.o

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $@ $^

$(ELF_TARGET) : $(OBJECTS)
    $(CC) -o $@ $^

어? 더 암호화 된 모습니다. 이걸로도 정말 makefile이 제대로 작동할 까요? 제대로 작동합니다. 정말로 멋진 모습입니다. 결국 OBJECTS (재료들)만 선언해 주고, compile은 Macro 한 줄로 모든 걸 해결해 버렸네요.

여기에서 마지막줄의 $(CC) -o $@ $^ 요 부분에서 보면 어쨌거나 .o로 된 녀석들은 CC를 이용해서 .c를 만들어 내는 건 공통이겠죠? 그러니까 확장자 규칙이란 걸 쓰면 더욱 간단하게 할 수 있습니다.


4. 반복되는 확장자 관계도 간략하게~ (.c → .o), SUFFIX rule 이용하기

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
OBJECTS = spaghetti.o manupulation.o

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $@ $^

$(ELF_TARGET) : $(OBJECTS)

%o : %c
    (CC) -c $@ $<


오호라 마지막에 처음 보는 %가 나왔지요? 이런 건 .o가 나오면 같은 이름의 .c를 (CC)를 이용해서 컴파일 해라 뭐 이런 의미로 사용되는 겁니다. 확장자규칙이라고 부르는데요. 이렇게 하면 심지어. 다른 확장자를 가진 녀석들도 한꺼번에 OBJECT에 넣어놓고 확장자 규칙만 추가하면 한꺼번에 $(ELF_TARGET)을 만들어 낼 수 있는 게지요. 3번 예에서 실은 요 rule이 숨어 있는 거지요. 일반적인 make는 .c를 .o로 만드는 일이 대부분 이니까, Default make 설정으로 이걸 갖고 있어요. 그러니까, 이런 식으로 다시 선언해 주면 좀 더 명확해 질 수 있으니까, 만드는 사람들에 따라서 이걸 명확하게 선언해 주는 사람들도 많이 있습니다.

이런걸 이용해서, .c뿐만 아니라, 자신만의 확장자 rule을 이용해서, 다른 명령을 만들 수도 있는 거지요. 예를 들어 자신만의 script 파일을 만들었는데, 그 script를 해석하는 tool을 자기가 만들었다고 칩시다. script file의 확장자는 .m 이고, tool의 이름은 mytool이라고 치고요. 장난친 후의 file의 확장자가 .out이라고 한다면요.

Compile중에 이런 일을 좀 했으면 좋겠는데 싶은 상황에

%.out : %.m
    mytool $@ $<

요렇게 만들어 놓으면 재료 중에 .m file을 만나면 mytool을 이용해서 .m을 .out으로 만들어 준다니깐요. 음화화. 한가지 유의할 사항은 Suffix rule에서의 재료는 @^대신 @<를 쓴다는 거 잊지 마세요~

5. 어떤 한 디렉토리를 통째로 한꺼번에 컴파일 하고 싶을 때

한가지 더, 이제는 OBJECTS를 선언해 주는 것도 귀찮아져 버렸습니다. 이럴 때는 또 더 간단하게 해결할 수 있는 방법이 있습니다.

SRC = $(wildcard *.c)
OBJECTS = $(SRC:.c=.o)

마지막으로 Spaghetti.mak의 재료들이 모두 .c이고, output이 모두 .o라면, 이렇게 make위에 선언만 해준다면, 현재 Directory의 모든 c file을 SRC로 등록을 한 후, MACRO 안에서 .c만 .o로 모두 바꾸어 OBJECTS로 선언해 줍니다. MACRO의 새로운 용법이네요. 그렇다면~

spaghetti.mak -------------------------------------------------------------------------

TARGET = spaghetti.bin
ELF_TARGET = spaghetti.elf
BINTOOL = fromelf
CC = tcc
SRC = $(wildcard *.c)
OBJECTS = $(SRC:.c=.o)

$(TARGET) : $(ELF_TARGET)
    $(BINTOOL) -bin -o $@ $^

$(ELF_TARGET) : $(OBJECTS)
    $(CC) -o $@ $^

더 더욱이 간단해 졌습니다. 우리가 이렇게 까지 달려올 줄 누가 알았겠습니까. 이런 기법을 이용한다면, source file이 수만 개가 되더라도 간단하게 compile할 수 있겠습니다. 자, 다 덤벼 보시지.

그 결과는 다음과 같이 모두 같습니다. 냐하~
E:\>make
tcc -c -o manupulation.o manupulation.c
tcc -c -o spaghetti.o spaghetti.c
tcc -o spaghetti.elf manupulation.o spaghetti.o
fromelf -bin -o spaghetti.bin spaghetti.elf

 
Linked at 임베디드 시스템 개발자 되기 .. at 2009/06/26 01:16

... ocator ⓠ Makefile은 뭘하는 녀석일까~ ⓡ 컴파일을 더더더 쉽게. MACRO와 SUFFIX ⓢ 조금 더 Make 테크닉들 ⓣ Make option들 4) ... more

친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -