본문으로 건너뛰기
Previous
Next
C++ Conan 기초 완벽 가이드 | 설치·conanfile·프로필·CMake 연동 [#53-4]

C++ Conan 기초 완벽 가이드 | 설치·conanfile·프로필·CMake 연동 [#53-4]

C++ Conan 기초 완벽 가이드 | 설치·conanfile·프로필·CMake 연동 [#53-4]

이 글의 핵심

C++ Conan 패키지 매니저 기초 가이드입니다. 설치, conanfile 작성, 프로필 설정, CMake 연동 방법을 실전 예제로 설명합니다. fmt 라이브러리를 쓰려는데, 수동으로 다운로드·빌드·경로 설정이 너무 번거로워요. findpackage(fmt) could not find — CMake가 fmt를 못 찾아요. 로컬에서는 되는데 CI에서만 빌드가 실패해요.

들어가며: “Conan으로 의존성 지옥을 탈출하고 싶어요”

문제 시나리오

"fmt 라이브러리를 쓰려는데, 수동으로 다운로드·빌드·경로 설정이 너무 번거로워요."
"find_package(fmt) could not find — CMake가 fmt를 못 찾아요."
"로컬에서는 되는데 CI에서만 빌드가 실패해요."
"팀원 A는 spdlog 1.10, 나는 1.12를 쓰고 있어요. 버전이 꼬였어요."
"Windows에서는 되는데 Linux에서 빌드가 안 돼요."
"의존성 A는 fmt 9.x, B는 fmt 10.x를 요구해서 Version conflict 에러가 나요."
"새 팀원이 프로젝트를 빌드하려면 README 10페이지를 읽어야 해요."

이 글은 Conan 2.x 기초 완벽 가이드입니다. 설치부터 conanfile, 프로필, remote, 패키지 생성, CMake 연동까지 실전 예제와 함께 다룹니다. 실무 문제 시나리오, 자주 발생하는 에러, 베스트 프랙티스, 프로덕션 패턴까지 900줄 분량으로 정리합니다. 이 글을 읽으면:

  • Conan 2.x를 설치하고 프로젝트에 적용할 수 있습니다.
  • conanfile.txt와 conanfile.py로 의존성을 선언할 수 있습니다.
  • 프로필로 플랫폼·컴파일러별 빌드 환경을 관리할 수 있습니다.
  • remote를 추가해 Conan Center·사내 레포에서 패키지를 가져올 수 있습니다.
  • 기본적인 패키지 생성 흐름을 이해할 수 있습니다.
  • 자주 발생하는 에러와 해결법을 알 수 있습니다. 요구 환경: Python 3.8+, Conan 2.x, CMake 3.16+, C++17 권장

실무 적용 경험: 이 글은 대규모 C++ 프로젝트에서 실제로 겪은 문제와 해결 과정을 바탕으로 작성되었습니다. 책이나 문서에서 다루지 않는 실전 함정과 디버깅 팁을 포함합니다.

문제 시나리오 상세

시나리오 1: 수동 의존성 관리 지옥

상황: fmt, spdlog, nlohmann_json을 프로젝트에 넣어야 함
문제: 각각 다운로드·빌드·include/lib 경로 설정 필요
결과: 팀원마다 경로가 다르고, 버전이 제각각

시나리오 2: find_package 실패

상황: CMakeLists.txt에 find_package(fmt REQUIRED) 추가
문제: fmt를 시스템에 수동 설치했지만 CMake가 못 찾음
결과: CMAKE_PREFIX_PATH, FMT_ROOT 등 경로를 일일이 지정해야 함

시나리오 3: CI 빌드 불일치

상황: 로컬에서는 빌드 성공, GitHub Actions에서 실패
문제: CI 환경에 라이브러리가 설치되어 있지 않음
결과: conan install을 CI 스크립트에 추가해야 함

시나리오 4: 버전 불일치

상황: spdlog가 fmt에 의존, nlohmann_json도 fmt에 의존
문제: spdlog는 fmt 9.x, nlohmann_json은 fmt 10.x 요구
결과: Version conflict — Conan이 자동 해결하거나 override 필요

시나리오 5: 플랫폼별 빌드 차이

상황: Windows(MSVC), Linux(GCC), macOS(Clang)에서 각각 빌드
문제: 컴파일러·아키텍처마다 다른 바이너리 필요
결과: Conan 프로필로 설정 분리
flowchart TB
  subgraph Problems[실제 겪는 문제]
    P1[수동 경로 설정]
    P2[find_package 실패]
    P3[CI 빌드 불일치]
    P4[버전 충돌]
    P5[플랫폼별 차이]
  end
  subgraph Solutions[Conan으로 해결]
    S1[conanfile로 선언]
    S2[CMakeToolchain 연동]
    S3[conan install in CI]
    S4[override·lockfile]
    S5[프로필 분리]
  end
  P1 --> S1
  P2 --> S2
  P3 --> S3
  P4 --> S4
  P5 --> S5

1. Conan 설치

1.1 필수 요구사항

항목버전비고
Python3.8+Conan 2.x 요구
CMake3.16+CMakeToolchain 사용 시
C++ 컴파일러GCC 9+, Clang 10+, MSVC 2019+-

1.2 pip로 설치 (권장)

# 가상환경 생성 (권장)
python -m venv .venv
source .venv/bin/activate   # Linux/macOS
# .venv\Scripts\activate   # Windows
# Conan 설치
pip install conan
# 버전 확인
conan --version
# Conan version 2.x.x

1.3 시스템 Python 사용 시

# 사용자 권한으로 설치
pip install --user conan
# 또는 시스템 전역 (관리자 권한)
pip install conan

1.4 설치 검증

# Conan 실행 확인
conan --version
# 기본 프로필 확인
conan profile path default
# 프로필 자동 감지 (시스템 컴파일러 감지)
conan profile detect --force

1.5 Conan 1.x vs 2.x

주의: Conan 2.x는 1.x와 호환되지 않습니다. 프로필 형식, conan install 옵션, 캐시 경로가 다릅니다. 이 글은 Conan 2.x 기준입니다.

# Conan 2.x 캐시 경로 (기본)
# Linux/macOS: ~/.conan2/
# Windows: C:\Users\<user>\.conan2\

2. conanfile.txt — 의존성 선언

2.1 conanfile.txt란?

conanfile.txt는 패키지를 소비할 때 사용하는 단순한 선언 형식입니다. [requires]에 패키지 목록, [generators]에 CMake 연동용 생성기를 지정합니다.

2.2 완전한 conanfile.txt 예제

[requires]
fmt/10.1.1
spdlog/1.12.1
nlohmann_json/3.11.2
[generators]
CMakeDeps
CMakeToolchain
[options]
spdlog:shared=False
spdlog:wchar_support=False

섹션 설명:

  • [requires]: 필요한 패키지와 버전을 선언
  • [generators]: CMake가 find_package로 패키지를 찾을 수 있도록 설정 파일 생성
  • [options]: 패키지별 옵션 (선택)

2.3 버전 지정 방법

[requires]
fmt/10.1.1              # 정확한 버전
spdlog/[>=1.10.0]       # 최소 버전
# 범위 지정 (Conan 2.x)
# fmt/[>=10.0,<11]      # 10.x 대

2.4 프로젝트 구조

my-conan-app/
├── conanfile.txt
├── CMakeLists.txt
├── src/
│   └── main.cpp
└── build/

2.5 의존성 설치

conan install 내부 동작 흐름:

conan install . --output-folder=build --build=missing

1. conanfile 파싱:
   
   conanfile.txt 읽기:
   [requires]
   fmt/10.1.1
   spdlog/1.12.1
   nlohmann_json/3.11.2
   

   
   의존성 그래프 초기화:
   app (root)
   ├─ fmt/10.1.1
   ├─ spdlog/1.12.1
   └─ nlohmann_json/3.11.2

2. 전이적 의존성 해석 (Transitive Dependencies):
   
   spdlog/1.12.1의 conanfile.py 조회:
   def requirements(self):
       self.requires("fmt/9.1.0")
   
   의존성 그래프 업데이트:
   app
   ├─ fmt/10.1.1 (직접 요구)
   ├─ spdlog/1.12.1
   │  └─ fmt/9.1.0 (spdlog가 요구)  ← 버전 충돌!
   └─ nlohmann_json/3.11.2

3. 버전 충돌 해결 (Conflict Resolution):
   
   충돌 감지:
   - app → fmt/10.1.1
   - spdlog → fmt/9.1.0
   
   버전 범위 만족 확인:
   spdlog의 요구사항: fmt/[>=9.1.0,<11]
   
   해결 전략:
   a. 상위 버전 선택 (Version Range 내):
      fmt/10.1.1 선택 (9.1.0과 호환)
      → spdlog의 범위 만족
   
   b. 버전 범위 불만족 시:
      ERROR: Version conflict
      → override 또는 lockfile 필요
   
   최종 그래프:
   app
   ├─ fmt/10.1.1 ✓
   ├─ spdlog/1.12.1
   │  └─ fmt/10.1.1 (shared)
   └─ nlohmann_json/3.11.2

4. 패키지 ID 계산 (Package ID):
   
   각 패키지별로 바이너리 ID 생성:
   
   fmt/10.1.1:
   Hash = hash(
       name: fmt
       version: 10.1.1
       settings:
           os: Linux
           arch: x86_64
           compiler: gcc-12
           build_type: Release
       options:
           header_only: False
   )
   
   예시 ID: fmt/10.1.1:abc123def456...
   
   이 ID로 캐시/remote에서 바이너리 검색

5. 캐시 검색:
   
   ~/.conan2/p/ 디렉토리 검색:
   
   fmt/10.1.1:abc123... → 캐시에 있음 ✓
   spdlog/1.12.1:def456... → 캐시에 없음 ✗
   nlohmann_json/3.11.2:ghi789... → 캐시에 있음 ✓

6. Remote 다운로드:
   
   캐시에 없는 패키지:
   spdlog/1.12.1:def456...
   
   Remote 순서대로 검색:
   1. mycompany → 없음
   2. conancenter → 있음!
   
   다운로드:
   https://center.conan.io/.../spdlog-1.12.1-Linux-x86_64-gcc12-Release.tgz

   ~/.conan2/p/spdlog.../p/

7. --build=missing 처리:
   
   바이너리가 없으면 소스에서 빌드:
   
   1. 소스 다운로드:
      git clone https://github.com/gabime/spdlog.git
   
   2. conanfile.py의 build() 실행:
      cmake -B build -S .
      cmake --build build
   
   3. package() 실행:
      cmake --install build --prefix=package/
   
   4. 캐시에 저장:
      ~/.conan2/p/spdlog.../p/
      ├── include/
      ├── lib/
      └── conaninfo.txt

8. Generator 실행:
   
   CMakeToolchain:
   생성: build/conan_toolchain.cmake
   
   내용:
   set(CMAKE_CXX_COMPILER /usr/bin/g++-12)
   set(CMAKE_BUILD_TYPE Release)
   list(APPEND CMAKE_PREFIX_PATH 
       ~/.conan2/p/fmt.../p
       ~/.conan2/p/spdlog.../p
       ~/.conan2/p/nlohmann_json.../p
   )
   
   CMakeDeps:
   생성: build/fmt-config.cmake
         build/spdlog-config.cmake
         build/nlohmann_json-config.cmake
   
   fmt-config.cmake 내용:
   add_library(fmt::fmt STATIC IMPORTED)
   set_target_properties(fmt::fmt PROPERTIES
       IMPORTED_LOCATION ~/.conan2/p/fmt.../p/lib/libfmt.a
       INTERFACE_INCLUDE_DIRECTORIES ~/.conan2/p/fmt.../p/include
   )

9. 출력 파일 생성:
   
   build/
   ├── conan_toolchain.cmake
   ├── conanbuild.sh
   ├── conandeps.cmake
   ├── fmt-config.cmake
   ├── spdlog-config.cmake
   └── nlohmann_json-config.cmake

전체 시간:
- 캐시 히트: ~1초
- Remote 다운로드: ~5-10초
- 소스 빌드: ~30-300초 (패키지 크기 의존)
# build 폴더에 conan_toolchain.cmake 등 생성
conan install . --output-folder=build --build=missing
# 프로필 지정
conan install . --output-folder=build --build=missing -pr=default
# Debug 빌드
conan install . --output-folder=build --build=missing -s build_type=Debug

—build=missing: Conan Center에 해당 설정의 바이너리가 없으면 소스에서 빌드합니다.

3. conanfile.py — 고급 소비

3.1 conanfile.txt vs conanfile.py

형식용도조건부 의존성옵션
conanfile.txt단순 의존성 선언불가제한적
conanfile.py고급 소비·패키지 생성가능완전 제어

3.2 소비용 conanfile.py 예제

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMakeDeps, cmake_layout
from conan.tools.build import check_min_cppstd
class MyAppConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeDeps", "CMakeToolchain"
    def layout(self):
        cmake_layout(self)
    def requirements(self):
        self.requires("fmt/10.1.1")
        self.requires("spdlog/1.12.1")
        self.requires("nlohmann_json/3.11.2")
    def configure(self):
        check_min_cppstd(self, "17")
    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.generate()

3.3 조건부 의존성

def requirements(self):
    self.requires("fmt/10.1.1")
    self.requires("spdlog/1.12.1")
    if self.settings.os == "Linux":
        self.requires("libcurl/8.5.0")
    if self.settings.build_type == "Debug":
        self.requires("gtest/1.14.0")  # 테스트용

3.4 패키지 옵션 지정

def requirements(self):
    self.requires("spdlog/1.12.1")
    # spdlog 옵션: shared, wchar_support 등
    # conan install 시 -o spdlog:shared=True 로 전달
# shared 라이브러리로 빌드
conan install . --output-folder=build -o spdlog:shared=True

4. 프로필 — 빌드 환경

4.1 프로필이란?

프로필은 OS, 아키텍처, 컴파일러, 빌드 타입 등 빌드 환경을 정의합니다. Conan은 프로필에 따라 적절한 바이너리를 선택하거나 소스에서 빌드합니다.

4.2 기본 프로필 확인

# 기본 프로필 확인
conan profile show default
# 프로필 경로
conan profile path default

4.3 프로필 자동 감지

# 시스템 컴파일러 감지
conan profile detect --force
# 감지된 프로필 확인
conan profile show default

4.4 프로필 파일 예시

# conan/profiles/linux-gcc12
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++11
build_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja

4.5 Windows 프로필

# conan/profiles/windows-msvc2022
[settings]
os=Windows
arch=x86_64
compiler=msvc
compiler.version=193
compiler.runtime=dynamic
build_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja

4.6 macOS 프로필

# conan/profiles/macos-clang
[settings]
os=Macos
arch=armv8
compiler=apple-clang
compiler.version=15
compiler.libcxx=libc++
build_type=Release

4.7 프로필 사용

# 프로필 지정
conan install . --output-folder=build -pr=conan/profiles/linux-gcc12
# 프로필 + 옵션
conan install . --output-folder=build -pr=default -o spdlog:shared=True

4.8 프로필 구조

my-project/
├── conanfile.txt
├── conan/
│   └── profiles/
│       ├── default
│       ├── linux-gcc12
│       ├── windows-msvc2022
│       └── macos-clang
└── CMakeLists.txt

5. Remote — 패키지 소스

5.1 Remote란?

Remote는 Conan이 패키지를 다운로드하는 원격 저장소입니다. 기본적으로 Conan Center가 등록되어 있습니다.

5.2 Remote 목록 확인

# 등록된 remote 목록
conan remote list
# 출력 예시
# conancenter: https://center.conan.io [VerifySSL: True]

5.3 Remote 추가 (사내 레포)

# Artifactory Conan 레포 추가
conan remote add mycompany https://mycompany.jfrog.io/artifactory/api/conan/conan-local
# remote 목록
conan remote list

5.4 Remote 우선순위

# 먼저 나오는 remote가 우선 검색됨
conan remote list
# 사내 레포를 우선으로 (0번에 삽입)
conan remote add mycompany https://....--insert=0
# remote 제거
conan remote remove mycompany

5.5 패키지 검색

# Conan Center에서 fmt 검색
conan search fmt --remote=conancenter
# 사용 가능한 버전 확인
conan search fmt --remote=conancenter -q="*"
# 사내 remote에서 검색
conan search lib-core --remote=mycompany

5.6 Remote 흐름

sequenceDiagram
  participant Dev as 개발자
  participant Conan as Conan
  participant CC as Conan Center
  participant Corp as 사내 레포
  Dev->>Conan: conan install
  Conan->>Conan: remote 순서대로 검색
  Conan->>Corp: 1. 사내 레포 검색
  alt 패키지 있음
    Corp-->>Conan: 패키지 제공
  else 없음
    Conan->>CC: 2. Conan Center 검색
    CC-->>Conan: 패키지 제공
  end
  Conan->>Dev: build/conan_toolchain.cmake

6. 패키지 생성 기초

6.1 패키지 생성 흐름

Conan 패키지는 레시피(conanfile.py)로 정의됩니다. conan create로 빌드·패키징·캐시 저장을 수행합니다. 상세한 레시피 작성은 Conan 레시피 가이드를 참고하세요.

6.2 최소 conanfile.py (패키지 생성용)

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class MylibConan(ConanFile):
    name = "mylib"
    version = "1.0.0"
    settings = "os", "compiler", "build_type", "arch"
    exports_sources = "CMakeLists.txt", "src/*", "include/*"
    def layout(self):
        cmake_layout(self)
    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()
    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
    def package(self):
        cmake = CMake(self)
        cmake.install()
    def package_info(self):
        self.cpp_info.libs = [mylib]

6.3 conan create 실행

# 현재 디렉터리의 conanfile.py로 패키지 생성
conan create .
# 특정 설정
conan create . -s build_type=Debug
# 프로필 지정
conan create . -pr=default

6.4 패키지 생성 후 사용

# conan create로 캐시에 저장된 패키지
# conanfile.txt에서 mylib/1.0.0 요구 가능
[requires]
mylib/1.0.0
fmt/10.1.1
[generators]
CMakeDeps
CMakeToolchain

7. CMake 연동

7.1 전체 흐름

1. conan install → build/conan_toolchain.cmake, build/fmt-config.cmake 등 생성
2. cmake -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake ...
3. find_package(fmt) 등이 Conan이 생성한 config를 사용

7.2 CMakeLists.txt 예제

cmake_minimum_required(VERSION 3.20)
project(my-conan-app VERSION 1.0.0 LANGUAGES CXX)
# Conan toolchain이 먼저 로드되어야 함
add_executable(my-app src/main.cpp)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
target_link_libraries(my-app PRIVATE
    fmt::fmt
    spdlog::spdlog
    nlohmann_json::nlohmann_json
)
target_compile_features(my-app PRIVATE cxx_std_17)

7.3 빌드 스크립트

#!/bin/bash
# build.sh
set -e
BUILD_DIR=build
echo "=== Conan install ==="
conan install . --output-folder=$BUILD_DIR --build=missing
echo "=== CMake configure ==="
cmake -B $BUILD_DIR -S . -DCMAKE_TOOLCHAIN_FILE=$BUILD_DIR/conan_toolchain.cmake
echo "=== CMake build ==="
cmake --build $BUILD_DIR
echo "=== Run ==="
./$BUILD_DIR/my-app

7.4 main.cpp 예제

#include <spdlog/spdlog.h>
#include <fmt/core.h>
#include <nlohmann/json.hpp>
int main() {
    spdlog::info("Conan 기초 예제");
    spdlog::info("fmt: {}", fmt::format("Hello, {}!", "Conan"));
    nlohmann::json j = {{"app", "my-conan-app"}, {"version", "1.0.0"}};
    spdlog::info("JSON: {}", j.dump());
    return 0;
}

7.5 CMake 연동 다이어그램

flowchart LR
  subgraph Conan[Conan]
    C1[conan install] --> C2[conan_toolchain.cmake]
    C2 --> C3[fmt-config.cmake]
    C2 --> C4[spdlog-config.cmake]
  end
  subgraph CMake[CMake]
    M1[CMAKE_TOOLCHAIN_FILE] --> M2[find_package]
    M2 --> M3[target_link_libraries]
  end
  C2 --> M1
  C3 --> M2
  C4 --> M2

7.6 완전한 프로젝트 예제

복사 후 바로 빌드 가능한 최소 프로젝트 구조입니다. 디렉터리 구조:

my-conan-app/
├── conanfile.txt
├── CMakeLists.txt
├── build.sh
└── src/
    └── main.cpp

conanfile.txt:

// 실행 예제
[requires]
fmt/10.1.1
spdlog/1.12.1
[generators]
CMakeDeps
CMakeToolchain

CMakeLists.txt:

cmake_minimum_required(VERSION 3.20)
project(my-conan-app LANGUAGES CXX)
add_executable(my-app src/main.cpp)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
target_link_libraries(my-app PRIVATE fmt::fmt spdlog::spdlog)
target_compile_features(my-app PRIVATE cxx_std_17)

src/main.cpp:

#include <spdlog/spdlog.h>
#include <fmt/core.h>
int main() {
    spdlog::info("{}", fmt::format("Hello, Conan!"));
    return 0;
}

빌드:

conan install . --output-folder=build --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
./build/my-app

8. 자주 발생하는 에러와 해결법

에러 1: “Could NOT find a package configuration file provided by ‘fmt’”

증상:

CMake Error at ...: Could not find a package configuration file provided by "fmt"

원인: conan install을 실행하지 않았거나, CMAKE_TOOLCHAIN_FILE을 Conan이 생성한 conan_toolchain.cmake로 지정하지 않음. 해결법:

# 1. conan install 먼저 실행
conan install . --output-folder=build --build=missing
# 2. CMake에 toolchain 파일 지정
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=$(pwd)/build/conan_toolchain.cmake

에러 2: “Version conflict”

증상:

ERROR: Version conflict: spdlog/1.12.1 requires fmt/9.1.0, nlohmann_json/3.11.2 requires fmt/10.1.1

해결법 1 — conanfile.txt:

// 실행 예제
[requires]
fmt/10.1.1
spdlog/1.12.1
nlohmann_json/3.11.2

직접 fmt/10.1.1을 선언하면 Conan이 우선 사용합니다. 해결법 2 — conanfile.py override:

def requirements(self):
    self.requires("spdlog/1.12.1")
    self.requires("nlohmann_json/3.11.2")
    self.requires("fmt/10.1.1", override=True)

에러 3: “conan_toolchain.cmake not found”

원인: conan install을 실행하지 않았거나, --output-folder 경로가 CMake -B와 다름. 해결법:

# output-folder를 build로 통일
conan install . --output-folder=build --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake

에러 4: “Package ‘fmt/10.1.1’ not found”

원인: Conan Center에 해당 버전이 없거나, remote 설정 문제. 해결법:

# 패키지 검색
conan search fmt --remote=conancenter
# 사용 가능한 버전 확인
conan search fmt --remote=conancenter -q="*"
# remote 목록 확인
conan remote list

에러 5: “Build type mismatch”

증상: Debug로 빌드했는데 Release 라이브러리와 링크됨. ABI 호환성 문제. 해결법:

# 프로필의 build_type 확인
conan profile show default
# Debug로 설치
conan install . --output-folder=build --build=missing -s build_type=Debug

에러 6: “Invalid configuration: compiler.version ‘12’ is not valid”

원인: 시스템에 설치된 GCC 버전이 프로필과 다름. 해결법:

# 설치된 컴파일러 확인
gcc --version
# 프로필 자동 감지
conan profile detect --force

에러 7: “Binary missing” / “Can’t find a compatible binary”

증상:

WARN: fmt/10.1.1: Binary missing

원인: 해당 설정(OS, 컴파일러, arch)에 맞는 바이너리가 Conan Center에 없음. 해결법:

# 소스에서 빌드
conan install . --output-folder=build --build=missing
# 특정 패키지만 빌드
conan install . --output-folder=build --build=fmt --build=spdlog

에러 8: “Python not found” / “Conan requires Python 3.8+”

원인: Python 3.8 미만 설치 또는 PATH 문제. 해결법:

# Python 버전 확인
python3 --version
# pip로 설치 시
python3 -m pip install conan

에러 9: “ERROR: Lockfile ‘conan.lock’ is outdated”

원인: conanfile.txt를 수정했지만 conan.lock을 업데이트하지 않음. 해결법:

# lockfile 재생성
conan lock create . --lockfile-out=conan.lock

에러 10: Windows에서 “MSVC not found”

원인: Visual Studio가 설치되어 있지 않거나, 개발자 명령 프롬프트가 아님. 해결법:

# Visual Studio Developer Command Prompt에서 실행
# 또는 vcvarsall.bat 먼저 실행
conan profile detect --force

9. 베스트 프랙티스

9.1 버전 명시

# 권장: 정확한 버전
fmt/10.1.1
# 주의: 범위는 재현 가능성 낮음
# fmt/[>=10.0]

9.2 conan install 순서

# 1. conan install 먼저
conan install . --output-folder=build --build=missing
# 2. CMake configure
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
# 3. CMake build
cmake --build build

9.3 프로필 공유

conan/profiles/ 를 프로젝트에 포함하고 팀원이 동일한 프로필 사용

9.4 lockfile 사용 (재현 가능한 빌드)

# lockfile 생성
conan lock create .
# lockfile로 설치
conan install . --output-folder=build --lockfile=conan.lock --build=missing

9.5 .gitignore

# Conan
build/
.conan/

9.6 베스트 프랙티스 요약

항목권장
버전fmt/10.1.1처럼 명시적 버전
lockfileconan.lock Git 커밋
프로필팀 공유 프로필 사용
CIconan install을 CI 스크립트에 포함
output-folderbuild와 CMake -B 경로 통일

10. 프로덕션 패턴

10.1 빌드 스크립트

#!/bin/bash
# build.sh
set -e
BUILD_DIR=build
PROFILE=${1:-default}
echo "=== Conan install (profile: $PROFILE) ==="
conan install . --output-folder=$BUILD_DIR --lockfile=conan.lock --build=missing -pr=$PROFILE
echo "=== CMake configure ==="
cmake -B $BUILD_DIR -S . -DCMAKE_TOOLCHAIN_FILE=$BUILD_DIR/conan_toolchain.cmake
echo "=== CMake build ==="
cmake --build $BUILD_DIR
echo "=== Run ==="
./$BUILD_DIR/my-app

10.2 GitHub Actions

name: Build
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - name: Install Conan
        run: pip install conan
      - name: Cache Conan
        uses: actions/cache@v4
        with:
          path: ~/.conan2
          key: conan-${{ runner.os }}-${{ hashFiles('conanfile.*', 'conan.lock') }}
      - name: Conan install
        run: |
          conan profile detect --force
          conan install . --output-folder=build --lockfile=conan.lock --build=missing
      - name: CMake configure
        run: cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
      - name: CMake build
        run: cmake --build build

10.3 프로젝트 구조 (프로덕션)

my-conan-prod/
├── conanfile.txt
├── conan.lock
├── CMakeLists.txt
├── build.sh
├── conan/
│   └── profiles/
│       ├── default
│       ├── linux-gcc12
│       └── windows-msvc2022
└── src/
    └── main.cpp

10.4 의존성 업데이트 워크플로우

conan lock create . --lockfile-out=conan.lock
conan install . --output-folder=build --lockfile=conan.lock --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
git add conan.lock && git commit -m "chore: update dependencies"

11. 구현 체크리스트

Conan 기초 사용 체크리스트

  • Conan 2.x 설치 (pip install conan)
  • conan profile detect --force 실행
  • conanfile.txt 또는 conanfile.py 작성
  • conan installCMAKE_TOOLCHAIN_FILE 지정
  • CMakeLists.txt에 find_package 추가
  • target_link_libraries에 Conan 패키지 링크

프로덕션 체크리스트

  • conan.lock 생성 및 Git 커밋
  • 팀 프로필 공유 (conan/profiles/)
  • CI에서 conan install 포함
  • CI에서 Conan 캐시 활용
  • 빌드 스크립트 (build.sh) 작성

에러 대응 체크리스트

  • find_package 실패 → toolchain 파일 지정 확인
  • Version conflict → override 또는 conanfile.txt에 직접 선언
  • Binary missing → --build=missing 사용
  • Build type mismatch → -s build_type 확인

정리

항목설명
설치pip install conan, Conan 2.x
conanfile.txt[requires], [generators]로 의존성 선언
conanfile.py조건부 의존성, 옵션, 고급 소비
프로필OS, 컴파일러, build_type 등 빌드 환경
RemoteConan Center, 사내 Artifactory
CMakeCMAKE_TOOLCHAIN_FILE로 연동
핵심 원칙:
  1. conan install을 CMake configure 전에 실행
  2. CMAKE_TOOLCHAIN_FILE을 Conan이 생성한 파일로 지정
  3. conan.lock으로 재현 가능한 빌드
  4. 프로필 공유로 팀 환경 일치

자주 묻는 질문 (FAQ)

Q. conanfile.txt와 conanfile.py 중 뭘 써야 하나요?

A. 단순 의존성만 선언하면 conanfile.txt로 충분합니다. 조건부 의존성, 옵션, 고급 설정이 필요하면 conanfile.py를 사용하세요.

Q. vcpkg와 Conan은 같이 쓸 수 있나요?

A. 같은 프로젝트에서 둘 다 쓰는 것은 권장하지 않습니다. 의존성 충돌과 경로 혼란이 발생할 수 있습니다. 팀 규약으로 하나를 선택하는 것이 좋습니다.

Q. Conan 1.x에서 2.x로 마이그레이션은?

A. Conan 2.x는 1.x와 호환되지 않습니다. conanfile.txt 형식은 비슷하지만, conan install 옵션과 프로필 형식이 다릅니다. Conan 2.0 마이그레이션 가이드를 참고하세요.

Q. lockfile을 언제 사용하나요?

A. 의존성 버전을 고정해 재현 가능한 빌드를 원할 때 conan lock create .로 lockfile을 생성하고 Git에 커밋합니다. CI에서는 --lockfile=conan.lock으로 설치합니다.

Q. 프로덕션에서 Conan 캐시는 어떻게 관리하나요?

A. CI에서 ~/.conan2를 캐시 레이어로 저장하고, conanfile.*·conan.lock 해시를 캐시 키로 사용합니다. Artifactory를 사용하면 바이너리 캐시 서버로 활용할 수 있습니다.

참고 자료


관련 글

심화 부록: 구현·운영 관점

이 부록은 앞선 본문에서 다룬 주제(「C++ Conan 기초 완벽 가이드 | 설치·conanfile·프로필·CMake 연동 [#53-4]」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.

내부 동작과 핵심 메커니즘

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]
sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(런타임·게이트웨이·프로세스)
  participant D as 의존성(API·DB·큐·파일)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)
  • 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.

프로덕션 운영 패턴

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가
용량피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.

확장 예시: 엔드투엔드 미니 시나리오

앞선 본문 주제(「C++ Conan 기초 완벽 가이드 | 설치·conanfile·프로필·CMake 연동 [#53-4]」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)
  authorize(validated, ctx)
  result = domainCore(validated)
  persistOrEmit(result, idempotentKey)
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정 불일치프로필·시크릿·기본값, 리전스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

배포 전에는 git addgit commitgit pushnpm run deploy 순서를 권장합니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

C++, Conan, 패키지관리, 의존성관리, CMake, 빌드시스템 등으로 검색하시면 이 글이 도움이 됩니다.