C++ 빌드 시스템 완전 비교 | CMake·Meson·Bazel·Makefile·패키지 매니저 선택 가이드
이 글의 핵심
C++ 빌드 시스템 완전 비교 가이드입니다. CMake, Meson, Bazel, Makefile의 장단점과 패키지 매니저 선택 기준을 실전 관점에서 설명합니다. "신규 프로젝트 시작하는데 CMake? Meson? Bazel? 뭘 써야 해요?" "레거시 Makefile 프로젝트를 유지보수하는데, 새 팀원이 Makefile 읽기를 못해요." "Windows에서는 되는데 Linux CI에서만 빌드가 깨져요.
들어가며: “빌드 시스템 뭘 쓰지?”
실제 겪는 문제 시나리오
"신규 프로젝트 시작하는데 CMake? Meson? Bazel? 뭘 써야 해요?"
"레거시 Makefile 프로젝트를 유지보수하는데, 새 팀원이 Makefile 읽기를 못해요."
"Windows에서는 되는데 Linux CI에서만 빌드가 깨져요."
"vcpkg 쓰는 팀과 Conan 쓰는 팀이 합쳐졌는데, 둘 다 쓸 수 있나요?"
"빌드가 30분 걸려요. Meson이나 Bazel로 바꾸면 빨라지나요?"
"Bazel 도입하려 했는데 학습 곡선이 너무 가파르대요."
"CMakeLists.txt가 3000줄인데, 유지보수가 지옥이에요."
이 글에서 다루는 것:
- 문제 시나리오: 빌드 시스템 선택·유지보수·마이그레이션 시 겪는 문제
- 완전한 빌드 시스템 비교: CMake·Meson·Bazel·Makefile·Ninja·패키지 매니저
- 자주 발생하는 에러와 해결법
- 마이그레이션 가이드: Makefile→CMake, CMake→Meson 등
- 프로덕션 패턴: CI/CD·캐시·재현 가능한 빌드
언어 경계를 넘어 보려면 Rust Cargo·npm·Node 모듈·Go 모듈·Python pip·uv·Poetry가 각각 빌드·의존성·캐시를 어떻게 묶는지와 대조하면, C++의 CMake + Conan·vcpkg 조합의 위치가 잡힙니다. Makefile 직접 작성과의 대비도 함께 참고하세요.
요구 환경: C++17 이상, 각 빌드 시스템 최신 버전
실무 적용 경험: 이 글은 대규모 C++ 프로젝트에서 실제로 겪은 문제와 해결 과정을 바탕으로 작성되었습니다. 책이나 문서에서 다루지 않는 실전 함정과 디버깅 팁을 포함합니다.
목차
- 문제 시나리오 상세
- 빌드 시스템 분류와 아키텍처
- 완전한 빌드 시스템 비교표
- CMake 상세
- Meson 상세
- Bazel 상세
- Makefile 상세
- 패키지 매니저: vcpkg·Conan
- 자주 발생하는 에러와 해결법
- 마이그레이션 가이드
- 프로덕션 패턴
- 선택 가이드와 의사결정
- 구현 체크리스트
1. 문제 시나리오 상세
시나리오 1: 신규 프로젝트 빌드 시스템 선택
상황: 3명 팀이 C++ 서버 프로젝트를 시작합니다. Windows·Linux·macOS 개발자가 각 1명씩 있습니다.
질문: CMake? Meson? Bazel? 뭘 써야 하나요?
고려 사항:
- 크로스 플랫폼 필수
- fmt, spdlog, Boost.Asio 등 외부 라이브러리 사용
- CI에서 GitHub Actions로 빌드
- 학습 곡선이 너무 가파르면 안 됨
해결 방향: CMake + vcpkg가 가장 현실적. Meson은 더 빠르지만 생태계가 작음. Bazel은 Google 스타일 팀에 적합.
시나리오 2: 레거시 Makefile 유지보수
상황: 10년 된 C++ 프로젝트가 Makefile만 있습니다. 새 팀원이 "Makefile 읽기 어려워요"라고 합니다.
질문: Makefile을 계속 쓸까요, CMake로 마이그레이션할까요?
고려 사항:
- Makefile 의존성 규칙이 복잡함
- IDE(CLion, VS Code) 지원이 Makefile보다 CMake가 좋음
- 점진적 마이그레이션 가능 여부
해결 방향: CMake로 점진적 마이그레이션. 또는 Makefile을 CMake의 ExternalProject로 감싸서 IDE 지원만 먼저 받기.
시나리오 3: 빌드 시간 폭증
상황: 10만 줄 코드베이스에서 전체 빌드에 30분, 증분 빌드에 5분 걸립니다.
질문: Meson이나 Bazel로 바꾸면 빨라지나요?
고려 사항:
- CMake + Ninja 조합이 이미 최적화됨
- 병목은 대부분 컴파일 자체(병렬화, PCH, ccache)
- 빌드 시스템 변경 비용 vs 이득
해결 방향: 먼저 ccache, PCH, 병렬 빌드(-j) 확인. Meson은 configure 단계가 빠름. Bazel은 대규모에서 증분 빌드가 강함.
시나리오 4: 패키지 매니저 충돌
상황: A팀은 vcpkg, B팀은 Conan을 써왔습니다. 팀이 합쳐졌습니다.
질문: 하나로 통일해야 하나요? 둘 다 쓸 수 있나요?
고려 사항:
- CMake는 vcpkg·Conan 둘 다 toolchain으로 연동 가능
- 동일 프로젝트에서 둘 혼용은 권장하지 않음(의존성 충돌)
- 팀 표준 하나로 통일 필요
해결 방향: 프로젝트 하나당 하나의 패키지 매니저. 팀 합치면 기존 라이브러리 수·CI 구축 상태를 보고 선택.
시나리오 5: 빌드 재현성
상황: "어제까지 되던 빌드가 오늘 CI에서 실패해요." vcpkg baseline이 업데이트된 것 같습니다.
질문: 어떻게 재현 가능한 빌드를 유지하나요?
고려 사항:
- vcpkg: builtin-baseline, vcpkg.lock
- Conan: conan.lock, 명시적 버전
- Docker로 빌드 환경 고정
해결 방향: lock 파일(vcpkg.lock, conan.lock)을 Git에 커밋. baseline/버전을 명시적으로 고정.
시나리오 6: 크로스 컴파일
상황: x86_64 호스트에서 ARM 임베디드 타겟용 빌드를 해야 합니다.
질문: 어떤 빌드 시스템이 크로스 컴파일을 잘 지원하나요?
고려 사항:
- CMake: toolchain 파일
- Meson: cross file
- Conan: 프로필
- Bazel: platform
해결 방향: CMake + Conan 또는 vcpkg triplet이 가장 문서화·예제가 많음.
2. 빌드 시스템 분류와 아키텍처
빌드 시스템 분류
flowchart TB
subgraph Meta["메타 빌드 시스템 (설정 파일 → 네이티브 빌드)"]
CMake[CMake]
Meson[Meson]
Bazel[Bazel]
end
subgraph Native["네이티브 빌드 (직접 실행)"]
Make[Make]
Ninja[Ninja]
MSBuild[MSBuild]
end
subgraph Package["패키지 매니저 (의존성 + 빌드)"]
vcpkg[vcpkg]
Conan[Conan]
end
CMake --> Make
CMake --> Ninja
CMake --> MSBuild
Meson --> Ninja
Meson --> MSBuild
Bazel --> Bazel내부[Bazel 내부 엔진]
vcpkg --> CMake
Conan --> CMake
빌드 파이프라인 흐름
sequenceDiagram
participant Dev as 개발자
participant Meta as 메타 빌드 (CMake/Meson)
participant Native as 네이티브 빌드 (Ninja/Make)
participant PM as 패키지 매니저 (선택)
Dev->>PM: 의존성 설치 (vcpkg/Conan)
PM->>Dev: toolchain 경로
Dev->>Meta: configure (설정 생성)
Meta->>Native: Makefile/Ninja 등 생성
Dev->>Native: build (실제 컴파일)
Native->>Dev: 실행 파일·라이브러리
용어 정리
| 용어 | 설명 |
|---|---|
| 메타 빌드 | CMake, Meson처럼 설정 파일을 읽고 네이티브 빌드 파일을 생성하는 도구 |
| 네이티브 빌드 | Make, Ninja, MSBuild처럼 실제 컴파일·링크를 수행하는 도구 |
| 패키지 매니저 | vcpkg, Conan처럼 외부 라이브러리 다운로드·빌드·경로 설정을 자동화 |
| 툴체인 | 컴파일러·링커·플래그 조합 (예: GCC 12, Clang 15, MSVC 2022) |
3. 완전한 빌드 시스템 비교표
핵심 비교표
| 항목 | CMake | Meson | Bazel | Makefile |
|---|---|---|---|---|
| 역할 | 메타 빌드 | 메타 빌드 | 통합 빌드 | 네이티브 빌드 |
| 시장 점유율 | ~83% (2024) | ~5% | ~3% | 레거시 다수 |
| 설정 언어 | CMake (자체 DSL) | Meson (Python 스타일) | Starlark (Python 스타일) | Makefile 문법 |
| 학습 곡선 | 중간~높음 | 낮음~중간 | 높음 | 중간 |
| 크로스 플랫폼 | 우수 | 우수 | 우수 | 수동 |
| configure 속도 | 보통 | 빠름 | 빠름 | N/A |
| 빌드 속도 | Ninja 사용 시 빠름 | Ninja 기본 | 빠름 | Make 기본 |
| IDE 지원 | 최고 | 보통 | 보통 | 제한적 |
| 패키지 연동 | vcpkg, Conan, FetchContent | wrap, Conan | rules_cc, Conan | 수동 |
| 대규모 프로젝트 | 가능 | 가능 | 최적화됨 | 어려움 |
| 생태계 | 최대 | 성장 중 | Google 생태계 | 레거시 |
패키지 매니저 비교
| 항목 | vcpkg | Conan |
|---|---|---|
| 역할 | C++ 패키지 매니저 | C++ 패키지 매니저 |
| 빌드 시스템 | CMake 기반 | CMake 등 생성 |
| 패키지 수 | 2000+ | 1500+ |
| 설치 | Git 클론 + bootstrap | pip install conan |
| 의존성 파일 | vcpkg.json | conanfile.txt / .py |
| 버전 고정 | builtin-baseline, vcpkg.lock | 명시적 버전, conan.lock |
| CMake 연동 | toolchain 자동 | conan install → toolchain |
| Microsoft 생태계 | 강함 | 보통 |
| 사내 패키지 | 오버레이 포트 | 사설 레포 (Artifactory) |
사용 사례별 추천
| 사용 사례 | 1순위 | 2순위 | 비고 |
|---|---|---|---|
| 신규 C++ 프로젝트 | CMake + vcpkg | Meson + wrap | 생태계·IDE 지원 |
| Windows 중심 | CMake + vcpkg | Visual Studio | MSVC 통합 |
| 대규모 모노레포 | Bazel | CMake | Google 스타일 |
| 레거시 Makefile | CMake 마이그레이션 | 유지 | 점진적 전환 |
| 임베디드 | CMake + Conan | CMake + vcpkg | 크로스 컴파일 |
| 오픈소스 라이브러리 | CMake | Meson | 사용자 편의 |
4. CMake 상세
CMake 개요
CMake는 메타 빌드 시스템으로, CMakeLists.txt를 읽고 Makefile, Ninja, Visual Studio 프로젝트 등을 생성합니다. 2024년 기준 C++ 빌드 시장의 83% 점유율입니다.
장점
- 생태계: 대부분의 C++ 라이브러리가 CMake 지원
- IDE: CLion, Visual Studio, VS Code 모두 CMake 우선 지원
- 패키지 매니저: vcpkg, Conan과 통합 용이
- 크로스 플랫폼: Windows, Linux, macOS, 임베디드
단점
- 문법: 복잡하고 역사적 레거시가 많음
- configure 속도: 대규모 프로젝트에서 느릴 수 있음
- 디버깅: 에러 메시지가 직관적이지 않음
기본 예제
cmake_minimum_required(VERSION 3.20)
project(MyApp VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(myapp
src/main.cpp
src/utils.cpp
)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
)
find_package 예제
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
Boost::system
)
vcpkg 툴체인 연동
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build
Ninja 사용 (빌드 속도 향상)
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
5. Meson 상세
Meson 개요
Meson은 “빠르고 사용하기 쉬운” 빌드 시스템을 목표로 합니다. Python 스타일 DSL을 사용하며, Ninja를 기본 백엔드로 사용합니다.
장점
- configure 속도: CMake보다 빠름
- 문법: 간결하고 읽기 쉬움
- 의존성: 자동으로 올바른 순서로 빌드
단점
- 생태계: CMake보다 작음
- wrap: 패키지 수가 vcpkg·Conan보다 적음
- Windows: VS Code에서 컴파일러 선택이 제한적
기본 예제
project('myapp', 'cpp',
version : '1.0.0',
default_options : ['cpp_std=c++17']
)
fmt_dep = dependency('fmt')
spdlog_dep = dependency('spdlog')
executable('myapp',
'src/main.cpp',
dependencies : [fmt_dep, spdlog_dep]
)
wrap 프로젝트 (의존성)
# subprojects/fmt.wrap
[wrap-file]
directory = fmt-9.1.0
source_url = https://github.com/fmtlib/fmt/archive/9.1.0.zip
source_filename = fmt-9.1.0.zip
source_hash = ...
크로스 컴파일
# cross-arm.txt
[binaries]
c = 'arm-linux-gnueabihf-gcc'
cpp = 'arm-linux-gnueabihf-g++'
meson setup build --cross-file cross-arm.txt
meson compile -C build
6. Bazel 상세
Bazel 개요
Bazel은 Google이 만든 통합 빌드 시스템으로, 대규모 모노레포·재현 가능한 빌드에 최적화되어 있습니다. Starlark(Python 스타일) 언어를 사용합니다.
장점
- 재현성: Hermetic 빌드, 캐시
- 대규모: 증분 빌드, 원격 캐시
- 멀티 언어: C++, Java, Go, Python 등
단점
- 학습 곡선: 가파름
- 생태계: C++보다 Java·Go에서 더 활발
- 설정: WORKSPACE, BUILD 파일 구조가 독자적
기본 예제
# BUILD
cc_binary(
name = "myapp",
srcs = [src/main.cpp],
deps = [
"@fmt//:fmt",
"@spdlog//:spdlog",
],
)
WORKSPACE
# WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "fmt",
urls = [https://github.com/fmtlib/fmt/archive/9.1.0.zip],
strip_prefix = "fmt-9.1.0",
)
# third_party/fmt/BUILD
cc_library(
name = "fmt",
srcs = glob([src/*.cc]),
hdrs = glob([include/**/*.h]),
includes = [include],
visibility = [//visibility:public],
)
7. Makefile 상세
Makefile 개요
Makefile은 가장 오래된 빌드 도구로, 여전히 많은 레거시 프로젝트에서 사용됩니다. make 명령으로 실행합니다.
장점
- 단순성: 작은 프로젝트에서는 간단
- 범용성: 모든 Unix에 기본 설치
- 유연성: 셸 스크립트와 자유롭게 혼합
단점
- 크로스 플랫폼: Windows에서 별도 설정 필요
- 의존성: 복잡한 규칙 작성이 어려움
- IDE: CLion 등은 CMake를 우선 지원
기본 예제
CXX = g++
CXXFLAGS = -std=c++17 -Wall -O2
LDFLAGS = -lfmt -lspdlog
SRCS = src/main.cpp src/utils.cpp
OBJS = $(SRCS:.cpp=.o)
TARGET = myapp
$(TARGET): $(OBJS)
$(CXX) $(OBJS) -o $(TARGET) $(LDFLAGS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
.PHONY: clean
의존성 자동 생성
-include $(SRCS:.cpp=.d)
%.d: %.cpp
@$(CXX) -MM $(CXXFLAGS) $< > $@.tmp && mv $@.tmp $@
8. 패키지 매니저: vcpkg·Conan
vcpkg와 Conan의 역할
빌드 시스템(CMake·Meson)과 패키지 매니저(vcpkg·Conan)는 다른 역할입니다.
- 빌드 시스템: 소스 → 컴파일 → 링크 → 실행 파일
- 패키지 매니저: 외부 라이브러리 다운로드·빌드·경로 설정
vcpkg 기본 사용
// vcpkg.json
{
"name": "myapp",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json"
]
}
# CMake에서 vcpkg 툴체인 지정
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
Conan 기본 사용
# conanfile.txt
[requires]
fmt/9.1.0
spdlog/1.11.0
[generators]
CMakeDeps
CMakeToolchain
conan install . --output-folder=build --build=missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
vcpkg vs Conan 선택
| 상황 | vcpkg | Conan |
|---|---|---|
| Windows·Visual Studio | ✅ | 보통 |
| 사내 라이브러리 배포 | 오버레이 | ✅ Artifactory |
| 크로스 컴파일 | triplet | ✅ 프로필 |
| 빠른 시작 | ✅ | 보통 |
| 버전 세밀 제어 | baseline | ✅ |
9. 자주 발생하는 에러와 해결법
CMake 관련
에러 1: “Could not find a package configuration file”
CMake Error: Could not find a package configuration file provided by "fmt"
원인: CMAKE_TOOLCHAIN_FILE 미지정, vcpkg/Conan 미설치, 패키지 미빌드.
해결법:
# vcpkg 사용 시
cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
# Conan 사용 시: conan install 먼저 실행
conan install . --output-folder=build --build=missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
에러 2: “undefined reference to” / LNK2019
undefined reference to `fmt::v9::format(...)'
원인: target_link_libraries에 라이브러리 누락, Debug/Release 혼용.
해결법:
# ✅ 모든 의존성 링크
target_link_libraries(myapp PRIVATE fmt::fmt spdlog::spdlog)
# Debug/Release 일치 확인
# vcpkg triplet 또는 Conan 프로필에서 build_type 통일
에러 3: “No such file or directory” (헤더)
fatal error: mylib.h: No such file or directory
원인: target_include_directories 누락, PUBLIC/PRIVATE 전파 오류.
해결법:
# 라이브러리에서 include를 PUBLIC으로
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
# 또는 target_link_libraries로 의존성 링크 시 자동 전파
target_link_libraries(myapp PRIVATE mylib)
vcpkg 관련
에러 4: “Version conflict” / “builtin-baseline”
Error: Version conflict: fmt 9.1.0 vs 10.1.0
원인: 의존성 버전 충돌, baseline이 최신으로 업데이트됨.
해결법:
// vcpkg.json - 버전 명시
{
"dependencies": [
"fmt",
{"name": "spdlog", "version>=": "1.11.0"}
],
"builtin-baseline": "고정된 커밋 해시"
}
# vcpkg.lock을 Git에 커밋해 재현성 확보
git add vcpkg.lock
Conan 관련
에러 5: “Version conflict”
ERROR: Version conflict: fmt/9.1.0 vs fmt/10.1.0
원인: 의존성 트리에서 버전 충돌.
해결법:
# conanfile.py - override
def requirements(self):
self.requires("fmt/9.1.0", override=True)
# conan.lock 사용
conan lock create . --lockfile=conan.lock
conan install . --lockfile=conan.lock
Meson 관련
에러 6: “dependency not found”
meson.build:5:0: ERROR: Dependency "fmt" not found
원인: wrap 미설치, 시스템 패키지 없음.
해결법:
# wrap 사용
meson wrap install fmt
# 또는 시스템 패키지
# Ubuntu: apt install libfmt-dev
# macOS: brew install fmt
Makefile 관련
에러 7: “missing separator”
Makefile:10: *** missing separator. Stop.
원인: Makefile에서 탭 대신 공백 사용.
해결법:
# ❌ 공백 (잘못됨)
target:
g++ main.cpp -o target
# ✅ 탭 (올바름)
target:
g++ main.cpp -o target
전체 에러 요약표
| 에러 | 빌드 시스템 | 원인 | 해결 |
|---|---|---|---|
| Could not find package | CMake | toolchain 미지정 | CMAKE_TOOLCHAIN_FILE |
| undefined reference | 공통 | 링크 누락 | target_link_libraries |
| No such file (헤더) | CMake | include 경로 | target_include_directories |
| Version conflict | vcpkg/Conan | 버전 충돌 | lock, override |
| missing separator | Makefile | 탭/공백 | 탭 사용 |
| dependency not found | Meson | wrap 미설치 | meson wrap install |
10. 마이그레이션 가이드
Makefile → CMake
flowchart LR
A[Makefile 분석] --> B[CMakeLists.txt 작성]
B --> C[병렬 실행 검증]
C --> D[CI 업데이트]
단계별 가이드:
- 소스·의존성 파악:
SRCS,LDFLAGS,CXXFLAGS추출 - 최소 CMakeLists.txt 작성:
cmake_minimum_required(VERSION 3.20)
project(MyApp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(myapp
src/main.cpp
src/utils.cpp
)
target_link_libraries(myapp PRIVATE
fmt::fmt
pthread
)
- 동일 빌드 결과 확인:
diff로 기존 빌드와 비교 - CI 스크립트 수정:
make→cmake --build build
CMake → Meson
적합한 경우: 프로젝트 크기가 중간 이하, CMake 복잡도가 높은 경우.
단계:
meson.build작성 (동일 구조)
project('myapp', 'cpp', default_options : ['cpp_std=c++17'])
executable('myapp', 'src/main.cpp', 'src/utils.cpp', dependencies : [dependency('fmt'), dependency('spdlog')])
- wrap으로 의존성 처리
- CI에서 Meson 빌드 추가
- 병렬로 CMake·Meson 유지 후 검증 후 CMake 제거
vcpkg → Conan (또는 역)
주의: 한 프로젝트 내 혼용은 권장하지 않음. 전체 마이그레이션 필요.
vcpkg → Conan:
conanfile.txt에vcpkg.json의존성 대응 작성conan install후 빌드 검증- CI에서 vcpkg 제거, Conan 추가
vcpkg.json삭제
Conan → vcpkg:
vcpkg.json에conanfile.txt의존성 대응 작성CMAKE_TOOLCHAIN_FILE을 vcpkg로 변경conan install제거, CI 업데이트
11. 프로덕션 패턴
패턴 1: 재현 가능한 빌드
목표: 동일 소스·설정으로 어디서나 동일한 결과
CMake + vcpkg:
// vcpkg.json - 버전 고정
{
"builtin-baseline": "abc123def456...",
"dependencies": ["fmt", "spdlog"]
}
# vcpkg.lock 커밋
git add vcpkg.lock
CMake + Conan:
conan lock create .
conan install . --lockfile=conan.lock
패턴 2: CI 캐시
vcpkg:
# GitHub Actions
- uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/vcpkg/buildtrees
${{ github.workspace }}/vcpkg/packages
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json', 'vcpkg.lock') }}
Conan:
- uses: actions/cache@v4
with:
path: ~/.conan2
key: conan-${{ runner.os }}-${{ hashFiles('conanfile.*', 'conan.lock') }}
패턴 3: CMake Presets
// CMakePresets.json
{
"version": 3,
"configurePresets": [
{
"name": "vcpkg-default",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}
]
}
cmake --preset vcpkg-default
cmake --build --preset vcpkg-default
패턴 4: Docker 빌드 환경
# Dockerfile.build
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y cmake g++ ninja-build git
RUN git clone https://github.com/microsoft/vcpkg.git /vcpkg && \
/vcpkg/bootstrap-vcpkg.sh
WORKDIR /src
COPY . .
RUN cmake -B build -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake && \
cmake --build build
패턴 5: 프로젝트 구조 표준
my-project/
├── CMakeLists.txt
├── vcpkg.json
├── vcpkg.lock
├── CMakePresets.json
├── src/
│ └── main.cpp
├── include/
├── tests/
└── .github/
└── workflows/
└── build.yml
패턴 6: 빌드 타입 분리
# Debug/Release 분리
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(myapp PRIVATE DEBUG_MODE)
endif()
# vcpkg triplet으로 정적/동적 선택
# x64-windows-static, x64-linux 등
12. 선택 가이드와 의사결정
의사결정 플로우
flowchart TD
A[신규 프로젝트?] -->|Yes| B{팀 규모?}
A -->|No| C{레거시?}
B -->|소~중| D[CMake + vcpkg]
B -->|대규모| E[Bazel 검토]
C -->|Makefile| F[CMake 마이그레이션]
C -->|CMake| G[유지 또는 Meson 검토]
D --> H[생태계·IDE 지원]
E --> I[대규모·재현성]
질문별 체크리스트
| 질문 | CMake | Meson | Bazel |
|---|---|---|---|
| 팀이 CMake를 잘 아나요? | ✅ | - | - |
| 빌드 속도가 최우선인가요? | Ninja 사용 | ✅ | ✅ |
| Google 스타일 팀인가요? | - | - | ✅ |
| 레거시 Makefile이 있나요? | ✅ 마이그레이션 | - | - |
| Windows 중심인가요? | ✅ | 보통 | 보통 |
| 사내 라이브러리 배포? | Conan | Conan | rules_cc |
최종 추천
| 상황 | 추천 |
|---|---|
| 대부분의 C++ 프로젝트 | CMake + vcpkg |
| 빌드 속도·문법 간결 | Meson |
| 대규모 모노레포 | Bazel |
| 레거시 | Makefile → CMake |
13. 구현 체크리스트
빌드 시스템 선택
- 팀 규모·기술 스택 파악
- 크로스 플랫폼 필요 여부
- 패키지 매니저 (vcpkg vs Conan) 결정
- IDE 지원 확인
CMake 프로젝트
-
CMAKE_CXX_STANDARD설정 -
target_link_libraries에 모든 의존성 -
target_include_directoriesPUBLIC/PRIVATE 구분 - Ninja 사용 (
-G Ninja)
vcpkg
-
vcpkg.json작성 -
builtin-baseline또는vcpkg.lock고정 -
CMAKE_TOOLCHAIN_FILE지정 - CI 캐시 설정
Conan
-
conanfile.txt또는conanfile.py작성 -
conan.lock생성 및 커밋 -
conan install후 빌드 - CI 캐시 설정
재현 가능한 빌드
- lock 파일 (vcpkg.lock, conan.lock) Git 커밋
- baseline/버전 명시
- Docker 빌드 환경 (선택)
CI/CD
- 빌드 캐시 설정
- CMake Presets 또는 동일 옵션 사용
- 멀티 플랫폼 빌드 (필요 시)
정리
| 작업 | CMake | Meson | Bazel |
|---|---|---|---|
| 설정 파일 | CMakeLists.txt | meson.build | BUILD, WORKSPACE |
| 의존성 | find_package, vcpkg, Conan | wrap, dependency | rules_cc, http_archive |
| 빌드 | cmake —build | meson compile | bazel build |
| 생태계 | 최대 | 성장 중 |
핵심 원칙:
- 팀 표준 하나로 통일: 빌드 시스템·패키지 매니저
- 재현 가능한 빌드: lock 파일, 버전 고정
- CI 캐시 활용: 빌드 시간 단축
- 점진적 마이그레이션: 레거시는 단계적으로
이 글에서 다루는 키워드: C++ 빌드 시스템, CMake, Meson, Bazel, vcpkg, Conan, Makefile, 빌드 비교, 마이그레이션
관련 글
- CMake 입문 | 수십 개 파일 컴파일할 때 필요한 빌드 자동화 (CMakeLists.txt 기초)
- C++ CMake 완벽 가이드 | 크로스 플랫폼 빌드·최신 CMake 3.28+ 기능·프리셋·모듈
- C++ CMake Presets 완벽 가이드 | 멀티 플랫폼·vcpkg·Conan·CI/CD 통합