Skip to content
C++

Which C++ package manager should I use?

Decision guide for choosing between vcpkg, Conan, Hunter, CPM, and other C++ dependency managers.

Start here

What is your build system?

→ CMake → continue below → Bazel → use Bazel's built-in dependency system (http_archive, rules_pkg) or rules_foreign_cc for CMake deps → Meson → Meson wraps system; or use vcpkg/Conan with Meson integration → No build system yet → pick one first (see the build system decision tree)


CMake projects — main choice

Is this a Windows-first or cross-platform project?

Windows-first or strong GitHub Actions/Azure DevOps integration:

  • vcpkg — Microsoft's package manager, excellent Windows support, integrates with CMake via toolchain file, CI caching built in
    • Install: git clone https://github.com/microsoft/vcpkg && bootstrap
    • Use: cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

Cross-platform, Python-friendly build team:

  • Conan — mature, enterprise-friendly, configurable binary compatibility (settings/profiles), Python-based
    • More flexible than vcpkg for handling ABI incompatibilities
    • Better for teams that need to mix compiler/stdlib/arch variants

Do you want zero-install, header-only or CMake FetchContent?

Minimal setup, FetchContent-based, no separate install step:

  • CPM.cmake — single CPM.cmake include, wraps FetchContent with version pinning and caching
    • Great for open-source projects that want self-contained builds
    • No binary caching — always builds from source

Header-only libs via git submodules:

  • Just git submodule add and add_subdirectory — no package manager needed for small projects

Do you need pre-built binaries?

Yes — large deps (Qt, Boost, OpenCV) take too long to build:

  • vcpkg — binary caching with GitHub Actions, Azure Artifacts, or a local cache server
  • Conan — Conan Center Index has pre-built binaries for many configurations

No / fine building from source:

  • CPM.cmake or FetchContent (native CMake) for small/medium projects

Quick comparison

vcpkgConanCPM.cmakeHunter
LanguageCMake/JSONPythonCMakeCMake
Binary cachingYesYesNoYes
Package count~2,000+~1,500+(uses GitHub)~400+
Windows supportExcellentGoodGoodGood
CI integrationExcellentGoodSimpleOK
ABI flexibilityModerateExcellentSource-onlyModerate
Learning curveLowMediumVery lowMedium

Recommendation by scenario

ScenarioRecommended
New project, any platformvcpkg (lowest friction)
Enterprise / mixed ABIs / large teamConan
Open-source project, CI simpleCPM.cmake
Small project, few depsFetchContent (built-in CMake)
Windows + Visual Studiovcpkg (built into VS 2019+)
Already using Homebrew/aptSystem packages + find_package

vcpkg quick start

bash
# Install vcpkg
git clone https://github.com/microsoft/vcpkg ~/vcpkg
~/vcpkg/bootstrap-vcpkg.sh

# Add a manifest file (vcpkg.json)
{
  "dependencies": ["fmt", "nlohmann-json", "boost-filesystem"]
}

# Configure CMake
cmake -B build -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build

Conan quick start

bash
pip install conan
conan profile detect  # auto-detect your compiler

# conanfile.txt
[requires]
fmt/10.2.1
nlohmann_json/3.11.3

[generators]
CMakeDeps
CMakeToolchain

# Install + generate
conan install . --output-folder=build --build=missing
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake

CPM.cmake — zero-install FetchContent wrapper

CPM.cmake wraps FetchContent with version pinning, a package cache, and a one-line syntax. No separate tool to install — just a single downloaded .cmake file:

cmake
# Download CPM.cmake once (or check it in to your repo)
file(DOWNLOAD
    https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/CPM.cmake
    ${CMAKE_BINARY_DIR}/cmake/CPM.cmake)
include(${CMAKE_BINARY_DIR}/cmake/CPM.cmake)

# Add dependencies — fetched from GitHub and built from source
CPMAddPackage("gh:fmtlib/fmt#10.2.1")
CPMAddPackage("gh:nlohmann/json@3.11.3")
CPMAddPackage(
    NAME spdlog
    GITHUB_REPOSITORY gabime/spdlog
    GIT_TAG v1.13.0
    OPTIONS "SPDLOG_FMT_EXTERNAL ON"  # build options for the dep
)

add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE fmt::fmt nlohmann_json::nlohmann_json spdlog::spdlog)
bash
# Set a local cache so packages aren't re-downloaded across builds:
cmake -B build -DCPM_SOURCE_CACHE=~/.cpm-cache

CPM.cmake is ideal for open-source projects where you want self-contained, reproducible builds without asking contributors to install vcpkg or Conan.


vcpkg binary caching in CI

vcpkg re-builds from source by default. Binary caching stores compiled packages so CI doesn't rebuild boost on every run:

yaml
# .github/workflows/ci.yml
- name: Set up vcpkg
  uses: lukka/run-vcpkg@v11
  with:
    vcpkgDirectory: ${{ github.workspace }}/vcpkg
    vcpkgGitCommitId: 'abc123...'  # pin to a specific vcpkg commit

- name: Configure CMake
  run: |
    cmake -B build \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
  env:
    VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"  # GitHub Actions cache
bash
# Local binary cache (shared across your machine's builds):
export VCPKG_BINARY_SOURCES="clear;files,~/.vcpkg-cache,readwrite"

# NuGet feed (for teams sharing binaries):
export VCPKG_BINARY_SOURCES="clear;nuget,https://your-feed.pkgs.visualstudio.com/,readwrite"

vcpkg triplets — cross-compilation

Triplets specify the target platform and linkage (<arch>-<os>-<linkage>):

bash
# Static linking on Linux (avoids libstdc++ version issues at deploy time):
cmake -B build -DCMAKE_TOOLCHAIN_FILE=... -DVCPKG_TARGET_TRIPLET=x64-linux-static

# ARM64 cross-compile from x64 Linux:
cmake -B build -DCMAKE_TOOLCHAIN_FILE=... -DVCPKG_TARGET_TRIPLET=arm64-linux

# Windows 64-bit static:
cmake -B build -DCMAKE_TOOLCHAIN_FILE=... -DVCPKG_TARGET_TRIPLET=x64-windows-static

Custom triplet — override defaults per-project:

cmake
# vcpkg-triplets/x64-linux-static-md.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
bash
cmake -B build -DVCPKG_OVERLAY_TRIPLETS=vcpkg-triplets \
               -DVCPKG_TARGET_TRIPLET=x64-linux-static-md

Conan profiles — managing ABI variants

Conan profiles capture the full build environment: compiler, stdlib, arch, build type. This is where Conan beats vcpkg for teams with multiple configurations:

ini
# ~/.conan2/profiles/gcc14-release
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=14
compiler.libcxx=libstdc++11
build_type=Release

[buildenv]
CC=gcc-14
CXX=g++-14
bash
# Use a named profile:
conan install . --profile gcc14-release --output-folder=build --build=missing

# Cross-compile: separate host/build profiles
conan install . --profile:host arm64-linux --profile:build gcc14-release