Skip to content

Package_managers

Package managers simplify C++ dependency management by handling downloading, building, and linking external libraries. This chapter covers the most popular options.

Manual dependency management is painful:

  • Finding and downloading libraries
  • Resolving transitive dependencies
  • Building libraries for different platforms
  • Managing versions and conflicts

Package managers solve all of these problems.

The most popular C++ package manager.

Terminal window
# Using pip (recommended)
pip install conan
# Verify installation
conan --version
[requires]
boost/1.80.0
nlohmann_json/3.10.5
poco/1.12.0
[generators]
cmake_find_package
cmake_paths
[options]
boost:shared=False
poco:shared=False
from conans import ConanFile, CMake, tools
class MyProject(ConanFile):
name = "myproject"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
exports_sources = "CMakeLists.txt", "src/*"
generators = "cmake", "cmake_find_package"
def requirements(self):
self.requires("boost/1.80.0")
self.requires("nlohmann_json/3.10.5")
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
self.copy("*.h", dst="include", src="src")
self.copy("*.lib", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.dylib", dst="lib", keep_path=False)
Terminal window
# Install dependencies
conan install . -s build_type=Release
# Create package
conan create . user/channel
# Search for packages
conan search boost
# List installed packages
conan list
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject)
# Include Conan-generated files
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
find_package(Boost REQUIRED)
find_package(nlohmann_json REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
Boost::boost
nlohmann_json::nlohmann_json
)

Microsoft’s C++ package manager, now officially supported.

Terminal window
# Clone repository
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
# Run bootstrap script
./bootstrap-vcpkg.sh # Linux/macOS
bootstrap-vcpkg.bat # Windows
# Integrate with Visual Studio
vcpkg integrate install
Terminal window
# Search for packages
vcpkg search boost
# Install packages
vcpkg install boost:x64-linux
vcpkg install nlohmann-json:x64-linux
# Install specific version
vcpkg install boost:arm64-linux==1.80.0
# Remove package
vcpkg remove boost

vcpkg uses triplets to specify target platforms:

triplets/custom-triplet.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_CONFIGURATION_MODE "EXTERNAL")
Terminal window
# Use custom triplet
vcpkg install boost:custom-triplet
Terminal window
# Configure with vcpkg
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake
# For dynamic linking
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-windows-dynamic
cmake_minimum_required(VERSION 3.15)
project(MyProject CXX)
find_package(Boost REQUIRED)
find_package(nlohmann_json REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE
Boost::boost
nlohmann_json::nlohmann_json
)

A CMake-driven package manager.

# In your CMakeLists.txt
include(HunterGate)
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.280.tar.gz"
SHA1 "abc123..."
)
project(MyProject)
find_package(Glog REQUIRED)
# hunter_config(Glog VERSION 0.6.0)
# hunter_config(Boost VERSION 1.80.0)

Bazel - Build System with Package Management

Section titled “Bazel - Build System with Package Management”

Bazel includes dependency management via repositories.

workspace(
name = "myproject",
managed_directories = {"@": ["EXTERNAL"]},
)
http_archive(
name = "boost",
url = "https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz",
sha256 = "...",
strip_prefix = "boost_1_80_0",
)
new_http_archive(
name = "nlohmann_json",
url = "https://github.com/nlohmann/json/releases/download/v3.10.5/include.zip",
build_file = "//third_party:nlohmann_json.BUILD",
)

A CMake script for dependency management inspired by Conan.

Terminal window
# Download CPM.cmake
wget https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.38.3/cpm.cmake
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(MyProject)
# Include CPM
include(cpm.cmake)
# Add packages
CPMAddPackage("gh:fmtlib/fmt#10.0.0")
CPMAddPackage("gh:nlohmann/json@3.10.5")
CPMAddPackage(
NAME Boost
VERSION 1.80.0
URL https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz
SHA256 abc123...
)
# Use packages
add_executable(main main.cpp)
target_link_libraries(main PRIVATE
fmt::fmt
nlohmann_json::nlohmann_json
)
FeatureConanvcpkgHunter
Package Count~2000~1900~500
Cross-compilationExcellentGoodGood
Binary cachingYesYesYes
CMake integrationExcellentExcellentGood
MSVC supportExcellentExcellentGood
Linux/macOSExcellentExcellentGood
Build systemPythonCMakeCMake
RegistrationCenteredDecentralizedCentralized
# conanfile.txt - Use version ranges
[requires]
boost/[>=1.70.0 <2.0.0]
nlohmann_json/3.10.5
Terminal window
# Generate lock file
conan lock create . --lockfile-out=conan.lock
# Use lock file
conan install . --lockfile=conan.lock
Terminal window
# Add private Conan server
conan remote add myserver https://myserver.com/artifactory/api/conan/myrepo
# Or use local cache
conan config set storage.path=/path/to/cache
# GitHub Actions example
- name: Install Conan
run: pip install conan
- name: Configure
run: conan install . -s build_type=Release
- name: Build
run: cmake --build . --config Release
from conans import ConanFile, CMake, tools
class MyLibraryConan(ConanFile):
name = "mylib"
version = "1.0.0"
license = "MIT"
settings = "os", "compiler", "build_type", "arch"
exports_sources = "CMakeLists.txt", "src/*"
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
self.copy("*.h", dst="include", src="include")
self.copy("*.lib", dst="lib")
self.copy("*.so", dst="lib")
self.copy("*.dylib", dst="lib")
def package_info(self):
self.cpp_info.libs = ["mylib"]
Terminal window
# Create package
conan create . user/channel
# Upload to remote
conan upload mylib/1.0.0@user/channel --all
  • Package managers simplify dependency management
  • Conan is most popular for C++ with Python-based recipes
  • vcpkg is Microsoft’s official package manager with CMake integration
  • CPM.cmake provides simple CMake-based dependency management
  • Choose based on your project’s build system and needs
  • Consider private registries for proprietary dependencies