Skip to content
C++
Package Manager
Updated 2025-01-01T00:00:00.000Z

Conan 2 — C++ Package Manager

"Conan 2 reference: conanfile.py, conanfile.txt, profiles, generators, binary compatibility, and CMake integration."

TL;DR

Conan 2 is a decentralized C++ package manager with binary caching and full binary compatibility management. Use conanfile.txt for simple projects, conanfile.py for complex ones. Conan Center Index has 1500+ packages.

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

Quick start with conanfile.txt

ini
# conanfile.txt
[requires]
fmt/10.1.1
nlohmann_json/3.11.3
boost/1.83.0

[generators]
CMakeDeps
CMakeToolchain
bash
# Install dependencies — downloads or builds binaries
conan install . --output-folder=build --build=missing

# Configure CMake using the generated toolchain
cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
cmake
# CMakeLists.txt
find_package(fmt REQUIRED)
find_package(nlohmann_json REQUIRED)
target_link_libraries(myapp PRIVATE fmt::fmt nlohmann_json::nlohmann_json)

conanfile.py — for complex requirements

python
# conanfile.py
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout

class MyAppConan(ConanFile):
    name = "my-app"
    version = "1.0"
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeDeps", "CMakeToolchain"

    def requirements(self):
        self.requires("fmt/10.1.1")
        self.requires("openssl/3.1.2")
        if self.settings.os == "Linux":
            self.requires("libpthread-stubs/0.4")

    def build_requirements(self):
        self.tool_requires("cmake/3.27.1")
        self.tool_requires("ninja/1.11.1")

    def layout(self):
        cmake_layout(self)

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

Profiles — compiler configuration

Conan uses profiles to define the compiler, stdlib, and build settings:

ini
# ~/.conan2/profiles/default  (created by: conan profile detect)
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux

Multiple profiles

ini
# ~/.conan2/profiles/clang17
[settings]
arch=x86_64
build_type=Debug
compiler=clang
compiler.cppstd=20
compiler.libcxx=libc++
compiler.version=17
os=Linux

[buildenv]
CC=clang-17
CXX=clang++-17
bash
# Use a specific profile
conan install . --profile=clang17 --output-folder=build --build=missing

# Cross-compile: host profile + build profile
conan install . \
  --profile:host=arm-linux \
  --profile:build=default \
  --output-folder=build --build=missing

Binary management

Conan's key feature: binaries are identified by a hash of (package name, version, settings, options, dependencies). If a matching binary exists in the cache or a remote, it's downloaded. Otherwise, it's built from source.

bash
# Check if binary exists without building
conan install . --output-folder=build

# Force build from source
conan install . --output-folder=build --build=missing  # build only if no binary
conan install . --output-folder=build --build=*        # build everything

# Show binary compatibility hash
conan search fmt/10.1.1 -r conancenter

# List cached packages
conan list "fmt:*"

Package options

Many packages expose options (static/shared, with/without features):

ini
# conanfile.txt
[requires]
boost/1.83.0

[options]
boost*:shared=False       # static linking
boost*:without_python=True
openssl*:shared=True
python
# conanfile.py
def requirements(self):
    self.requires("boost/1.83.0")

def configure(self):
    self.options["boost"].shared = False
    self.options["boost"].without_filesystem = False

Conan Center Index

1500+ pre-built open source packages at conan.io/center:

bash
# Search packages
conan search fmt -r conancenter

# Get package info
conan inspect fmt/10.1.1 -r conancenter

# Common packages
fmt/10.1.1              # {fmt} formatting library
nlohmann_json/3.11.3    # JSON for Modern C++
boost/1.83.0            # Boost libraries
openssl/3.1.2           # TLS/crypto
zlib/1.3                # Compression
sqlite3/3.43.2          # Embedded database
protobuf/4.24.4         # Protocol Buffers
grpc/1.56.2             # gRPC
catch2/3.4.0            # Unit testing
gtest/1.14.0            # Google Test
benchmark/1.8.3         # Google Benchmark
spdlog/1.12.0           # Fast logging
eigen/3.4.0             # Linear algebra

Private Artifactory remote

For enterprise or proprietary packages:

bash
# Add a remote
conan remote add mycompany https://artifactory.mycompany.com/artifactory/api/conan/conan-local

# Login
conan remote login mycompany myuser --password mypassword

# Upload a built package
conan upload "mylib/1.0" -r mycompany

# Install from multiple remotes (searched in order)
conan install . -r conancenter -r mycompany --output-folder=build

CI with GitHub Actions

yaml
- name: Install Conan
  run: pip install conan

- name: Detect profile
  run: conan profile detect

- name: Cache Conan packages
  uses: actions/cache@v4
  with:
    path: ~/.conan2/p
    key: conan-${{ hashFiles('conanfile.*') }}-${{ runner.os }}

- name: Install dependencies
  run: conan install . --output-folder=build --build=missing

- name: Configure and build
  run: |
    cmake -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
    cmake --build build

Conan 1 → Conan 2 migration

Conan 2 (released 2023) has breaking changes from Conan 1:

Conan 1Conan 2
GeneratorcmakeCMakeDeps + CMakeToolchain
Profile detectionmanualconan profile detect
conanfile.py importsfrom conans import ConanFilefrom conan import ConanFile
self.copy()availableremoved — use copy() from conan.tools.files
cpp_info.libsdirectstill works
build_requiresmethod namerenamed to build_requirements
Edit on GitHubUpdated 2025-01-01T00:00:00.000Z