C++ 패키지 매니저 | vcpkg·Conan으로 "라이브러리 설치 지옥" 탈출하기
이 글의 핵심
C++ 패키지 매니저에 대한 실전 가이드입니다. vcpkg·Conan으로 등을 예제와 함께 상세히 설명합니다.
들어가며: 라이브러리 설치가 너무 어렵다
”Boost 설치하는데 하루가 걸렸어요”
프로젝트에 Boost 라이브러리를 추가하려고 했습니다. 하지만:
- 소스 다운로드
- 빌드 스크립트 실행
- 헤더 경로 설정
- 라이브러리 경로 설정
- 플랫폼별로 다른 설정
하루가 걸렸습니다.
vcpkg·Conan 같은 패키지 매니저(라이브러리 다운로드·빌드·경로 설정을 자동화하는 도구)는 “의존성(다른 라이브러리·도구에 대한 필요)—이름과 버전”만 적으면 다운로드·빌드·경로 설정을 자동으로 해 줍니다. 팀 전체가 같은 버전의 라이브러리를 쓰게 할 수 있어서, “내 PC에서는 되는데 CI에서 안 된다” 같은 문제를 줄이는 데 도움이 됩니다.
flowchart LR
subgraph manual["수동 설치"]
M1[소스 다운로드] --> M2[빌드]
M2 --> M3[경로 설정]
M3 --> M4[플랫폼별 설정]
end
subgraph pm["패키지 매니저"]
P1[vcpkg.json / conanfile] --> P2[자동 설치]
P2 --> P3[CMake 연동]
end
vcpkg로 해결: vcpkg는 vcpkg install boost 한 줄로 Boost를 다운로드·빌드·설치하고, **vcpkg integrate install을 해 두면 CMake가 vcpkg 설치 경로를 자동으로 찾습니다. 그래서 find_package(Boost REQUIRED)만 해도 include·라이브러리 경로가 설정되고, target_link_libraries(myapp PRIVATE Boost::boost)**로 링크할 수 있습니다. 수동으로 경로 잡지 않아도 되어 “Boost 설치하는데 하루 걸리던” 상황을 크게 줄일 수 있습니다.
# 복사해 붙여넣은 뒤: vcpkg가 설치된 디렉터리에서 실행. 설치 후 CMake에서 -DCMAKE_TOOLCHAIN_FILE=[vcpkg]/scripts/buildsystems/vcpkg.cmake 로 사용
vcpkg install boost-asio
# CMake에서 자동 인식 (toolchain 지정 시)
# find_package(Boost REQUIRED)
# target_link_libraries(myapp PRIVATE Boost::boost)
실행 결과: vcpkg가 Boost.Asio를 다운로드·빌드하고, vcpkg list에 boost-asio가 보이면 설치 완료입니다.
실행 가능 예제 (vcpkg 설치 후 빌드할 수 있는 최소 C++ 프로그램):
// 복사해 붙여넣은 뒤: vcpkg로 설치한 툴체인으로 CMake 빌드하거나, 의존성 없이 g++ -std=c++17 -o demo main.cpp && ./demo
#include <iostream>
int main() {
std::cout << "vcpkg로 환경을 맞춘 뒤 이 프로젝트를 빌드하면 됩니다.\n";
return 0;
}
이 글을 읽으면:
- vcpkg로 라이브러리를 쉽게 설치할 수 있습니다.
- Conan으로 의존성을 관리할 수 있습니다.
- 프로젝트 의존성을 명시적으로 관리할 수 있습니다.
- 실전에서 재현 가능한 빌드를 만들 수 있습니다.
문제 시나리오: 실무에서 겪는 패키지 관리 고통
시나리오 1: “내 PC에서는 되는데 CI에서 안 돼요”
증상: 로컬에서는 빌드가 되는데, GitHub Actions나 Jenkins에서 find_package(fmt) failed 에러가 납니다.
원인: 로컬에 수동으로 설치한 라이브러리가 CI 환경에는 없음. 시스템 패키지(apt, brew)로 설치하면 버전이 플랫폼마다 달라짐.
해결: vcpkg.json 또는 conanfile로 의존성을 선언하고, CI에서 toolchain/profile을 지정해 동일한 환경으로 빌드.
시나리오 2: “라이브러리 버전이 바뀌어서 빌드가 깨졌어요”
증상: 어제까지 잘 되던 프로젝트가 오늘 conan install 후 빌드 에러가 납니다.
원인: 의존성에 버전 범위를 넣지 않아 최신 버전이 설치됨. API 변경으로 호환성이 깨짐.
해결: vcpkg는 builtin-baseline으로, Conan은 fmt/9.1.0처럼 명시적 버전으로 고정.
시나리오 3: “헤더는 찾는데 링크 에러가 나요”
증상: undefined reference to 'fmt::v9::format(...)' 같은 링크 에러.
원인: find_package는 찾았지만 target_link_libraries에 누락했거나, 동적/정적 라이브러리 혼용(예: Release로 빌드한 fmt를 Debug로 링크).
해결: target_link_libraries(myapp PRIVATE fmt::fmt) 명시, 트리플렛/프로파일에서 build_type 일치 확인.
시나리오 4: “의존성 트리가 꼬였어요”
증상: A는 Boost 1.70, B는 1.80을 요구하는데 둘 다 링크해야 하는 상황.
원인: 전역 설치된 라이브러리나 여러 패키지 매니저 혼용.
해결: Manifest 모드(vcpkg.json) 또는 conanfile로 프로젝트별 격리. 한 프로젝트 내에서는 하나의 버전만 사용.
시나리오 5: “빌드가 너무 오래 걸려요”
증상: vcpkg install 또는 conan install이 30분 이상 걸림.
원인: 바이너리 캐시 없이 매번 소스에서 빌드. CI에서 매번 클린 빌드.
해결: vcpkg binary cache, Conan remote 캐시 활용. CI에서는 의존성 캐시 레이어 분리.
목차
- vcpkg 시작하기
- vcpkg 고급 사용법
- vcpkg 완전 예제
- Conan 시작하기
- Conan 고급 사용법
- Conan 완전 예제
- 비교와 선택
- 자주 발생하는 에러와 해결법
- 베스트 프랙티스
- 프로덕션 패턴
1. vcpkg 시작하기
설치
vcpkg는 Git 저장소를 클론한 뒤 bootstrap 스크립트를 실행해 vcpkg 실행 파일을 만듭니다. Linux/macOS는 ./bootstrap-vcpkg.sh, Windows는 **.\bootstrap-vcpkg.bat**을 쓰면 됩니다. 이후 vcpkg 명령은 이 디렉토리에서 실행하거나, PATH에 넣어 두고 사용합니다. 한 번 설치해 두면 여러 프로젝트에서 같은 vcpkg 인스턴스를 쓸 수 있습니다.
# 복사해 붙여넣은 뒤: 프로젝트 밖 디렉터리에서 실행. 완료 후 vcpkg.exe(Windows) 또는 vcpkg(Linux/Mac) 실행 파일이 생성됨
# Linux/Mac
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
# Windows (PowerShell 또는 cmd)
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
실행 결과: vcpkg(또는 vcpkg.exe) 실행 파일이 생성되고, ./vcpkg version으로 확인할 수 있습니다.
기본 사용법
**vcpkg search json으로 이름에 “json”이 들어간 패키지를 검색하고, vcpkg install nlohmann-json으로 해당 패키지를 설치합니다. 설치된 목록은 vcpkg list로 확인하고, vcpkg remove nlohmann-json**으로 제거할 수 있습니다. 패키지 이름은 vcpkg 포트 이름이라 라이브러리 공식 이름과 다를 수 있으므로(예: nlohmann-json), search로 정확한 이름을 확인하는 것이 좋습니다.
# 라이브러리 검색
vcpkg search json
# 라이브러리 설치
vcpkg install nlohmann-json
# 설치된 라이브러리 확인
vcpkg list
# 라이브러리 제거
vcpkg remove nlohmann-json
CMake 통합
**vcpkg integrate install**을 실행하면 vcpkg가 시스템에 통합 스크립트를 등록합니다. CMake로 프로젝트를 configure할 때 **-DCMAKE_TOOLCHAIN_FILE=[vcpkg 루트]/scripts/buildsystems/vcpkg.cmake**를 주면, find_package가 vcpkg로 설치한 패키지를 찾고, target_link_libraries만 해도 include·링크 경로가 자동으로 붙습니다. 그래서 CMakeLists.txt는 “find_package + target_link_libraries”만 쓰면 되고, 경로를 수동으로 지정할 필요가 없습니다.
# CMake 통합 설정
vcpkg integrate install
# CMakeLists.txt에서 자동 인식
# find_package(nlohmann_json REQUIRED)
# target_link_libraries(myapp PRIVATE nlohmann_json::nlohmann_json)
2. vcpkg 고급 사용법
vcpkg.json (Manifest Mode)
Manifest 모드에서는 프로젝트 루트에 vcpkg.json을 두고 의존성을 선언합니다. dependencies 배열에 패키지 이름을 문자열로 넣거나, name과 features(Boost의 system, filesystem 등)를 객체로 지정할 수 있습니다. 이렇게 하면 **cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=...**로 빌드할 때 vcpkg가 vcpkg.json을 읽고 필요한 패키지를 자동으로 설치합니다. 팀원이나 CI가 같은 파일만 있으면 동일한 의존성으로 빌드할 수 있어 재현성이 좋아집니다.
{
"name": "myproject",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
{
"name": "boost",
"features": ["system", "filesystem"]
}
]
}
사용:
# vcpkg.json이 있는 디렉토리에서
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=[vcpkg root]/scripts/buildsystems/vcpkg.cmake
cmake --build build
트리플렛 (플랫폼 지정)
트리플렛은 vcpkg가 “어떤 플랫폼·아키텍처·링크 방식”으로 빌드할지 구분하는 이름입니다. x64-windows는 Windows 64비트, x64-linux는 Linux 64비트, x64-osx는 macOS입니다. x64-windows-static은 정적 링크로 빌드해, 실행 파일 하나에 라이브러리를 포함하고 싶을 때 씁니다. Manifest 모드에서도 트리플렛을 지정할 수 있어, CI에서 x64-linux로 빌드하고 로컬에서는 x64-windows로 빌드하는 식으로 나눌 수 있습니다.
# Windows 64비트
vcpkg install fmt:x64-windows
# Linux 64비트
vcpkg install fmt:x64-linux
# macOS
vcpkg install fmt:x64-osx
# 정적 라이브러리
vcpkg install fmt:x64-windows-static
버전 고정
version>=로 최소 버전을 요구하고, builtin-baseline에 vcpkg 저장소의 커밋 날짜(또는 커밋 해시)를 넣으면, 그 시점의 포트 버전을 기준으로 의존성이 잡힙니다. 이렇게 하면 “오늘은 9.1.0인데 내일 9.2.0으로 바뀌어서 빌드가 깨지는” 상황을 막을 수 있습니다. 팀 전체가 같은 baseline을 쓰면 동일한 버전으로 빌드되어 “내 PC에서는 되는데 CI에서 안 된다”를 줄일 수 있습니다.
{
"name": "myproject",
"version": "1.0.0",
"dependencies": [
{
"name": "fmt",
"version>=": "9.1.0"
}
],
"builtin-baseline": "2023-04-15"
}
3. vcpkg 완전 예제
프로젝트 구조
myapp-vcpkg/
├── CMakeLists.txt
├── vcpkg.json
├── src/
│ └── main.cpp
└── tests/
└── test_main.cpp
vcpkg.json (의존성 선언)
{
"name": "myapp-vcpkg",
"version": "1.0.0",
"description": "vcpkg를 사용한 C++ 프로젝트 예제",
"dependencies": [
"fmt",
"spdlog",
{
"name": "nlohmann-json",
"version>=": "3.11.0"
},
{
"name": "boost-asio",
"features": ["ssl"]
}
],
"builtin-baseline": "a1c7f64"
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyAppVcpkg LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
# vcpkg가 toolchain으로 지정되면 find_package가 vcpkg 설치 경로를 자동으로 찾음
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
Boost::system
)
src/main.cpp (실행 가능한 예제)
#include <iostream>
#include <fmt/core.h>
#include <spdlog/spdlog.h>
#include <nlohmann/json.hpp>
#include <boost/asio.hpp>
int main() {
spdlog::info("vcpkg 예제 시작");
// fmt 사용
std::cout << fmt::format("Hello, {}!\n", "vcpkg");
// nlohmann-json 사용
auto j = nlohmann::json::parse(R"({"name": "myapp", "version": 1})");
std::cout << "JSON: " << j.dump() << "\n";
// Boost.Asio 사용 (타이머만)
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));
t.async_wait( { spdlog::info("타이머 완료"); });
io.run();
return 0;
}
빌드 명령
# VCPKG_ROOT을 vcpkg 설치 경로로 설정
export VCPKG_ROOT=/path/to/vcpkg
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
./build/myapp
4. Conan 시작하기
설치
# pip로 설치
pip install conan
# 버전 확인
conan --version
기본 사용법
**conan profile detect --force**는 현재 환경(OS, 컴파일러, 아키텍처)을 감지해 기본 프로파일을 만듭니다. conanfile.txt에는 [requires]에 패키지와 버전을, [generators]에 CMakeDeps와 CMakeToolchain을 넣어 두면, conan install . --build=missing 시 Conan이 의존성을 설치하고 CMake가 쓸 설정 파일(conan_toolchain.cmake 등)을 생성합니다. —build=missing은 로컬/캐시에 없으면 해당 패키지를 빌드한다는 뜻입니다.
# 프로파일 생성
conan profile detect --force
# 라이브러리 검색
conan search fmt -r conancenter
# conanfile.txt 생성 후 의존성 설치
conan install . --build=missing
conanfile.txt 예시
[requires]
fmt/9.1.0
spdlog/1.11.0
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
CMake 통합
**conan install**을 먼저 실행하면 빌드 디렉토리에 conan_toolchain.cmake 등이 생성됩니다. CMake configure 시 **-DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake**를 넘기면, Conan이 만든 경로와 타겟이 적용되어 find_package(fmt) 등이 Conan으로 설치한 패키지를 찾습니다. vcpkg는 툴체인 파일만 주면 자동으로 manifest를 읽는 반면, Conan은 conan install을 먼저 돌려야 하므로 빌드 스크립트나 문서에 순서를 명시해 두는 것이 좋습니다.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject)
set(CMAKE_CXX_STANDARD 17)
# Conan toolchain 로드 (conan install 후 build/conan_toolchain.cmake 생성됨)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/conan_toolchain.cmake" CACHE PATH "" FORCE)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
)
빌드:
# 1. 의존성 설치 (반드시 먼저)
conan install . --build=missing
# 2. CMake 빌드
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
5. Conan 고급 사용법
conanfile.py
conanfile.py는 Python으로 의존성·빌드·패키징을 제어하는 방식입니다. requirements()에서 self.requires()로 런타임 의존성을, build_requirements()에서 self.test_requires()로 테스트용 의존성(GTest 등)을 선언합니다. layout()으로 소스·빌드 디렉토리 구조를 정하고, generate()에서 CMakeToolchain을 생성해 CMake가 Conan 결과를 쓰게 합니다. build()에서 CMake(self).configure().build()를 호출해 실제 빌드를 수행합니다. 복잡한 옵션이나 조건부 의존성이 필요할 때 conanfile.py가 유리합니다.
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class MyProjectConan(ConanFile):
name = "myproject"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
def requirements(self):
self.requires("fmt/9.1.0")
self.requires("spdlog/1.11.0")
self.requires("boost/1.81.0")
def build_requirements(self):
self.test_requires("gtest/1.12.1")
def layout(self):
cmake_layout(self)
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
옵션과 설정
options로 패키지별 선택 사항을 정의할 수 있습니다. shared는 동적/정적 라이브러리 선택, with_tests는 테스트 빌드 여부 같은 식으로 쓰입니다. default_options로 기본값을 두고, requirements() 안에서 if self.options.with_tests:처럼 분기해 test_requires를 조건부로 추가할 수 있습니다. conan install . -o with_tests=False처럼 명령줄에서 옵션을 오버라이드할 수 있어, CI에서는 테스트를 빼고 빌드하는 등 유연한 설정이 가능합니다.
from conan import ConanFile
class MyProjectConan(ConanFile):
options = {
"shared": [True, False],
"with_tests": [True, False]
}
default_options = {
"shared": False,
"with_tests": True
}
def requirements(self):
self.requires("fmt/9.1.0")
if self.options.with_tests:
self.test_requires("gtest/1.12.1")
프로파일 커스터마이징
프로파일 파일에 [settings]로 OS, 아키텍처, 컴파일러, C++ 표준 라이브러리, 빌드 타입 등을 고정할 수 있습니다. ~/.conan2/profiles/ 아래에 gcc11 같은 이름으로 두고, **conan install . --profile=gcc11로 사용합니다. [conf]**에서 CMake 제너레이터를 Ninja로 바꾸는 등 도구 설정도 넣을 수 있어, 팀 표준 환경(예: Ubuntu 22.04 + GCC 11 + Release)을 프로파일 하나로 맞춰 두면 재현 가능한 빌드가 됩니다.
# ~/.conan2/profiles/gcc11
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
build_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
사용:
conan install . --profile=gcc11 --build=missing
6. Conan 완전 예제
프로젝트 구조
myapp-conan/
├── CMakeLists.txt
├── conanfile.txt
├── src/
│ └── main.cpp
└── tests/
└── test_main.cpp
conanfile.txt
[requires]
fmt/9.1.0
spdlog/1.11.0
nlohmann_json/3.11.2
boost/1.81.0
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyAppConan LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
# conan install 후 생성된 toolchain 사용
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
Boost::system
)
src/main.cpp
#include <iostream>
#include <fmt/core.h>
#include <spdlog/spdlog.h>
#include <nlohmann/json.hpp>
#include <boost/asio.hpp>
int main() {
spdlog::info("Conan 예제 시작");
std::cout << fmt::format("Hello, {}!\n", "Conan");
auto j = nlohmann::json::parse(R"({"name": "myapp", "version": 1})");
std::cout << "JSON: " << j.dump() << "\n";
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));
t.async_wait( { spdlog::info("타이머 완료"); });
io.run();
return 0;
}
빌드 스크립트 (build.sh)
#!/bin/bash
set -e
# 1. Conan 의존성 설치
conan install . --output-folder=build --build=missing
# 2. CMake configure & build
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
echo "빌드 완료. 실행: ./build/myapp"
7. 비교와 선택
vcpkg vs Conan 상세 비교
flowchart TB
subgraph vcpkg["vcpkg"]
V1[Git 클론 설치]
V2[Manifest: vcpkg.json]
V3[트리플렛: x64-windows]
V4[CMake 자동 연동]
end
subgraph conan["Conan"]
C1[pip install]
C2[conanfile.txt / .py]
C3[프로파일: compiler, build_type]
C4[conan install 선실행]
end
V2 --> V4
C2 --> C4 --> C4
| 특징 | vcpkg | Conan |
|---|---|---|
| 설치 | Git 클론 + bootstrap | pip install conan |
| 라이브러리 수 | 2000+ (Microsoft 포트) | 1500+ (Conan Center) |
| CMake 통합 | toolchain만 지정하면 자동 | conan install → toolchain |
| 버전 관리 | builtin-baseline, version>= | 명시적 버전 (fmt/9.1.0) |
| 빌드 설정 | 트리플렛 (x64-windows 등) | 프로파일 (compiler, build_type) |
| 학습 곡선 | 쉬움 | 중간 |
| 유연성 | 중간 | 높음 (Python 스크립트) |
| 바이너리 캐시 | vcpkg binary cache | Conan remote 캐시 |
| 크로스 컴파일 | 트리플렛으로 지원 | 프로파일로 지원 |
선택 가이드
vcpkg 추천:
- CMake 프로젝트
- 빠른 시작 원함
- Microsoft 생태계 (Visual Studio, Azure)
- 팀이 C++만 다룸
Conan 추천:
- 복잡한 의존성 관리 (조건부, 옵션)
- 세밀한 빌드 제어
- Python 친숙함
- 자체 패키지 배포 필요
8. 자주 발생하는 에러와 해결법
에러 1: “Could not find a package configuration file”
CMake Error at CMakeLists.txt:10 (find_package):
Could not find a package configuration file provided by "fmt"
원인: vcpkg/Conan toolchain을 CMake에 전달하지 않음. 또는 conan install을 하지 않음.
해결:
# vcpkg
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
# Conan: conan install을 먼저 실행
conan install . --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
에러 2: “undefined reference to” 링크 에러
undefined reference to `fmt::v9::format(...)'
원인: find_package는 성공했지만 target_link_libraries에 누락. 또는 Debug/Release 불일치.
해결:
# ✅ 반드시 target_link_libraries에 추가
target_link_libraries(myapp PRIVATE fmt::fmt)
# vcpkg: 트리플렛 일치 확인 (x64-windows vs x64-windows-static)
# Conan: 프로파일 build_type=Release/Debug 일치
에러 3: “Version conflict” (Conan)
ERROR: Version conflict: fmt/10.0.0, fmt/9.1.0
원인: 여러 패키지가 서로 다른 fmt 버전을 요구.
해결: conanfile에서 동일 버전으로 통일. 또는 override로 강제:
[requires]
fmt/9.1.0
spdlog/1.11.0
[tool_requires]
# override는 conanfile.py에서 self.requires("fmt/9.1.0", override=True)
에러 4: vcpkg “Baseline must be a valid git commit”
Error: builtin-baseline must be a valid git commit
원인: builtin-baseline에 잘못된 날짜 또는 해시.
해결: vcpkg 저장소의 최신 커밋 해시 사용:
cd vcpkg
git log -1 --format=%H
{
"builtin-baseline": "a1c7f64b3" // 실제 해시로 교체
}
에러 5: “Package not found” (Conan)
ERROR: Package 'xyz/1.0' not found
원인: Conan Center에 해당 패키지가 없거나, 이름/버전 오타.
해결:
# 패키지 검색
conan search xyz -r conancenter
# vcpkg 패키지 이름과 다를 수 있음 (예: nlohmann-json vs nlohmann_json)
에러 6: “A suitable version of cmake was not found”
원인: Conan이 요구하는 CMake 버전이 시스템에 없음.
해결:
# conanfile.txt에 tool_requires 추가
[tool_requires]
cmake/3.25.0
9. 베스트 프랙티스
1. 의존성 파일을 버전 관리에 포함
vcpkg.json, conanfile.txt, conanfile.py는 반드시 Git에 커밋합니다. 팀원과 CI가 동일한 의존성으로 빌드할 수 있습니다.
2. 버전 고정
// vcpkg: builtin-baseline + version>=
{
"builtin-baseline": "a1c7f64",
"dependencies": [{ "name": "fmt", "version>=": "9.1.0" }]
}
; Conan: 명시적 버전
[requires]
fmt/9.1.0
3. 최소 의존성 원칙
필요한 컴포넌트만 요구합니다. Boost 전체가 아닌 boost-asio, boost-system 등 필요한 것만.
4. CI에서 캐시 활용
# GitHub Actions 예시 (vcpkg)
- uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}/installed
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}
5. 로컬과 CI 환경 일치
동일한 트리플렛(vcpkg) 또는 프로파일(Conan)을 사용합니다. 로컬이 x64-windows면 CI도 x64-windows.
6. 빌드 스크립트로 순서 고정 (Conan)
# build.sh
conan install . --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
10. 프로덕션 패턴
패턴 1: Monorepo + Manifest 모드
대규모 프로젝트에서 여러 서브프로젝트가 있을 때, 루트에 vcpkg.json 하나로 통합하거나, 각 서브디렉토리에 vcpkg.json을 두고 각자 의존성을 관리합니다.
monorepo/
├── vcpkg.json # 공통 의존성
├── service-a/
│ ├── vcpkg.json # service-a 전용
│ └── CMakeLists.txt
└── service-b/
├── vcpkg.json
└── CMakeLists.txt
패턴 2: Docker로 빌드 환경 고정
# Dockerfile.build
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y cmake g++ git python3-pip
RUN git clone https://github.com/Microsoft/vcpkg.git /vcpkg && \
/vcpkg/bootstrap-vcpkg.sh
ENV VCPKG_ROOT=/vcpkg
WORKDIR /app
COPY . .
RUN cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake && \
cmake --build build
패턴 3: Binary Cache로 CI 속도 향상
vcpkg: --x-use-binary-cache 또는 Azure Artifacts 연동
vcpkg install fmt --x-binarysource=clear;default
Conan: remote 캐시 서버 구축 또는 Artifactory 사용
conan remote add mycache https://my-artifactory.com/conan
conan upload "*" -r mycache --all
패턴 4: 프로파일/트리플렛 팀 공유
프로파일 파일을 저장소에 포함해 팀 전체가 동일한 컴파일러·플래그를 사용합니다.
conan/
├── profiles/
│ ├── linux-gcc11
│ ├── windows-msvc2022
│ └── macos-clang14
conan install . --profile=conan/profiles/linux-gcc11
패턴 5: 의존성 업데이트 워크플로우
- builtin-baseline (vcpkg) 또는 버전(Conan) 업데이트
- 로컬에서 빌드 테스트
- CI 통과 확인
- 커밋
실전 예제 요약
프로젝트 구조
myproject/
├── CMakeLists.txt
├── vcpkg.json # vcpkg 사용 시
├── conanfile.txt # Conan 사용 시
├── src/
│ └── main.cpp
└── tests/
└── test_main.cpp
vcpkg.json
{
"name": "myproject",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
"gtest"
]
}
conanfile.txt
[requires]
fmt/9.1.0
spdlog/1.11.0
nlohmann_json/3.11.2
[test_requires]
gtest/1.12.1
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject)
set(CMAKE_CXX_STANDARD 17)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
)
if(BUILD_TESTS)
find_package(GTest REQUIRED)
enable_testing()
add_executable(myapp_test tests/test_main.cpp)
target_link_libraries(myapp_test PRIVATE GTest::gtest_main)
add_test(NAME myapp_test COMMAND myapp_test)
endif()
구현 체크리스트
- vcpkg 또는 Conan 설치
- vcpkg.json 또는 conanfile.txt 작성
- builtin-baseline(vcpkg) 또는 명시적 버전(Conan) 설정
- CMake에 toolchain 파일 지정
- target_link_libraries에 모든 의존성 추가
- CI에서 동일한 toolchain/profile 사용
- 의존성 캐시 설정 (선택)
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ CMake 고급 | 멀티 타겟·외부 라이브러리 관리 (대규모 프로젝트 빌드)
- CMake 입문 | 수십 개 파일 컴파일할 때 필요한 빌드 자동화 (CMakeLists.txt 기초)
- C++ 개발 환경 구축 | “C++ 어디서 시작하죠?” 컴파일러 설치부터 Hello World까지
이 글에서 다루는 키워드 (관련 검색어)
C++ 패키지 매니저, vcpkg, Conan, 의존성 관리, 라이브러리 설치 등으로 검색하시면 이 글이 도움이 됩니다.
정리
| 작업 | vcpkg | Conan |
|---|---|---|
| 설치 | vcpkg install fmt | conan install . |
| 의존성 파일 | vcpkg.json | conanfile.txt/py |
| CMake 통합 | toolchain 자동 | conan install → toolchain |
| 버전 고정 | Baseline + version>= | 명시적 버전 |
핵심 원칙:
- 패키지 매니저 사용 필수
- 의존성 파일로 명시
- 버전 고정으로 재현성
- CI/CD 통합
- 프로젝트에 맞는 도구 선택
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. vcpkg와 Conan으로 C++ 라이브러리를 쉽게 설치하고, 프로젝트 의존성을 관리하며, 재현 가능한 빌드를 만드는 방법을 다룹니다. 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
한 줄 요약: vcpkg·Conan으로 외부 라이브러리를 선언만 하고 설치·링크를 자동화할 수 있습니다. 다음으로 Google Test(#18-1)를 읽어보면 좋습니다.
이전 글: [C++ 실전 가이드 #17-1] CMake 고급: 대규모 프로젝트 빌드 시스템 구축
다음 글: [C++ 실전 가이드 #18-1] Google Test로 단위 테스트 작성하기
관련 글
- C++ CMake 고급 | 멀티 타겟·외부 라이브러리 관리 (대규모 프로젝트 빌드)
- C++ 반복자 기초 완벽 가이드 | iterator 카테고리·begin/end·역방향 반복자·실전 패턴
- C++ 커스텀 반복자 완벽 가이드 | Forward·Bidirectional
- C++ 패키지 관리 완벽 가이드 | vcpkg·Conan·시스템 패키지·프로덕션 패턴 [#55-6]
- C++ vcpkg 기초 완벽 가이드 | 설치·Manifest·Triplet·버전·커스텀 포트 [#53-3]