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
- Install:
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.cmakeinclude, 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 addandadd_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
| vcpkg | Conan | CPM.cmake | Hunter | |
|---|---|---|---|---|
| Language | CMake/JSON | Python | CMake | CMake |
| Binary caching | Yes | Yes | No | Yes |
| Package count | ~2,000+ | ~1,500+ | (uses GitHub) | ~400+ |
| Windows support | Excellent | Good | Good | Good |
| CI integration | Excellent | Good | Simple | OK |
| ABI flexibility | Moderate | Excellent | Source-only | Moderate |
| Learning curve | Low | Medium | Very low | Medium |
Recommendation by scenario
| Scenario | Recommended |
|---|---|
| New project, any platform | vcpkg (lowest friction) |
| Enterprise / mixed ABIs / large team | Conan |
| Open-source project, CI simple | CPM.cmake |
| Small project, few deps | FetchContent (built-in CMake) |
| Windows + Visual Studio | vcpkg (built into VS 2019+) |
| Already using Homebrew/apt | System packages + find_package |
vcpkg quick start
# 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 buildConan quick start
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.cmakeCPM.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:
# 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)# Set a local cache so packages aren't re-downloaded across builds:
cmake -B build -DCPM_SOURCE_CACHE=~/.cpm-cacheCPM.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:
# .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# 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>):
# 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-staticCustom triplet — override defaults per-project:
# 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)cmake -B build -DVCPKG_OVERLAY_TRIPLETS=vcpkg-triplets \
-DVCPKG_TARGET_TRIPLET=x64-linux-static-mdConan 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:
# ~/.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# 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