
Makefile은 C 프로젝트에서 여러 `.c` 파일을 한 번에 빌드하기 위해 자주 쓰는 기본 도구입니다.
핵심은 컴파일과 링크를 나누고, 어떤 파일이 바뀌었을 때 무엇을 다시 만들지 적어두는 것입니다. 이 글은 GNU Make와 GCC 문서를 기준으로 target, dependency, object file, clean rule을 초보용 예제로 정리합니다.

Makefile이 필요한 순간
C를 처음 배울 때는 `gcc main.c -o app`이면 충분합니다. 하지만 파일이 `main.c`, `user.c`, `order.c`처럼 늘어나면 매번 긴 명령을 직접 치기 어렵고, 무엇을 다시 빌드해야 하는지도 헷갈립니다.
src/
main.c
user.c
user.h
order.c
order.hMakefile은 이 빌드 규칙을 파일에 남겨서 같은 명령을 반복하지 않게 해 줍니다.
컴파일과 링크를 나누어 보자
C 빌드는 크게 컴파일과 링크로 나눌 수 있습니다. 컴파일은 `.c` 파일을 object file인 `.o`로 바꾸는 단계이고, 링크는 여러 `.o` 파일을 실행 파일로 묶는 단계입니다.
gcc -c main.c -o main.o
gcc -c user.c -o user.o
gcc main.o user.o -o app이렇게 나누면 `user.c`만 바뀌었을 때 `main.c`까지 다시 컴파일하지 않아도 됩니다. 큰 프로젝트일수록 이 차이가 커집니다.
가장 작은 Makefile 예제
Makefile의 기본 형태는 target, dependency, recipe로 읽으면 됩니다. target은 만들 결과물, dependency는 그 결과물에 필요한 입력, recipe는 실제 명령입니다.
app: main.o user.o
gcc main.o user.o -o app
main.o: main.c user.h
gcc -c main.c -o main.o
user.o: user.c user.h
gcc -c user.c -o user.o주의할 점은 recipe 줄 앞에는 공백이 아니라 탭 문자가 들어가야 한다는 것입니다. Makefile 입문자가 가장 자주 만나는 실수입니다.
변수로 중복을 줄이기
컴파일러 이름이나 옵션이 여러 줄에 반복되면 변수를 두는 편이 좋습니다. 나중에 경고 옵션이나 표준 버전을 바꾸기 쉬워집니다.
CC = gcc
CFLAGS = -Wall -Wextra -std=c11
app: main.o user.o
$(CC) main.o user.o -o app
main.o: main.c user.h
$(CC) $(CFLAGS) -c main.c -o main.o
user.o: user.c user.h
$(CC) $(CFLAGS) -c user.c -o user.o변수는 Makefile을 고급스럽게 보이게 하려는 장식이 아니라, 같은 빌드 정책을 한곳에서 관리하기 위한 장치입니다.
clean rule은 왜 따로 둘까
빌드 결과물을 지우고 처음부터 다시 빌드해야 할 때가 있습니다. 이때 `clean` target을 두면 object file과 실행 파일을 한 번에 정리할 수 있습니다.
.PHONY: clean
clean:
rm -f app *.o`.PHONY`는 clean이 실제 파일 이름이 아니라 명령용 target이라는 뜻을 분명히 합니다.
실무 체크리스트
- 먼저 .c 파일을 .o 파일로 컴파일하는 흐름을 이해한다
- 실행 파일은 여러 .o 파일을 링크해서 만든다
- 헤더 파일을 dependency에 넣어 변경 시 다시 빌드되게 한다
- CC, CFLAGS 같은 변수로 반복 옵션을 관리한다
- clean rule과 .PHONY를 추가해 빌드 산출물을 정리한다
정리
Makefile는 이름만 외우는 것보다 어떤 문제를 줄이기 위한 도구인지 보는 편이 좋습니다. 이 글에서는 공식 문서 기준으로 핵심 개념, 자주 하는 실수, 실무 판단 기준을 함께 정리했습니다.
함께 보면 좋은 내부 글은 C 언어 헤더 파일은 왜 나눌까, C extern 변수는 왜 필요할까, C 언어 배열과 포인터는 같은 걸까입니다. 외부 기준은 GNU Make Manual – Introduction, GCC Manual – Overall Options, GNU Make Manual – Rule Syntax를 확인했습니다.