2025. 3. 11. 19:11ㆍ개발/개발도구와 환경
📌 4-3. 빌드 캐싱 및 증분 빌드 (Build Caching & Incremental Build)
빌드 속도를 최적화하는 핵심 기법 중 하나는 빌드 캐싱(Build Caching)과 증분 빌드(Incremental Build)입니다.
이를 통해 변경된 파일만 다시 컴파일하여 불필요한 빌드를 방지하고, 전체 빌드 시간을 단축할 수 있습니다.
대표적인 방법으로 touch를 활용한 최신 빌드 관리와 ccache를 활용한 컴파일 캐싱이 있습니다.
1. 빌드 캐싱(Build Caching) 및 증분 빌드(Incremental Build)란?
📌 1-1. 빌드 캐싱과 증분 빌드 개념
- 증분 빌드(Incremental Build)
- 변경된 파일만 다시 컴파일하고, 변경되지 않은 파일은 재사용.
- Makefile의 의존성(Dependency) 관리를 통해 자동 수행됨.
- 빌드 캐싱(Build Caching)
- 이전에 컴파일한 결과를 저장하고, 같은 입력이 들어오면 기존 결과를 재사용.
- 대표적인 도구: ccache (컴파일 결과 캐싱)
📌 1-2. 빌드 캐싱 및 증분 빌드의 필요성
✅ 빌드 속도 최적화
- 전체 프로젝트를 다시 빌드하는 것이 아니라, 변경된 파일만 다시 컴파일.
- ccache를 사용하면 이전 컴파일 결과를 재활용하여 속도를 더욱 향상.
✅ 개발 생산성 향상
- 코드 변경 시 즉각적인 빌드 및 테스트 가능.
- 특히 대규모 프로젝트에서는 필수적인 최적화 기법.
✅ CI/CD(지속적 통합 및 배포) 환경에서 필수
- GitLab CI/CD, Jenkins 같은 자동화 환경에서도 빌드 시간을 최소화.
2. touch를 활용한 최신 빌드 관리
📌 2-1. touch 명령어란?
- touch 명령어는 파일의 수정 시간을 변경하는 유닉스 명령어.
- Makefile에서 특정 파일을 강제로 최신 상태로 유지할 때 사용 가능.
touch filename
➡ filename의 수정 시간을 현재 시간으로 업데이트.
📌 2-2. touch를 활용한 증분 빌드
Makefile에서 touch를 활용하면 강제로 파일을 최신 상태로 만들어 불필요한 재컴파일을 방지할 수 있습니다.
🔹 예제 1: touch를 활용한 최신 빌드 관리
CC = gcc
CFLAGS = -Wall -g
SRC = main.c utils.c
OBJS = $(SRC:.c=.o)
TARGET = myprogram
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
touch $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
✅ 설명
- $(TARGET): $(OBJS) 빌드 후 touch $@를 실행하여 myprogram의 시간을 최신으로 변경.
- 다음번 make 실행 시 변경되지 않은 경우 재컴파일을 방지.
✅ 실행 과정
make
➡ gcc -c 실행 후 gcc -o myprogram 실행됨.
make
➡ 파일이 최신 상태이므로 다시 빌드되지 않음.
📌 2-3. touch를 활용한 강제 빌드 트리거
파일을 강제로 재컴파일하려면 touch를 활용하여 특정 파일을 오래된 상태로 만들 수 있음.
touch main.c
make
➡ main.c의 시간이 업데이트되었으므로 main.o가 다시 컴파일됨.
touch $(OBJS)
make
➡ 모든 .o 파일을 재컴파일 없이 최신 상태로 유지.
3. ccache를 활용한 빌드 캐싱
📌 3-1. ccache란?
- ccache는 C/C++ 컴파일 결과를 캐싱하여 동일한 빌드를 재사용하는 도구.
- 동일한 입력(소스 코드, 컴파일 옵션 등)이 들어오면 기존 결과를 사용하여 재컴파일을 방지.
✅ ccache의 장점
- 중복된 컴파일 방지 → 빌드 속도 극대화.
- 클린 빌드(make clean && make) 후에도 속도 유지.
- CI/CD 환경에서 빠른 빌드 수행 가능.
📌 3-2. ccache 설치 및 설정
1️⃣ ccache 설치
Ubuntu/Debian:
sudo apt install ccache
Mac (Homebrew):
brew install ccache
Fedora:
sudo dnf install ccache
2️⃣ ccache를 Makefile에서 활용
기본적으로 ccache는 컴파일러 앞에 위치하여 실행됩니다.
CC = ccache 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)
✅ 설명
- CC = ccache gcc를 사용하여 gcc 대신 ccache gcc가 실행되도록 설정.
- 이미 컴파일된 파일이면 컴파일을 생략하고 캐시된 결과 사용.
📌 3-3. ccache 사용 예제
🔹 ccache 적용 전후 비교
time make
➡ 전체 빌드 수행 (오랜 시간 소요).
time make
➡ 변경된 파일이 없으면 즉시 완료됨 (캐시 적용됨).
📌 3-4. ccache 상태 확인
ccache의 캐시 상태를 확인하려면 다음 명령어를 실행:
ccache -s
➡ 캐시된 파일 개수, 히트율(Cache Hit Rate), 캐시 크기 등을 확인 가능.
📌 4-3. 빌드 캐싱 및 증분 빌드 요약 정리
기법 | 설명 |
touch 활용 | 특정 파일을 최신 상태로 유지하여 불필요한 재컴파일 방지 |
파일 강제 재컴파일 | touch main.c를 실행하면 해당 파일만 다시 컴파일 |
ccache 사용 | 이전 컴파일 결과를 저장하여 동일한 입력 시 캐시된 결과 사용 |
ccache 장점 | 클린 빌드 후에도 속도 유지, CI/CD 환경에서 필수 |