반응형
Makefile이란?
- Makefile은 make 명령을 이용해 프로그램의 컴파일과 빌드 과정을 자동화하는 파일입니다.
- 다중 소스 파일을 관리하며, 파일 의존성을 기반으로 필요한 부분만 재컴파일하여 시간을 절약합니다.
Makefile의 기본 구성 요소
1) 목표(Target)
- 빌드해야 할 대상 파일(예: 실행 파일 이름).
2) 의존성(Dependencies)
- 대상 파일이 생성되기 위해 필요한 파일(예: 소스 파일, 헤더 파일).
3) 명령(Rules)
- 의존성을 만족하기 위해 실행할 명령어(예: 컴파일 명령).
기본 Makefile 구조
# 변수 설정
CC = gcc # 컴파일러 설정
CFLAGS = -Wall -g # 컴파일 플래그 설정
# 소스 및 타겟 설정
TARGET = program # 최종 생성될 실행 파일
SRC = main.c module.c # 소스 파일 목록
OBJ = main.o module.o # 객체 파일 목록
# 기본 타겟
$(TARGET): $(OBJ) # 실행 파일 생성 규칙
$(CC) $(CFLAGS) -o $@ $^ # 객체 파일을 링크하여 실행 파일 생성
# 객체 파일 생성 규칙
%.o: %.c # 모든 .c 파일 -> 대응하는 .o 파일 생성
$(CC) $(CFLAGS) -c $< -o $@
# 클린업 규칙
clean:
rm -f $(OBJ) $(TARGET) # 객체 파일 및 실행 파일 삭제
Makefile 코드 상세 설명
1. 변수 정의
변수는 Makefile에서 반복되는 값을 간단히 설정하기 위해 사용됩니다.
CC = gcc
CFLAGS = -Wall -g
- CC: 사용할 컴파일러를 지정. 대부분 gcc 또는 clang 사용.
- CFLAGS: 컴파일러 플래그 설정.
- -Wall: 컴파일 시 모든 경고 표시.
- -g: 디버깅 정보를 포함.
2. 타겟과 의존성
타겟은 Makefile의 주요 목적입니다. 타겟은 의존성과 명령으로 구성됩니다.
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
- $(TARGET): 생성할 최종 실행 파일.
- $(OBJ): 실행 파일을 생성하기 위해 필요한 객체 파일 목록.
- 명령: 객체 파일을 링크하여 실행 파일 생성.
- $@: 현재 타겟의 이름 (program).
- $^: 모든 의존성 파일 목록 (main.o module.o).
3. 패턴 규칙
패턴 규칙은 특정 파일 유형에 대해 공통 작업을 정의합니다.
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
- %.o: 어떤 .o 파일이든 타겟이 될 수 있음.
- %.c: 대응하는 .c 파일.
- 명령:
- $<: 첫 번째 의존성 파일(현재 .c 파일).
- $@: 현재 타겟 파일(생성될 .o 파일).
- 작동 방식:
- main.c → main.o
- module.c → module.o
4. 클린업 규칙
clean은 빌드 과정에서 생성된 파일을 삭제하는 규칙입니다.
clean:
rm -f $(OBJ) $(TARGET)
- rm -f: 강제로 파일을 삭제. 오류 메시지 방지.
- $(OBJ): 모든 객체 파일(main.o, module.o) 삭제.
- $(TARGET): 실행 파일(program) 삭제.
사용 방법:
make clean
Makefile의 동작 흐름
- 실행 파일 생성 타겟:
- program 실행 파일 생성.
- 객체 파일(main.o, module.o)이 필요한 의존성.
- $(TARGET): $(OBJ) $(CC) $(CFLAGS) -o $@ $^
- 객체 파일 생성 규칙:
- .c 파일을 컴파일하여 대응하는 .o 파일 생성.
- %.o: %.c $(CC) $(CFLAGS) -c $< -o $@
- 클린업:
- 중간 파일과 실행 파일 삭제.
- clean: rm -f $(OBJ) $(TARGET)
확장된 Makefile 기능
1. 자동 의존성 생성
헤더 파일 변경 시 관련 객체 파일을 자동으로 재컴파일하도록 설정.
# 자동 의존성 생성
DEP = $(OBJ:.o=.d)
%.d: %.c
$(CC) -M $(CFLAGS) $< > $@
include $(DEP)
- .d 파일: .c 파일의 의존성을 저장.
- -M 옵션: 헤더 파일 의존성 생성.
2. 다중 타겟
다양한 실행 파일을 한 Makefile로 관리.
all: program test
program: main.o module.o
$(CC) $(CFLAGS) -o program main.o module.o
test: test.o
$(CC) $(CFLAGS) -o test test.o
- all 타겟: program과 test를 모두 빌드.
Makefile 실행 예제
- make 실행:
- 실행 파일(program) 생성.
- make
- 파일 변경 후 재컴파일:
- main.c 수정 시, Make는 main.o만 다시 컴파일.
- clean 실행:
- 빌드 과정에서 생성된 파일 삭제.
- make clean
예제 프로젝트
파일 구조
project/
├── Makefile
├── main.c
├── module.c
├── module.h
Makefile
# 변수 설정
CC = gcc
CFLAGS = -Wall -g
TARGET = program
SRC = main.c module.c
OBJ = main.o module.o
# 실행 파일 빌드
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
# 개별 객체 파일 컴파일
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 클린업
clean:
rm -f $(OBJ) $(TARGET)
main.c
#include "module.h"
int main(void) {
printMessage();
return 0;
}
module.c
#include <stdio.h>
#include "module.h"
void printMessage() {
printf("Hello, Makefile!\n");
}
module.h
#ifndef MODULE_H
#define MODULE_H
void printMessage();
#endif
실행
- 컴파일 및 빌드:
- make
- 실행:
- ./program
- 출력 결과:
- Hello, Makefile!
- 클린업:
- make clean
Makefile은 복잡한 프로젝트의 빌드 과정을 단순화하는 강력한 도구입니다. 위 내용을 실습하며 이해를 심화시킬 수 있습니다. 추가로 궁금한 점이 있으면 질문해주세요! 😊
반응형
'Computer Science > C 언어' 카테고리의 다른 글
[C #13] 포인터와 배열 (Pointers and Arrays) (1) | 2024.12.11 |
---|---|
[C #12] 포인터 (Pointers) (1) | 2024.12.10 |
[C 10] 프로그램 조직화 (Program Organization) (1) | 2024.12.08 |
[C #9] 함수 (Functions) (3) | 2024.12.07 |
[C #8] 배열 (Arrays) (1) | 2024.12.06 |