2. Makefile

2.1 Makefile의 내부 구조

Makefile은 3가지의 rule들이 계속해서 나열됨.

target ... : dependency ...
                command
                ...
                ...
  • target(목표) : object file, 실행 file, make clean과 같은 label이다. command(명령)이 수행 되어서 나온 결과 파일을 지정한다.
  • dependency(의존 관계)
  • command(명령): command 부분에 정의된 것들은 아래의 상황에 차례대로 실행됨.(command는 TAB으로 시작해야함. 그래야 make가 command라고 인지함.)
    • dependency 부분에 정의된 file의 내용이 바뀌었거나,
    • target 부분에 해당하는 파일이 없을 때

 

2.2 Makefile 예제

시나리오

main.c, read.c, write.c와 io.h라는 헤더로 구성된 프로그램.

이들을 각각 컴파일하여 test라는 실행 파일을 생성시켜보자.

read.c, write.c, io.h 빈 파일을 생성했으며,

main.c로 "hello make"를 출력하는 코드를 삽입했다.

#include <stdio.h>

int main(){
    printf("hello make\n");
    return 0;
}

[make 사용 X]

gcc -c main.c
gcc -c read.c
gcc -c write.c

gcc -o test main.o read.o write.o

[make 사용 O]

test : main.o read.o write.o
        gcc -o test main.o read.o write.o

main.o : io.h main.c
            gcc -c main.c
read.o : io.h read.c
            gcc -c read.c
wrtie.o: io.h write.c
            gcc -c write.c

make를 실행하니 아래와 같이 .o(object file)과 test(실행 file)이 생성됐다.

의존 관계 텍스트 그림 출처 : http://doc.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make-2.html

이 그림을 봤을 때, io.h는 모든 .c 파일이 의존하고 있다. 그렇기 때문에 io.h가 변경된다면 모든 파일이 다시 컴파일 됨을 그림을 통해 알 수 있다.

하지만, main.c만 수정됐다고 가정했을 때, main.c만 컴파일되어 main.o만 새로 생성된다. 그리고 test(실행 파일)이 갱신된다.

한 번 테스트 해보겠다.

우선 main.c만 수정해보겠다.

#include <stdio.h>

int main(){
    printf("hello make\n");
    printf("hello make2\n");
    return 0;
}

그리고 다시 make했다.

주황색 박스는 수정 전("hello make2"를 추가하기 전)이며, 노란색 박스는 수정 후의 make다.

예상했던 것처럼 노란색 박스에서는 main.c만 다시 컴파일 됐으며, test 실행 파일이 새로 생성됐다.

이제 io.h를 수정했을 때 모든 파일이 다시 컴파일 되는지 아래와 같이 io.h만 수정해보겠다.

아래는 아무 의미없는 코드이다.

#define COMPILE_TEST 0

그리고 다시 make 해보겠다.

?? 모든 파일이 다시 컴파일될 것이라 예상했던 것과 다르게 write.o는 다시 생성되지 않은 모양이다. 영문을 모르겠다. 조만간 지인 찬스를 사용하여 답변하겠다.

 

2.3 매크로의 사용

OBJECTS = main.o read.o write.o

test : $(OBJECTS)
                gcc -o test $(OBJECTS)

main.o : io.h main.c
                gcc -c main.c
read.o : io.h read.c
                gcc -c read.c
write.o: io.h write.c
                gcc -c write.c

OBJECT라는 매크로를 만들었다. 매크로를 사용할 때는 위 코드와 같이 $(매크로명)을 사용한다.

 

2.4 레이블(label)의 사용

target 부분에 해당하는 부분이 label과 같이 사용될 수도 있다.

아래 코드는 object파일을 모두 삭제하는 명령어를 추가하였다.

OBJECTS = main.o read.o write.o

test : $(OBJECTS)
                gcc -o test $(OBJECTS)

main.o : io.h main.c
                gcc -c main.c
read.o : io.h read.c
                gcc -c read.c
write.o: io.h write.c
                gcc -c write.c

clean :
                rm $(OBECTS)

'임베디드 > make' 카테고리의 다른 글

1. GNU make란?  (0) 2021.03.18

+ Recent posts