C++ 패키지 매니저 vcpkg와 Conan 비교: manifest·트리플렛·프로파일과 CMake 연동
vcpkg와 Conan은 둘 다 C++ 라이브러리를 내려받아 빌드하고 CMake가 찾을 수 있게 연결해 주는 패키지 매니저입니다. vcpkg는 CMake 툴체인 파일 하나로 통합되는 단순함이 장점이고, Conan은 프로파일과 Python 레시피로 빌드 설정을 세밀하게 코드화할 수 있다는 점이 장점입니다. 어느 쪽이든 핵심은 의존성을 vcpkg.json이나 conanfile에 적어 저장소에 커밋해 두는 것입니다. 17-1 CMake 고급을 먼저 읽으면 이어지는 CMake 연동 부분이 수월합니다.
들어가며: 왜 패키지 매니저가 필요한가
Boost 같은 라이브러리를 직접 설치하려면 소스를 받아 빌드 스크립트를 돌리고, 헤더와 라이브러리 경로를 CMake에 알려 주고, 이 과정을 운영체제마다 따로 반복해야 합니다. 더 큰 문제는 재현성입니다. 개발자 PC에 손으로 설치한 라이브러리는 CI 서버에는 없고, apt나 brew 같은 시스템 패키지로 설치하면 배포판마다 버전이 다릅니다. “내 PC에서는 되는데 CI에서 find_package(fmt)가 실패한다”는 상황이 여기서 생깁니다.
패키지 매니저는 의존성의 이름과 버전을 파일에 적어 두면 다운로드·빌드·경로 설정을 자동으로 해 주고, 같은 파일을 쓰는 모든 환경에서 같은 버전을 설치합니다.
flowchart LR
subgraph manual[수동 설치]
M1[소스 다운로드] --> M2[빌드]
M2 --> M3[경로 설정]
M3 --> M4[플랫폼별 설정]
end
subgraph pm[패키지 매니저]
P1[vcpkg.json / conanfile] --> P2[자동 설치]
P2 --> P3[CMake 연동]
end
vcpkg 설치와 CMake 통합
설치
vcpkg는 Git 저장소를 클론한 뒤 bootstrap 스크립트를 실행해 실행 파일을 만듭니다. 한 번 설치해 두면 여러 프로젝트에서 같은 vcpkg를 쓸 수 있습니다.
# Linux/macOS (curl, zip, unzip, tar, pkg-config가 필요)
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 version으로 확인하고, 이후 설명을 위해 VCPKG_ROOT 환경 변수를 이 디렉터리로 지정해 둡니다.
클래식 모드 기본 명령
vcpkg 저장소 디렉터리에서 직접 패키지를 설치하는 방식을 클래식 모드라고 합니다. 패키지 이름은 vcpkg 포트 이름이라 라이브러리의 공식 이름과 다를 수 있으므로(예: nlohmann/json은 nlohmann-json), search로 확인하는 것이 좋습니다.
vcpkg search json # 포트 검색
vcpkg install nlohmann-json
vcpkg list # 설치된 패키지
vcpkg remove nlohmann-json
설치가 끝나면 vcpkg가 CMake에서 쓸 find_package와 target_link_libraries 구문(usage)을 출력해 줍니다. 타깃 이름은 라이브러리마다 다르므로 이 안내를 그대로 쓰는 것이 가장 정확합니다.
CMake 통합
CMake와 연결하는 방법은 configure 단계에서 vcpkg의 툴체인 파일을 지정하는 것 하나입니다. 그러면 find_package가 vcpkg로 설치한 패키지를 찾고, target_link_libraries로 타깃을 링크하면 include 경로와 라이브러리 경로가 함께 붙습니다.
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
vcpkg integrate install이라는 명령도 있는데, 이것은 MSBuild(Visual Studio의 .vcxproj 프로젝트)가 vcpkg를 자동으로 쓰게 하는 기능입니다. CMake 프로젝트에서는 이 명령을 실행해도 툴체인 파일 경로를 출력해 줄 뿐이므로, 위처럼 CMAKE_TOOLCHAIN_FILE을 직접 지정해야 합니다.
vcpkg Manifest 모드, 트리플렛, 버전 고정
vcpkg.json (Manifest 모드)
실무에서는 클래식 모드보다 Manifest 모드를 씁니다. 프로젝트 루트에 vcpkg.json을 두고 의존성을 선언하면, 툴체인 파일을 지정해 CMake configure를 실행할 때 vcpkg가 이 파일을 읽어 필요한 패키지를 빌드 디렉터리 아래(build/vcpkg_installed)에 설치합니다. 팀원이나 CI는 이 파일만 있으면 같은 의존성으로 빌드할 수 있습니다.
{
"name": "myproject",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
"boost-filesystem",
{
"name": "boost-asio",
"features": ["ssl"]
}
]
}
Boost는 vcpkg에서 라이브러리별 포트(boost-filesystem, boost-asio 등)로 나뉘어 있으므로, 전체를 설치하는 boost 대신 필요한 것만 적는 편이 빌드 시간을 크게 줄입니다. features는 포트가 제공하는 선택 기능으로, 위 예에서는 Asio의 SSL 지원을 켭니다.
# vcpkg.json이 있는 디렉터리에서
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
트리플렛 (플랫폼 지정)
트리플렛은 vcpkg가 어떤 아키텍처·운영체제·링크 방식으로 빌드할지를 나타내는 이름입니다. x64-windows는 Windows 64비트 DLL, x64-windows-static은 정적 라이브러리와 정적 CRT, x64-linux는 Linux 64비트(기본이 정적 라이브러리), arm64-osx는 Apple Silicon macOS입니다. 클래식 모드에서는 패키지:트리플렛으로, Manifest 모드에서는 CMake 변수 VCPKG_TARGET_TRIPLET으로 지정합니다.
# 클래식 모드
vcpkg install fmt:x64-windows-static
# Manifest 모드
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-windows-static
x64-windows-static으로 받은 라이브러리는 정적 CRT(/MT)로 빌드되므로, 앱도 같은 CRT 설정이어야 LNK2038 에러가 나지 않습니다.
버전 고정
builtin-baseline에는 vcpkg 저장소의 커밋 SHA(40자리 전체)를 넣습니다. 그러면 모든 의존성의 버전이 그 커밋 시점의 포트 버전으로 고정되므로, vcpkg 저장소를 git pull해도 빌드 결과가 바뀌지 않습니다. 날짜나 짧은 해시는 받아들여지지 않습니다. 특정 패키지에 최소 버전이 필요하면 version>=를 추가합니다.
{
"name": "myproject",
"version": "1.0.0",
"dependencies": [
{
"name": "fmt",
"version>=": "10.1.0"
}
],
"builtin-baseline": "<vcpkg 저장소의 40자리 커밋 SHA>"
}
baseline 값을 직접 찾는 대신, 프로젝트 디렉터리에서 vcpkg x-update-baseline --add-initial-baseline을 실행하면 현재 vcpkg 저장소의 커밋으로 채워 줍니다. 의존성을 올리고 싶을 때는 vcpkg 저장소를 갱신한 뒤 vcpkg x-update-baseline으로 baseline만 바꾸고, 빌드와 테스트를 확인한 다음 커밋하는 흐름이 일반적입니다.
vcpkg 예제 프로젝트: vcpkg.json부터 빌드까지
myapp-vcpkg/
├── CMakeLists.txt
├── vcpkg.json
└── src/
└── main.cpp
vcpkg.json
{
"name": "myapp-vcpkg",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"nlohmann-json",
"boost-asio"
],
"builtin-baseline": "<vcpkg 저장소의 40자리 커밋 SHA>"
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(MyAppVcpkg LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(boost_asio CONFIG REQUIRED) # 최근 vcpkg의 Boost 포트별 CMake 패키지
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE
fmt::fmt
spdlog::spdlog
nlohmann_json::nlohmann_json
Boost::asio
)
Boost의 CMake 패키지 이름과 타깃 이름은 vcpkg와 Boost 버전에 따라 바뀌어 왔습니다(예전에는 find_package(Boost REQUIRED COMPONENTS system) + Boost::system 형태). 설치할 때 vcpkg가 출력하는 usage 안내에 맞추세요.
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 예제 시작");
std::cout << fmt::format("Hello, {}!\n", "vcpkg");
auto j = nlohmann::json::parse(R"({"name": "myapp", "version": 1})");
std::cout << "JSON: " << j.dump() << "\n";
// Boost.Asio: 1초 타이머
boost::asio::io_context io;
boost::asio::steady_timer t(io, std::chrono::seconds(1));
t.async_wait([](const boost::system::error_code& ec) {
if (!ec) spdlog::info("타이머 완료");
});
io.run();
return 0;
}
빌드
export VCPKG_ROOT=/path/to/vcpkg
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
cmake --build build
./build/myapp
첫 configure는 모든 의존성을 소스에서 빌드하므로 오래 걸립니다. vcpkg는 빌드한 패키지를 기본적으로 사용자 디렉터리의 바이너리 캐시(Linux는 ~/.cache/vcpkg/archives, Windows는 %LOCALAPPDATA%\vcpkg\archives)에 저장하므로, 같은 버전·트리플렛·컴파일러 조합이면 두 번째부터는 캐시에서 바로 복원합니다.
Conan 설치와 conanfile.txt
설치
Conan은 Python 패키지로 배포됩니다. 아래 내용은 현재 버전인 Conan 2 기준이며, 인터넷에 남아 있는 Conan 1 예제(conan_basic_setup, --all 등)와는 명령과 생성 파일이 다르므로 주의해야 합니다.
pip install conan
conan --version
기본 사용법
conan profile detect는 현재 환경(OS, 컴파일러, 아키텍처)을 감지해 기본 프로파일을 만듭니다. conanfile.txt의 [requires]에 패키지와 버전을, [generators]에 CMakeDeps와 CMakeToolchain을 적고 conan install을 실행하면, Conan이 의존성을 설치하고 CMake가 쓸 설정 파일(conan_toolchain.cmake, 각 패키지의 xxx-config.cmake, CMakePresets.json)을 생성합니다. --build=missing은 원격 저장소에 맞는 바이너리가 없을 때 소스에서 빌드하라는 뜻입니다.
conan profile detect --force
conan search fmt -r conancenter
conan install . --build=missing
conanfile.txt 예시
[requires]
fmt/10.2.1
spdlog/1.13.0
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
spdlog는 내부적으로 fmt에 의존하므로, 두 패키지를 함께 쓸 때는 spdlog 레시피가 요구하는 fmt 버전과 맞춰야 버전 충돌이 나지 않습니다. 맞는 조합은 ConanCenter의 spdlog 레시피에서 확인할 수 있습니다.
CMake 통합
cmake_layout을 쓰면 생성 파일은 build/Release/generators/(Linux·macOS 단일 구성 기준) 같은 하위 디렉터리에 만들어지고, 함께 생성되는 CMakeUsersPresets.json 덕분에 CMake 프리셋으로 바로 빌드할 수 있습니다(CMake 3.23 이상).
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
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-a. 프리셋 사용 (CMake 3.23+)
cmake --preset conan-release
cmake --build --preset conan-release
# 2-b. 프리셋 없이 직접 지정
cmake -B build/Release -S . \
-DCMAKE_TOOLCHAIN_FILE=build/Release/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release
cmake --build build/Release
툴체인 파일은 첫 project() 호출보다 먼저 읽혀야 효과가 있으므로, CMakeLists.txt 안에서 set(CMAKE_TOOLCHAIN_FILE ...)로 지정하는 방식은 동작하지 않거나 순서에 따라 무시됩니다. 명령줄이나 프리셋으로 넘기는 것이 맞습니다. vcpkg는 configure만 하면 Manifest를 읽어 설치까지 하지만, Conan은 conan install을 먼저 실행해야 하므로 빌드 스크립트나 README에 순서를 적어 두는 것이 좋습니다.
conanfile.py, 옵션, 프로파일
conanfile.py
conanfile.py는 Python으로 의존성·빌드·패키징을 제어하는 방식입니다. requirements()에서 self.requires()로 일반 의존성을, build_requirements()에서 self.test_requires()로 테스트 전용 의존성(GTest 등)을 선언합니다. layout()으로 디렉터리 구조를 정하고, generate()에서 CMake용 파일을 만들며, build()에서 실제 빌드를 수행합니다. 조건부 의존성이나 옵션이 필요할 때 텍스트 파일보다 유리합니다.
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
class MyProjectConan(ConanFile):
name = "myproject"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
def requirements(self):
self.requires("fmt/10.2.1")
self.requires("spdlog/1.13.0")
def build_requirements(self):
self.test_requires("gtest/1.14.0")
def layout(self):
cmake_layout(self)
def generate(self):
CMakeDeps(self).generate()
CMakeToolchain(self).generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
CMakeDeps를 생성하지 않으면 find_package(fmt)가 쓸 config 파일이 만들어지지 않으므로, generate()를 직접 쓸 때는 CMakeToolchain과 함께 생성해야 합니다(또는 클래스에 generators = "CMakeDeps", "CMakeToolchain"을 지정합니다).
옵션
options로 이 레시피의 선택 사항을 정의하고 default_options로 기본값을 둡니다. requirements() 안에서 옵션에 따라 의존성을 다르게 줄 수 있습니다.
from conan import ConanFile
class MyProjectConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
options = {"with_tests": [True, False]}
default_options = {"with_tests": True}
def requirements(self):
self.requires("fmt/10.2.1")
if self.options.with_tests:
self.test_requires("gtest/1.14.0")
명령줄에서 현재 레시피(consumer)의 옵션을 바꿀 때는 &: 접두사를 씁니다. 예를 들어 conan install . -o "&:with_tests=False"로 테스트 의존성을 빼고 설치할 수 있고, 의존 패키지의 옵션은 -o "fmt/*:shared=True"처럼 패턴으로 지정합니다.
프로파일
프로파일 파일의 [settings]로 OS, 아키텍처, 컴파일러와 버전, 표준 라이브러리, C++ 표준, 빌드 타입을 고정할 수 있고, [conf]로 CMake 제너레이터 같은 도구 설정도 넣을 수 있습니다. 팀 표준 환경(예: Ubuntu 22.04 + GCC 11 + Release)을 프로파일 하나로 정의해 두면 누구의 PC에서든 같은 설정으로 의존성이 빌드됩니다.
# conan/profiles/linux-gcc11
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
compiler.cppstd=17
build_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
conan install . --profile=conan/profiles/linux-gcc11 --build=missing
프로파일 파일을 ~/.conan2/profiles/ 대신 저장소 안에 두고 경로로 지정하면, 프로파일 자체도 코드 리뷰와 버전 관리의 대상이 됩니다.
vcpkg와 Conan 중 무엇을 고를까
| 특징 | vcpkg | Conan |
|---|---|---|
| 설치 | Git 클론 + bootstrap | pip install conan |
| 공개 패키지 | vcpkg 저장소의 포트 (수천 개 규모) | ConanCenter 레시피 (수천 개 규모에 조금 못 미침) |
| CMake 통합 | 툴체인 파일만 지정하면 configure 중 자동 설치 | conan install 후 생성된 툴체인·프리셋 사용 |
| 버전 고정 | builtin-baseline + version>=, overrides | 레시피마다 명시적 버전, 버전 범위, lockfile |
| 빌드 설정 | 트리플렛 (x64-windows 등) | 프로파일 (컴파일러, build_type, cppstd 등) |
| 확장 방식 | 오버레이 포트, 사용자 정의 트리플렛 | Python 레시피 |
| 바이너리 재사용 | 로컬·원격 바이너리 캐시 | 원격 저장소(Artifactory 등)에 바이너리 업로드 |
CMake 프로젝트에서 빠르게 시작하고 싶고 설정 파일을 최소로 유지하고 싶다면 vcpkg가 진입 장벽이 낮습니다. Visual Studio가 vcpkg Manifest 모드를 기본 지원하므로 Windows 중심 팀이라면 더욱 그렇습니다. 반대로 같은 라이브러리를 여러 컴파일러·빌드 타입 조합으로 빌드해 사내 저장소에 바이너리로 올려 공유해야 하거나, 옵션에 따라 의존성이 달라지는 복잡한 조건이 있거나, 자체 라이브러리를 패키지로 배포해야 한다면 Conan이 더 유연합니다. 팀에 Python을 다룰 사람이 있는지도 현실적인 기준입니다.
자주 만나는 설정 에러
“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"
툴체인 파일을 CMake에 넘기지 않았거나, Conan의 경우 conan install을 먼저 실행하지 않은 것이 대부분의 원인입니다. 이미 한 번 configure한 빌드 디렉터리라면 CMAKE_TOOLCHAIN_FILE이 캐시에 남지 않은 상태일 수 있으므로, 빌드 디렉터리를 지우고 다시 configure하는 것이 확실합니다.
# vcpkg
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
# Conan: conan install을 먼저 실행
conan install . --build=missing
cmake --preset conan-release
”undefined reference to” 링크 에러
undefined reference to `fmt::v10::vformat(...)'
find_package는 성공했지만 target_link_libraries에 타깃을 빠뜨린 경우가 가장 흔합니다. 헤더만 찾고 라이브러리는 링크하지 않은 상태라 컴파일은 되고 링크에서 실패합니다. 그 밖에 Debug용으로 받은 라이브러리를 Release 빌드에 쓰는 경우(Windows에서는 CRT 불일치로 LNK2038), 다른 버전의 같은 라이브러리가 시스템에도 설치되어 있어 엉뚱한 쪽이 잡히는 경우도 있습니다.
target_link_libraries(myapp PRIVATE fmt::fmt)
Conan 버전 충돌
ERROR: Version conflict: Conflict between fmt/10.2.1 and fmt/9.1.0 in the graph.
두 의존성이 서로 다른 fmt 버전을 요구할 때 나는 에러입니다. 가능하면 버전을 맞춘 조합으로 바꾸고, 그래도 안 되면 최상위 conanfile.py에서 self.requires("fmt/10.2.1", override=True)로 그래프 전체의 fmt 버전을 강제합니다. 이렇게 강제한 버전이 실제로 하위 패키지와 API 호환되는지는 직접 확인해야 합니다.
vcpkg baseline 에러
builtin-baseline에 날짜나 짧은 해시를 넣거나, 로컬 vcpkg 저장소에 없는 커밋을 넣으면 baseline을 찾을 수 없다는 에러가 납니다. vcpkg 저장소가 얕은 클론(--depth 1)이라 해당 커밋이 없는 경우도 같은 증상입니다. vcpkg x-update-baseline으로 현재 저장소의 커밋을 넣거나, 저장소를 전체 히스토리로 다시 받으면 해결됩니다.
Conan: 패키지를 찾을 수 없음
ERROR: Package 'xyz/1.0' not resolved
ConanCenter에 해당 이름·버전의 레시피가 없거나 오타인 경우입니다. 이름 규칙도 vcpkg와 다를 수 있습니다(vcpkg는 nlohmann-json, Conan은 nlohmann_json).
conan search "xyz*" -r conancenter
팀과 CI에서 쓰는 패턴
CI에서 바이너리 캐시 재사용
vcpkg는 빌드한 패키지를 바이너리 캐시에 저장하므로, CI에서는 그 디렉터리를 보존하면 매번 소스에서 다시 빌드하지 않아도 됩니다. GitHub Actions라면 캐시 디렉터리를 환경 변수로 고정하고 actions/cache로 저장합니다.
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/.vcpkg-cache
steps:
- uses: actions/checkout@v4
- run: mkdir -p .vcpkg-cache
- uses: actions/cache@v4
with:
path: .vcpkg-cache
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }}
restore-keys: vcpkg-${{ runner.os }}-
Manifest 모드에서 설치된 패키지는 build/vcpkg_installed에 들어가므로 $VCPKG_ROOT/installed를 캐시해도 효과가 없습니다. 여러 머신이 캐시를 공유해야 한다면 VCPKG_BINARY_SOURCES 환경 변수로 Azure Blob, S3 호환 저장소, NuGet 피드 같은 원격 캐시를 지정할 수 있습니다.
Conan은 빌드한 바이너리를 사내 원격 저장소(Artifactory 등)에 올려 공유합니다.
conan remote add mycompany https://artifactory.example.com/artifactory/api/conan/conan-local
conan upload "*" -r mycompany --confirm
Docker로 빌드 환경 고정
# Dockerfile.build
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
cmake g++ git curl zip unzip tar pkg-config ninja-build
RUN git clone https://github.com/microsoft/vcpkg.git /vcpkg && \
/vcpkg/bootstrap-vcpkg.sh -disableMetrics
ENV VCPKG_ROOT=/vcpkg
WORKDIR /app
COPY . .
RUN cmake -B build -S . -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake && \
cmake --build build
COPY . . 전에 vcpkg.json만 먼저 복사해 의존성 설치 레이어를 분리하면, 소스만 바뀌었을 때 의존성 빌드 레이어를 Docker 캐시로 재사용할 수 있습니다.
모노레포에서의 vcpkg.json
vcpkg는 기본적으로 최상위 CMake 소스 디렉터리(CMAKE_SOURCE_DIR)의 vcpkg.json 하나만 읽습니다. 루트에서 전체를 빌드하는 모노레포라면 서브디렉터리마다 vcpkg.json을 두어도 무시되므로, 루트의 vcpkg.json에 전체 의존성을 모으는 것이 기본입니다. 서비스별로 따로 빌드한다면 각 서비스 디렉터리를 CMake 소스 디렉터리로 지정하거나 VCPKG_MANIFEST_DIR로 읽을 파일을 지정합니다. 서비스마다 다른 기능만 켜고 싶다면 하나의 vcpkg.json에 features를 정의하고 VCPKG_MANIFEST_FEATURES로 고르는 방법도 있습니다.
vcpkg와 Conan을 함께 지원하기
라이브러리를 외부에 배포한다면 사용자가 어느 패키지 매니저를 쓰든 빌드되도록 vcpkg.json과 conanfile.txt를 함께 두기도 합니다. 핵심은 CMakeLists.txt가 특정 패키지 매니저를 모르게 하는 것입니다. find_package와 타깃 이름만 쓰고 경로나 툴체인을 하드코딩하지 않으면, 어떤 툴체인 파일을 넘기느냐에 따라 같은 CMakeLists.txt가 양쪽에서 동작합니다.
cmake_minimum_required(VERSION 3.15)
project(MyProject LANGUAGES CXX)
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)
option(BUILD_TESTS "Build tests" OFF)
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()
이 방식에서는 두 파일의 의존성 버전을 손으로 맞춰야 하므로, 버전을 올릴 때 양쪽을 함께 바꾸는 규칙을 정해 두어야 합니다.