C++ 패키지 매니저 | vcpkg·Conan으로 "라이브러리 설치 지옥" 탈출하기

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 listboost-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에서는 의존성 캐시 레이어 분리.


목차

  1. vcpkg 시작하기
  2. vcpkg 고급 사용법
  3. vcpkg 완전 예제
  4. Conan 시작하기
  5. Conan 고급 사용법
  6. Conan 완전 예제
  7. 비교와 선택
  8. 자주 발생하는 에러와 해결법
  9. 베스트 프랙티스
  10. 프로덕션 패턴

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 배열에 패키지 이름을 문자열로 넣거나, namefeatures(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]CMakeDepsCMakeToolchain을 넣어 두면, 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
특징vcpkgConan
설치Git 클론 + bootstrappip 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 cacheConan 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: 의존성 업데이트 워크플로우

  1. builtin-baseline (vcpkg) 또는 버전(Conan) 업데이트
  2. 로컬에서 빌드 테스트
  3. CI 통과 확인
  4. 커밋

실전 예제 요약

프로젝트 구조

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, 의존성 관리, 라이브러리 설치 등으로 검색하시면 이 글이 도움이 됩니다.

정리

작업vcpkgConan
설치vcpkg install fmtconan install .
의존성 파일vcpkg.jsonconanfile.txt/py
CMake 통합toolchain 자동conan install → toolchain
버전 고정Baseline + version>=명시적 버전

핵심 원칙:

  1. 패키지 매니저 사용 필수
  2. 의존성 파일로 명시
  3. 버전 고정으로 재현성
  4. CI/CD 통합
  5. 프로젝트에 맞는 도구 선택

자주 묻는 질문 (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]