Makefile - 5. Makefile 최적화 및 실전 프로젝트 적용 (5-2. Makefile 디버깅 (Debugging Makefiles))

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

📌 5-2. Makefile 디버깅 (Debugging Makefiles)

Makefile을 작성할 때, 빌드 과정에서 예상치 못한 오류가 발생할 수 있습니다.
이때 디버깅 기능을 활용하면 빌드 과정과 실행될 명령을 쉽게 추적하여 문제를 해결할 수 있습니다.

특히, 다음과 같은 디버깅 기법이 유용합니다.

  1. make -n을 사용하여 실행 없이 명령만 출력 (Dry Run)
  2. make VERBOSE=1을 활용하여 자세한 명령어 출력

1. make -n을 활용한 실행 시뮬레이션 (Dry Run Mode)

📌 1-1. make -n의 개념

  • make -n을 실행하면 실제 빌드를 수행하지 않고, 어떤 명령어가 실행될지 출력됩니다.
  • Makefile을 실행하기 전에 어떤 작업이 수행될지 확인할 수 있는 디버깅 도구입니다.

활용 사례

  • 빌드를 실행하기 전에 실행될 명령어를 미리 확인하고 오류를 사전에 방지.
  • clean 같은 타겟을 실행할 때, 파일이 삭제되기 전에 어떤 파일이 삭제될지 확인 가능.
make -n

실제 명령은 실행되지 않고, 실행될 명령어만 출력됨.


📌 1-2. make -n 활용 예제

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

all: $(TARGET)

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

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

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

빌드 시뮬레이션

make -n

➡ 실제로 실행하지 않고 빌드 과정만 출력됨.

gcc -Wall -g -c main.c -o main.o
gcc -Wall -g -c utils.c -o utils.o
gcc -Wall -g -o myprogram main.o utils.o

make -n clean을 실행하여 삭제될 파일 확인

make -n clean

➡ 일반적인 경우 출력:

rm -f main.o utils.o myprogram

➡ 특정 환경에서는 파일 경로가 포함될 수도 있음:

rm -f ./main.o ./utils.o ./myprogram

📌 실제로 파일이 삭제되지 않으므로, 실행 전에 안전성을 검토 가능.


2. make VERBOSE=1을 활용한 디버깅 모드

📌 2-1. VERBOSE 변수를 사용한 디버깅

  • 기본적으로 Makefile은 실행되는 명령어를 최소한으로 출력합니다.
  • 하지만 make VERBOSE=1을 활용하면 실제 실행되는 명령어를 상세히 확인 가능합니다.
make VERBOSE=1

➡ VERBOSE 변수를 사용하여 추가 디버깅 정보를 출력.

활용 사례

  • 실제 실행되는 명령어를 그대로 확인.
  • 특정 옵션을 활성화하여 디버깅 플래그를 추가 가능.

📌 2-2. VERBOSE=1을 활용한 Makefile 작성 (출력 순서 개선)

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

# VERBOSE 모드 활성화
ifdef VERBOSE
  Q =
else
  Q = @
endif

all: $(TARGET)

$(TARGET): $(OBJS)
	$(Q)echo "Compiling completed. Now linking $@..."
	$(Q)$(CC) $(CFLAGS) -o $@ $^

%.o: %.c
	$(Q)echo "Compiling $<..."
	$(Q)$(CC) $(CFLAGS) -c $< -o $@

clean:
	$(Q)echo "Cleaning up..."
	$(Q)rm -f $(OBJS) $(TARGET)

개선된 점

  • Compiling이 먼저 출력되고 Linking이 나중에 출력됨 → 실제 빌드 순서와 동일하게 정리.
  • echo 메시지로 디버깅 시 단계별 진행 상황을 쉽게 확인 가능.

📌 2-3. VERBOSE=1을 사용한 실행 결과 비교

🔹 일반 실행 (make)

make

➡ 실행 결과:

Compiling completed. Now linking myprogram...

컴파일 과정이 보이지 않음.


🔹 디버깅 모드 (make VERBOSE=1)

make VERBOSE=1

➡ 실행 결과:

echo "Compiling main.c..."
gcc -Wall -g -c main.c -o main.o
echo "Compiling utils.c..."
gcc -Wall -g -c utils.c -o utils.o
echo "Compiling completed. Now linking myprogram..."
gcc -Wall -g -o myprogram main.o utils.o

실제 명령어가 그대로 출력되므로 디버깅이 용이.


3. 추가적인 Makefile 디버깅 옵션

📌 3-1. make -d (디버깅 메시지 출력)

make -d

모든 의존성 확인 및 실행 과정 상세 출력.
Makefile 내부에서 어떤 규칙이 실행되는지 디버깅 가능.


📌 3-2. make -p (Makefile 내부 변수 확인)

make -p

➡ Makefile에서 정의된 모든 변수와 규칙을 출력.
➡ Makefile에서 어떤 변수가 어떻게 설정되었는지 디버깅 가능.


📌 3-3. make --trace (실행되는 명령 추적)

make --trace

➡ 실행되는 각 명령어의 실행 순서를 출력하여 디버깅 가능.
어떤 규칙이 왜 실행되었는지 추적하는 데 유용.


📌 5-2. Makefile 디버깅 요약 정리

디버깅 방법 설명
make -n 실행 없이 어떤 명령이 실행될지 시뮬레이션
make -n clean 삭제될 파일을 실제 삭제 없이 미리 확인 (환경에 따라 출력 형식 차이 존재)
make VERBOSE=1 디버깅 모드 활성화 (모든 명령어 출력)
출력 순서 개선 컴파일(Compiling) 후 링킹(Linking) 순서로 메시지 조정
make -d Makefile의 디버깅 메시지 상세 출력
make -p Makefile 내부 변수와 규칙을 출력
make --trace 실행되는 명령 추적 (디버깅 용이)