Makefile - 3. Makefile의 기능 확장 (3-3. 조건문 활용 (Conditional Statements))

2025. 3. 11. 19:07개발/개발도구와 환경

📌 3-3. 조건문 활용 (Conditional Statements)

Makefile에서 조건문(Conditional Statements)을 사용하면 특정 상황에 따라 다른 빌드 옵션을 적용할 수 있습니다.
이를 활용하면 디버그 모드, 특정 기능 활성화, 환경 변수 설정 등을 유동적으로 변경할 수 있습니다.


1. 조건문(Conditional Statements)이란?

📌 1-1. Makefile에서 조건문을 사용하는 이유

환경에 따라 다른 빌드 옵션 적용

  • 디버그 모드(DEBUG=1일 때 -g 플래그 추가)
  • 특정 기능(FEATURE_X 활성화 시 -DFEATURE_X 플래그 추가)

플랫폼별 빌드 설정 가능

  • Windows와 Linux에서 다른 컴파일러 옵션 적용 가능

유지보수 및 확장성 향상

  • 특정 조건에 따라 Makefile을 유연하게 변경 가능

2. ifeq 조건문 활용

📌 2-1. ifeq 기본 문법

ifeq 조건문을 사용하면 특정 변수가 특정 값과 같을 때만 실행하도록 설정할 수 있습니다.

ifeq (변수값, 비교값)
  # 조건이 참일 때 실행할 코드
endif
  • ifeq는 (변수, 값) 형태로 변수를 비교.
  • 값이 일치하면 해당 블록이 실행됨.

📌 2-2. ifeq 활용 예제

🔹 예제 1: DEBUG 모드 활성화 시 -g 플래그 추가

CC = gcc
CFLAGS = -Wall

ifeq ($(DEBUG),1)
  CFLAGS += -g
endif

all:
	$(CC) $(CFLAGS) -o myprogram main.c

✅ 실행 방법:

make DEBUG=1

➡ gcc -Wall -g -o myprogram main.c 실행됨.
➡ DEBUG=1을 전달하지 않으면 -g 플래그가 빠짐.


📌 2-3. ifeq의 다양한 비교 방식

ifeq는 문자열을 비교할 수 있습니다.

🔹 예제 2: 특정 운영체제(OS) 감지

UNAME := $(shell uname)

ifeq ($(UNAME), Linux)
  CFLAGS += -DLINUX
endif

ifeq ($(UNAME), Darwin)
  CFLAGS += -DMACOS
endif

✅ 실행 시:

  • Linux에서 실행하면 CFLAGS += -DLINUX
  • MacOS에서 실행하면 CFLAGS += -DMACOS

3. ifdef 조건문 활용

📌 3-1. ifdef 기본 문법

ifdef는 변수가 설정되어 있는지 확인할 때 사용합니다.

ifdef 변수명
  # 변수가 존재할 때 실행할 코드
endif
  • ifdef는 변수의 값이 비어 있지 않으면 블록을 실행합니다.

📌 3-2. ifdef 활용 예제

🔹 예제 1: 특정 기능(FEATURE_X)이 정의되었을 때 컴파일 옵션 추가

CC = gcc
CFLAGS = -Wall

ifdef FEATURE_X
  CFLAGS += -DFEATURE_X
endif

all:
	$(CC) $(CFLAGS) -o myprogram main.c

✅ 실행 방법:

make FEATURE_X=1

➡ gcc -Wall -DFEATURE_X -o myprogram main.c 실행됨.
➡ FEATURE_X가 설정되지 않으면 -DFEATURE_X 플래그가 추가되지 않음.


📌 3-3. ifdef를 활용한 환경 변수 감지

🔹 예제 2: CC(컴파일러) 환경 변수 설정 감지

ifndef CC
  CC = gcc
endif

CFLAGS = -Wall

all:
	$(CC) $(CFLAGS) -o myprogram main.c

✅ 실행 방법:

make

➡ CC가 설정되지 않으면 기본값 gcc 사용.
➡ CC를 clang으로 변경하고 실행:

make CC=clang

➡ clang -Wall -o myprogram main.c 실행됨.


4. else, ifneq 활용하기

📌 4-1. else 조건문

ifeq 또는 ifdef와 함께 else를 사용할 수도 있습니다.

🔹 예제 1: DEBUG 모드에 따라 다른 설정 적용

ifeq ($(DEBUG),1)
  CFLAGS = -g -DDEBUG
else
  CFLAGS = -O2
endif

✅ 실행 결과:

make DEBUG=1   # CFLAGS = -g -DDEBUG
make           # CFLAGS = -O2

📌 4-2. ifneq 조건문

ifneq는 ifeq와 반대로, 값이 다를 경우 블록을 실행합니다.

ifneq ($(CC),gcc)
  CFLAGS += -DUSE_CUSTOM_COMPILER
endif

✅ 실행 결과:

make CC=clang  # CFLAGS += -DUSE_CUSTOM_COMPILER
make CC=gcc    # 추가 옵션 없음

5. ifeq와 ifdef를 함께 활용한 최적화된 Makefile

📌 최적화된 Makefile 예제

CC = gcc
CFLAGS = -Wall
SRC = main.c utils.c
OBJS = $(SRC:.c=.o)
TARGET = myprogram

# 디버그 모드 적용
ifeq ($(DEBUG),1)
  CFLAGS += -g -DDEBUG
else
  CFLAGS += -O2
endif

# 특정 기능 추가
ifdef FEATURE_X
  CFLAGS += -DFEATURE_X
endif

all: $(TARGET)

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

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

clean:
	rm -f $(OBJS) $(TARGET)

✅ 실행 결과:

make DEBUG=1            # 디버그 모드 활성화
make FEATURE_X=1        # FEATURE_X 활성화
make DEBUG=1 FEATURE_X=1 # 두 가지 옵션 활성화

📌 3-3. 조건문 활용 요약 정리

조건문  설명
ifeq ($(VAR), value) VAR가 특정 값과 같을 때 실행
ifneq ($(VAR), value) VAR가 특정 값과 다를 때 실행
ifdef VAR VAR가 정의되어 있을 때 실행
ifndef VAR VAR가 정의되지 않았을 때 실행
else ifeq, ifdef와 함께 사용하여 반대 조건 적용