Makefile 정리

jaehlee·2025년 4월 28일

Makefile

Makefile은 make 명령어가 읽어들여 "무엇을 어떻게 빌드해야 하는지"를 적어놓은 스크립트 파일이다.
즉, 매번 터미널에 일일이 "gcc -Wall -Wextra -Werror main.c utils.c -o myprogram" 이런 명령어를 치는 대신 Makefile 안에 이 과정을 자동으로 적어두는 것이다.

Makefile의 기본구조

target: dependencies
	command    

target 만들고자 하는 파일 이름 (ex: 실행 파일, 오브젝트 파일 등)
dependencies 타겟을 만들기 위해 필요한 파일 목록 (ex: 소스 파일)
command 타겟을 만들기 위해 실행할 명령어들 (탭으로 시작해야 함)

예제

1. 가장 간단한 예제

all:
	gcc -Wall -Wextra -Werror main.c utils.c -o myprogram

2. 간단한 프로젝트 Makefile 예제

CC = cc
CFLAGS = -Wall -Wextra -Werror

NAME = myprogram
SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o)

all: $(NAME)

$(NAME): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^

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

clean:
	rm -f $(OBJS)

fclean: clean
	rm -f $(NAME)

re: fclean all

.PHONY: all clean fclean re

Makefile 명령어 정리

  1. make: makefile을 읽고 규칙대로 빌드 실행
  2. all: 기본 빌드 타겟(보통 프로젝트 전체 빌드)
  3. clean: 컴파일 결과물만 삭제(.o파일 등)
  4. fclean: 컴파일 결과물 + 실행 파일 삭제
  5. re: fcleanall다시 빌드
  6. .PHONY: 진짜 파일이 아닌 "가짜 타겟"임을 명시(충돌방지)

.PHONY에 대한 추가 설명
.PHONY를 사용할 때

.PHONY: clean 
clean:
	rm -f *.o myprogram

이 경우에는 clean이란 파일이 실제로 있어도 make clean을 실행하면 무조건 rm -f *.o myprogram 명령어가 실행된다
.PHONY를 사용하지 않을 때

clean:
	rm -f *.o myprogram

이 경우에는 만약 clean이라는 이름의 파일이 파일이나 디렉토리가 현재 디렉토리에 존재하면 make clean을 입력해도 "clean이 최신 상태이므로 아무것도 할 필요 없음" 으로 인식하고 명령어가 실행되지 않는다.
-> make clean명령어가 무시된다.

.PHONY가 중요한 이유

  • 빌드 명령어가 항상 정상적으로 실행된다.
  • 실제 파일 이름과 충돌같은 예외사항이 발생하지 않는다.

즉 .PHONY를 선언해둬야 동일한 이름이나 폴더가 존재해도 명령어가 정상 작동한다.

Makefile 자동변수 정리

  1. $@: 현재 타겟(target) 이름 (만들 결과물 이름)
  2. $<: 첫 번째 의존성 파일(prerequisite)
  3. $^: 모든 의존성 파일 목록(중복 제거)
  4. $+: 모든 의존성 파일 목록(중복 허용)
  5. $?: 현재보다 최신 버전인 의존성 파일 목록
  6. $*: 확장자 없는 타겟 이름 (패턴 규칙에서 주로 사용)

간단한 실행 순서

Makefile
 ├─ CC, CFLAGS 같은 변수 정의
 ├─ 규칙 (target : dependencies)
 │    └─ 명령어 (탭으로 시작)
 ├─ 자동변수 활용 ($@, $<, $^)
 └─ PHONY 설정으로 파일명 충돌 방지
profile
공부하는 개발자

0개의 댓글