본문으로 건너뛰기 C++ 패키지 매니저 | vcpkg·Conan으로 '라이브러리 설치 지옥' 탈출하기

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

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

💡 초보자를 위한 한 줄: vcpkg는 CMake toolchain과 잘 맞으며, Conan프로필·레시피로 팀 규칙을 코드화하기 좋습니다. 공통으로 vcpkg.json / conanfile에 의존성을 박아 재현 가능한 빌드를 만드는 게 1순위입니다. 17-1 CMake 고급 다음이 읽기 순서에 맞습니다.

들어가며: 라이브러리 설치가 너무 어렵다

”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++ 프로그램):

main 함수의 구현 예제입니다.

// 복사해 연결하여넣은 뒤: 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 시작하기

설치

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가 유리합니다.

# 필요한 모듈 import
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++ 패키지 매니저, 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. 프로젝트에 맞는 도구 선택

초보자를 위한 체크리스트

  • 버전/트리플릿이 CI와 로컬에서 동일하게 고정돼 있는가?
  • conanfile.txt vs conanfile.py 중 팀에 맞는 쪽을 택했는가?
  • vcpkg 사용 시 VCPKG_ROOT·baseline을 문서화했는가?

💡 초보자 팁: 본문 7. 비교와 선택·8. 자주 발생하는 에러·1. vcpkg 시작하기를 함께 보세요.

자주 묻는 질문 (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로 단위 테스트 작성하기


관련 글