Makefile Reference
Makefile 빌드 자동화 레퍼런스
Makefile Reference 소개
Makefile 레퍼런스는 GNU Make의 모든 핵심 개념을 다루는 완전한 검색형 치트 시트입니다. 타겟(기본 규칙, .PHONY, .DEFAULT_GOAL), 변수(재귀 =, 단순 :=, 조건 ?=, 추가 +=), 패턴 규칙(%, wildcard, patsubst, vpath), 함수(shell, foreach, filter, subst, strip, word), 조건부(ifeq/ifneq, ifdef/ifndef, 인라인 $(if)), 자동변수($@, $<, $^, $?, $*, $(@D)/$(@F)) 여섯 가지 카테고리로 구성되어 있습니다.
소프트웨어 엔지니어, 빌드 시스템 관리자, 임베디드 개발자, DevOps 엔지니어들은 Makefile을 사용해 C/C++ 프로젝트 컴파일, 테스트 파이프라인 자동화, Docker 이미지 빌드, 멀티 스텝 배포 워크플로우를 관리합니다. 이 레퍼런스는 오브젝트 파일 컴파일용 패턴 규칙 작성, 크로스 플랫폼 빌드(리눅스 vs 윈도우)를 위한 조건부 로직, 레시피를 간결하게 유지하는 자동변수 활용에 특히 유용합니다.
각 항목은 정확한 문법, 동작에 대한 명확한 설명, 그리고 Makefile에 바로 복사해서 쓸 수 있는 실제 코드 예제를 제공합니다. 재귀적 변수와 단순 확장 변수의 차이, vpath를 통한 소스 파일 검색 경로 제어, 복잡한 멀티 타겟 빌드 구조 설계 방법을 다룹니다. 처음 Makefile을 작성하든, 복잡한 재귀 빌드를 디버깅하든, 필요한 답을 즉시 찾을 수 있습니다.
주요 기능
- 6개 카테고리: 타겟, 변수, 패턴규칙, 함수, 조건부, 자동변수
- 4가지 변수 할당 방식: =(재귀), :=(단순), ?=(조건부), +=(추가) 모두 수록
- 자동변수 $@, $<, $^, $?, $*, $(@D)/$(@F) 실동작 예제 포함
- 패턴 규칙 구문(%.o: %.c)과 wildcard/patsubst 파일 목록 조작
- git 해시, 날짜 스탬프 등 동적 값 처리를 위한 $(shell ...) 함수 활용
- ifeq/ifneq와 ifdef/ifndef를 통한 크로스 플랫폼·디버그/릴리즈 조건부 빌드
- 프로젝트 루트의 동명 파일 충돌 방지를 위한 .PHONY 선언 방법
- 키워드 또는 카테고리별 즉시 검색 — 필요한 규칙을 바로 찾기
자주 묻는 질문
Makefile에서 = 과 := 의 차이는 무엇인가요?
= 은 재귀적 확장 변수로, 참조할 때마다 오른쪽 값을 재평가합니다. := 은 단순 확장 변수로, 정의 시점에 한 번만 평가됩니다. $(shell ...) 호출처럼 비용이 큰 확장은 := 을 사용해 한 번만 실행되도록 하는 것이 좋습니다.
.PHONY는 Makefile에서 어떤 역할을 하나요?
.PHONY는 해당 타겟 이름이 실제 파일이 아님을 선언합니다. 선언하지 않으면 프로젝트 루트에 clean이나 test라는 파일이 있을 때 Make가 타겟을 이미 최신 상태로 간주하고 건너뜁니다. 파일이 아닌 모든 타겟은 .PHONY에 등록하는 것이 권장됩니다.
Makefile의 자동변수 $@ 는 무엇인가요?
$@ 는 현재 규칙의 타겟 파일명으로 확장됩니다. "gcc -o $@ $^" 레시피에서 $@ 는 app이나 build/main.o 같은 타겟 이름으로 대체되어, 패턴 규칙 전체에서 레시피를 재사용하고 출력 파일명을 하드코딩하지 않을 수 있습니다.
패턴 규칙 %.o: %.c 는 어떻게 동작하나요?
% 와일드카드는 비어 있지 않은 임의의 문자열에 매칭되는 스템 역할을 합니다. Make가 main.o를 빌드해야 할 때 %.o: %.c 패턴에 매칭되어 %를 "main"으로 치환하고 main.c를 컴파일합니다. 소스 파일마다 개별 규칙을 작성할 필요가 없어집니다.
$^ 와 $< 의 차이는 무엇인가요?
$< 는 첫 번째 의존 파일 하나만 참조하며, 단일 소스 파일을 컴파일하는 규칙에 사용됩니다. $^ 는 중복이 제거된 모든 의존 파일을 참조하며, 모든 오브젝트 파일을 링커에 전달해야 하는 링크 규칙에 사용됩니다.
Makefile에서 $(shell ...) 은 어떻게 사용하나요?
$(shell 명령어) 는 셸 명령을 실행하고 그 출력을 Make 변수 값으로 치환합니다. git 커밋 해시 캡처($(shell git rev-parse --short HEAD))나 빌드 날짜($(shell date +%F)) 기록에 자주 사용됩니다. 매 참조마다 재실행되지 않도록 := 으로 할당하는 것이 좋습니다.
ifeq 와 ifdef 는 언제 각각 사용하나요?
ifeq ($(VAR), 값) 은 변수의 값이 특정 문자열과 같은지 비교할 때 사용합니다 — 예를 들어 OS가 Windows_NT인지 확인. ifdef VAR 는 값과 무관하게 변수가 정의되어 있는지만 확인할 때 사용합니다 — 예를 들어 DEBUG 플래그가 설정되어 있는지 확인.
.DEFAULT_GOAL 은 무엇인가요?
.DEFAULT_GOAL 은 타겟을 지정하지 않고 make 를 실행했을 때 어떤 타겟을 실행할지 설정합니다. 기본적으로는 파일의 첫 번째 타겟이 기본값이 되지만, .DEFAULT_GOAL := help 를 설정하면 help 타겟이 기본값이 되어 대규모 프로젝트에서 자기 문서화 Makefile 패턴을 구현할 수 있습니다.