Makefile은 프로젝트 빌드 자동화와 의존성 관리를 담당하는 핵심 도구임. 다양한 숨은 규칙과 기호로 인해 처음 접할 때 복잡하게 느낄 수 있으나, 이 가이드는 주요 내용을 간결하고 직접 실행 가능한 예제로 정리함. 각 섹션별로 실습 기반 예시를 통한 이해가 가능함. 타겟: 의존성(들) 타겟: 빌드 결과 파일명(보통 하나) 명령어: 실제 동작하는 쉘 스크립트(탭으로 시작) 의존성: 타겟이 빌드되기 전에 반드시 준비되어야 할 파일 목록 예시: 예시: 이 가이드는 Makefile에 대해 실제로 동작하며 이해할 수 있는 풍부한 예제와 함께 전체 동작 원리와 실무적인 작성법을 포괄적으로 설명함.
Makefile 튜토리얼 가이드 소개
시작하기
Makefile의 존재 목적
Make의 대안 빌드 시스템
Make의 버전과 종류
예제 실행 방법
Makefile 기본 구문
규칙(Rule)의 구조
Make의 본질
Hello World 예제
hello:
echo "Hello, World"
echo "This line will print if the file hello does not exist."
C 파일 컴파일 기본 예제
blah:
cc blah.c -o blah
의존성 추가 방식
blah: blah.c
cc blah.c -o blah
예제 추가
연결된 타겟 및 의존성 예제
blah: blah.o
cc blah.o -o blah
blah.o: blah.c
cc -c blah.c -o blah.o
blah.c:
echo "int main() { return 0; }" > blah.c
반드시 실행되는 타겟 예제
some_file: other_file
echo "This will always run, and runs second"
touch some_file
other_file:
echo "This will always run, and runs first"
Make clean
변수 처리
files := file1 file2
some_file: $(files)
echo "Look at this variable: " $(files)
touch some_file
file1:
touch file1
file2:
touch file2
clean:
rm -f file1 file2 some_file
타겟 관리
all 타겟
all: one two three
one:
touch one
two:
touch two
three:
touch three
clean:
rm -f one two three
다중 타겟 및 자동 변수
all: f1.o f2.o
f1.o f2.o:
echo $@
자동 변수와 와일드카드
* 와일드카드
print: $(wildcard *.c)
ls -la $?
thing_wrong := *.o
thing_right := $(wildcard *.o)
% 와일드카드
Fancy Rules
암시적(Implicit) 규칙
CC = gcc
CFLAGS = -g
blah: blah.o
blah.c:
echo "int main() { return 0; }" > blah.c
clean:
rm -f blah*
Static Pattern Rules
objects = foo.o bar.o all.o
all: $(objects)
$(CC) $^ -o all
$(objects): %.o: %.c
$(CC) -c $^ -o $@
all.c:
echo "int main() { return 0; }" > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
Static Pattern Rules + filter 함수
obj_files = foo.result bar.o lose.o
src_files = foo.raw bar.c lose.c
all: $(obj_files)
.PHONY: all
$(filter %.o,$(obj_files)): %.o: %.c
echo "target: $@ prereq: $<"
$(filter %.result,$(obj_files)): %.result: %.raw
echo "target: $@ prereq: $<"
%.c %.raw:
touch $@
clean:
rm -f $(src_files)
패턴 규칙
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
%.c:
touch $@
Double-Colon Rules
all: blah
blah::
echo "hello"
blah::
echo "hello again"
명령어와 실행
명령어 출력 제어
각 명령어 실행 환경
쉘 종류 지정
달러 기호 이스케이프
에러 처리
make 중단 시 행동
재귀 make
변수와 환경
환경 변수 자동 읽기
export, .EXPORT_ALL_VARIABLES
Variables Pt. 2
변수의 종류와 확장
변수 초기화/추가/미정의
undefined 변수는 빈 문자열로 처리됨
명령행 인자, override
define/endef로 여러 줄 명령 정의
타겟별 변수, 패턴별 변수
조건문
if/else/ifeq/ifdef/ifndef
함수
내장 함수
filter, filter-out, nested filter
기타 고급 기능
include
vpath
멀티라인 명령
.PHONY
.DELETE_ON_ERROR
Makefile Cookbook: 실전 예제
TARGET_EXEC := final_program
BUILD_DIR := ./build
SRC_DIRS := ./src
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
DEPS := $(OBJS:.o=.d)
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
CPPFLAGS := $(INC_FLAGS) -MMD -MP
$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
$(CXX) $(OBJS) -o $@ $(LDFLAGS)
$(BUILD_DIR)/%.c.o: %.c
mkdir -p $(dir $@)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/%.cpp.o: %.cpp
mkdir -p $(dir $@)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -r $(BUILD_DIR)
-include $(DEPS)