[2026] C++ Conan 레시피 작성 완벽 가이드 | 패키지·빌드·원격 저장소 [#53-4]
이 글의 핵심
C++ Conan 패키지 레시피 작성: conanfile.py 구조, CMake 빌드, test_package, conan create·upload, Artifactory 연동. 자주 발생하는 에러·베스트 프랙티스·프로덕션 패턴까지 실전 예제로 다룹니다.
들어가며: “우리 라이브러리를 Conan 패키지로 배포하고 싶어요”
실제 겪는 문제 시나리오
시나리오 1: 사내 라이브러리 배포 지옥
"lib-core를 프로젝트 A, B, C에서 쓰는데, 각각 다른 경로에 복사해 두고 있어요."
"버전 1.2로 업데이트했는데, 프로젝트 B는 아직 1.1을 쓰고 있어요. 언제 바꿀지 모르겠어요."
"새 팀원이 lib-core를 빌드하려면 README 10페이지를 읽어야 해요."
원인: 수동 복사·빌드·경로 설정으로 버전 관리와 의존성 추적이 어렵습니다. 시나리오 2: Conan Center에 없는 라이브러리
"우리 회사에서 fork한 OpenSSL을 Conan으로 쓰고 싶어요."
"레거시 C 라이브러리를 Conan 패키지로 감싸서 배포해야 해요."
"내부용 유틸리티를 팀 전체가 conan install로 쓰게 하고 싶어요."
원인: Conan Center에 없는 패키지는 직접 레시피를 작성해야 합니다. 시나리오 3: 빌드 설정 불일치
"Windows에서는 shared=True로 빌드했는데, Linux에서는 static으로 빌드돼서 링크 에러가 나요."
"Debug/Release 혼용으로 ABI 호환성 문제가 발생해요."
원인: 레시피에 options·settings가 명확히 정의되지 않아 팀원마다 다른 바이너리가 생성됩니다. 시나리오 4: 패키지 품질 검증 부재
"conan create 했는데, 다른 프로젝트에서 링크하면 undefined reference가 나요."
"헤더 경로가 잘못되어 include가 안 돼요."
원인: test_package로 패키지 소비를 검증하지 않아, 실제 사용 시 문제가 드러납니다.
Conan 레시피로 해결
| 문제 | 해결 |
|---|---|
| 수동 배포 | conan create + conan upload로 원격 저장소 배포 |
| 버전 불일치 | name/version으로 패키지 식별, conan install로 버전 지정 |
| 빌드 설정 차이 | settings·options로 바이너리 구성 통일 |
| 품질 검증 | test_package로 빌드·링크·실행 검증 |
| 아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다. |
flowchart LR
subgraph Before["수동 배포 (Before)"]
B1[소스 복사] --> B2[수동 빌드]
B2 --> B3[경로 설정]
B3 --> B4[프로젝트마다 다름]
end
subgraph After["Conan 레시피 (After)"]
A1[conanfile.py] --> A2[conan create]
A2 --> A3[캐시/원격 저장소]
A3 --> A4[conan install로 통일]
end
이 글에서 다루는 것
| 항목 | 내용 |
|---|---|
| 레시피 구조 | conanfile.py 메타데이터, settings, options |
| 완전한 예제 | 헤더 전용, 정적/공유 라이브러리, CMake 연동 |
| 빌드·배포 | conan create, conan upload, test_package |
| 원격 저장소 | Artifactory, Conan Server 연동 |
| 자주 발생하는 에러 | package_info 누락, exports_sources 오류 등 |
| 베스트 프랙티스 | 버전 관리, 옵션 설계, CMake install |
| 프로덕션 패턴 | CI/CD, 버전 태깅, 사내 레포 워크플로 |
실무 적용 경험: 이 글은 대규모 C++ 프로젝트에서 실제로 겪은 문제와 해결 과정을 바탕으로 작성되었습니다. 책이나 문서에서 다루지 않는 실전 함정과 디버깅 팁을 포함합니다.
목차
- 환경 설정
- conanfile.txt vs conanfile.py
- 완전한 conanfile.py 레시피
- 헤더 전용 라이브러리 레시피
- 패키지 빌드 및 검증
- 원격 저장소 배포
- 자주 발생하는 에러와 해결법
- 베스트 프랙티스
- 프로덕션 패턴
- 구현 체크리스트
1. 환경 설정
필수 요구사항
| 항목 | 버전 | 비고 |
|---|---|---|
| Conan | 2.x | pip install conan |
| Python | 3.8+ | Conan 2.x 요구 |
| CMake | 3.15+ | CMake 기반 레시피 시 |
| C++ | C++14 이상 권장 | - |
Conan 설치 및 프로젝트 템플릿
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# Conan 2.x 설치
pip install conan
# 버전 확인
conan --version
# CMake 라이브러리 레시피 템플릿 생성 (Hello World 수준)
conan new cmake_lib -d name=mylib -d version=1.0
conan new로 생성되는 구조: 아래 코드는 text를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
mylib/
├── CMakeLists.txt
├── conanfile.py
├── include/
│ └── mylib.h
├── src/
│ └── mylib.cpp
└── test_package/
├── CMakeLists.txt
├── conanfile.py
└── src/
└── example.cpp
2. conanfile.txt vs conanfile.py
언제 무엇을 쓸까?
| 형식 | 용도 | 빌드·패키징 |
|---|---|---|
| conanfile.txt | 패키지 소비만 할 때 | 없음 (requires, generators만) |
| conanfile.py | 패키지 생성 또는 고급 소비 | build(), package(), package_info() |
레시피 작성은 반드시 conanfile.py를 사용합니다. conanfile.txt는 [requires]에 패키지 목록만 적고, 빌드·패키징 로직을 정의할 수 없습니다. |
conanfile.txt (소비 전용)
아래 코드는 ini를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
[requires]
mylib/1.0
[generators]
CMakeDeps
CMakeToolchain
conanfile.py (레시피 = 패키지 생성)
다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class MylibConan(ConanFile):
name = "mylib"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"
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]
3. 완전한 conanfile.py 레시피
3.1 레시피 전체 구조
Conan 레시피의 핵심 메서드와 역할: 아래 코드는 mermaid를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
flowchart TD A[conanfile.py] --> B[layout] A --> C[generate] A --> D[build] A --> E[package] A --> F[package_info] B --> G[소스·빌드 경로 정의] C --> H[CMakeToolchain 등 생성] D --> I[실제 빌드 수행] E --> J[아티팩트를 package 폴더로 복사] F --> K[소비자에게 전달할 정보]
3.2 완전한 CMake 라이브러리 레시피
다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
from conan.tools.build import check_min_cppstd
from conan.tools.files import copy
class MylibConan(ConanFile):
name = "mylib"
version = "1.0.0"
# 메타데이터 (선택이지만 권장)
license = "MIT"
author = "Your Name <your@email.com>"
url = "https://github.com/yourorg/mylib"
description = "A sample C++ library for Conan packaging"
topics = ("conan", "library", "example")
# 바이너리 구성
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}
# 소스 파일 (레시피와 함께 export됨)
exports_sources = "CMakeLists.txt", "src/*", "include/*"
def config_options(self):
# Windows에서는 fPIC 의미 없음
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self)
def requirements(self):
# 의존성 예: self.requires("fmt/10.1.1")
pass
def generate(self):
deps = CMakeDeps(self)
deps.generate()
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]
# 헤더 경로는 CMake install이 설정하면 자동
# 수동 지정 시: self.cpp_info.includedirs = [include]
3.3 CMakeLists.txt (레시피와 연동)
레시피의 cmake.install()이 동작하려면 CMake에 install 타겟이 있어야 합니다.
다음은 cmake를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
cmake_minimum_required(VERSION 3.15)
project(mylib VERSION 1.0.0 LANGUAGES CXX)
add_library(mylib
src/mylib.cpp
)
target_include_directories(mylib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_features(mylib PUBLIC cxx_std_17)
# Conan이 package()에서 cmake.install() 호출 시 사용
install(TARGETS mylib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install(DIRECTORY include/ DESTINATION include)
3.4 주요 속성·메서드 설명
| 항목 | 설명 |
|---|---|
| exports_sources | 레시피와 함께 Conan 캐시로 복사할 파일. conan create 시 사용 |
| config_options() | 플랫폼별로 옵션 제거 (예: Windows에서 fPIC) |
| configure() | 옵션 간 의존성 (shared=True면 fPIC 불필요) |
| layout() | 소스·빌드·패키지 폴더 구조. cmake_layout()이 표준 |
| generate() | CMakeToolchain, CMakeDeps 등 빌드 설정 파일 생성 |
| build() | 실제 빌드 (cmake configure + build) |
| package() | 빌드 결과를 package 폴더로 복사 |
| package_info() | 소비자가 링크·include할 때 필요한 정보 |
4. 헤더 전용 라이브러리 레시피
헤더 전용 라이브러리는 빌드 단계가 없습니다. build()를 생략하고, package()에서 헤더만 복사합니다.
다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
from conan import ConanFile
from conan.tools.files import copy
class HeaderOnlyConan(ConanFile):
name = "headeronly"
version = "1.0.0"
description = "Header-only C++ library"
# 헤더 전용: settings 불필요 (바이너리 없음)
# 단, 의존성이 있으면 settings 필요
settings = "os", "compiler", "build_type", "arch"
no_copy_source = True # 소스를 그대로 package에 복사
exports_sources = "include/*"
def package(self):
copy(self, "*.hpp", self.source_folder, self.package_folder)
copy(self, "*.h", self.source_folder, self.package_folder)
def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.libdirs = []
# includedirs 기본값이 "include"이므로, include/ 아래에 있으면 생략 가능
self.cpp_info.includedirs = [include]
주의: no_copy_source = True이면 self.source_folder에 소스가 있으므로, exports_sources로 지정한 파일이 package() 시점에 사용 가능합니다.
5. 패키지 빌드 및 검증
5.1 conan create — 빌드 + test_package
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 현재 디렉터리의 conanfile.py로 패키지 생성
conan create .
# 특정 설정
conan create . -s build_type=Debug
conan create . -o mylib/1.0.0:shared=True
# 프로필 지정
conan create . -pr=default
conan create는 다음을 수행합니다:
- 레시피와
exports_sources를 캐시로 export generate()→build()→package()실행test_package/로 이동해 패키지 소비 테스트
5.2 test_package 구조
test_package는 패키지가 올바르게 생성되었는지 검증하는 소규모 Conan 프로젝트입니다.
아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
test_package/
├── CMakeLists.txt
├── conanfile.py
└── src/
└── example.cpp
test_package/conanfile.py: 다음은 python를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
import os
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeDeps", "CMakeToolchain"
def layout(self):
cmake_layout(self)
def requirements(self):
# 생성 중인 패키지를 의존성으로
self.requires(self.tested_reference_str())
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
# 빌드된 실행 파일 실행
self.run(f".{os.sep}example")
test_package/CMakeLists.txt: 아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES CXX)
find_package(mylib REQUIRED)
add_executable(example src/example.cpp)
target_link_libraries(example PRIVATE mylib::mylib)
test_package/src/example.cpp: 아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.
#include <mylib.h>
int main() {
mylib::hello();
return 0;
}
5.3 conan create 출력 예시
다음은 text를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
======== Exporting recipe to the cache ========
mylib/1.0.0: Exporting package recipe
...
======== Installing packages ========
-------- Installing package mylib/1.0.0 (1 of 1) --------
mylib/1.0.0: Building from source
mylib/1.0.0: Calling build()
...
mylib/1.0.0: Package 'xxx' built
======== Testing the package: Building ========
...
======== Testing the package: Executing test ========
mylib/1.0.0 (test package): Running test()
mylib/1.0.0 (test package): RUN: ./example
5.4 로컬 개발 워크플로 (conan install + build)
패키지를 매번 conan create하지 않고, 로컬에서 수정하면서 빌드할 때:
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 1. 의존성 설치 (자기 자신은 제외)
conan install . --output-folder=build --build=missing
# 2. CMake 빌드
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
6. 원격 저장소 배포
6.1 conan upload — 로컬 캐시 → 원격
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 특정 패키지 업로드
conan upload "mylib/1.0.0" -r myremote --all
# 모든 리비전·바이너리 포함
conan upload "mylib/*" -r myremote --all
6.2 remote 추가 및 확인
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# remote 목록
conan remote list
# 사내 Artifactory 추가
conan remote add mycompany https://mycompany.jfrog.io/artifactory/api/conan/conan-local
# remote 우선순위 (0이 가장 높음)
conan remote add mycompany https://....--insert=0
6.3 Artifactory 연동 예시
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 1. remote 추가
conan remote add mycompany https://mycompany.jfrog.io/artifactory/api/conan/conan-local
# 2. 패키지 생성
conan create . mylib/1.0.0@
# 3. 업로드
conan upload "mylib/1.0.0" -r mycompany --all
6.4 소비 측에서 사내 레포 사용
아래 코드는 ini를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# conanfile.txt
[requires]
mylib/1.0.0
[generators]
CMakeDeps
CMakeToolchain
# mycompany remote에서 먼저 찾도록
conan install . --output-folder=build --build=missing
7. 자주 발생하는 에러와 해결법
에러 1: “package_info() missing cpp_info.libs”
ERROR: .../package_info(): self.cpp_info.libs is empty
원인: package_info()에서 self.cpp_info.libs를 설정하지 않음 (라이브러리 패키지인 경우).
해결법:
def package_info(self):
self.cpp_info.libs = [mylib] # 실제 라이브러리 이름
헤더 전용이면:
def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.libdirs = []
에러 2: “exports_sources” 파일을 찾을 수 없음
ERROR: ....exports_sources ....not found
원인: exports_sources에 지정한 경로가 레시피 디렉터리에 없음.
해결법:
아래 코드는 python를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 존재하는 경로만 지정
exports_sources = "CMakeLists.txt", "src/*", "include/*"
# 디렉터리 전체
exports_sources = "include/*"
에러 3: “CMake install failed” / “No install target”
CMake Error: ....install TARGETS given no RUNTIME DESTINATION
원인: CMakeLists.txt에 install() 타겟이 없거나 잘못됨.
해결법:
아래 코드는 cmake를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
install(TARGETS mylib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install(DIRECTORY include/ DESTINATION include)
에러 4: test_package에서 “find_package(mylib) failed”
원인: package_info()의 cpp_info가 CMakeDeps에 제대로 전달되지 않음. 또는 CMake 타겟 이름 불일치.
해결법:
다음은 간단한 python 코드 예제입니다. 함수를 통해 로직을 구현합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
def package_info(self):
self.cpp_info.libs = [mylib]
# CMake 타겟 이름 명시 (기본은 패키지 이름)
self.cpp_info.set_property("cmake_target_name", "mylib::mylib")
에러 5: “Binary not found” / “Can’t find a compatible binary”
ERROR: Missing prebuilt package for 'mylib/1.0.0'
원인: 해당 설정(OS, 컴파일러, arch 등)에 맞는 바이너리가 원격·캐시에 없음. 해결법: 아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# 소스에서 빌드
conan create . --build=missing
# 특정 패키지만 빌드
conan create . --build=mylib
에러 6: “Version conflict” (의존성 간)
ERROR: Conflict in mylib/1.0.0: requirement 'fmt/9.x' conflicts with 'fmt/10.1.1'
원인: 직접·간접 의존성의 버전 요구가 충돌. 해결법:
def requirements(self):
self.requires("fmt/10.1.1", override=True) # 강제로 이 버전 사용
에러 7: “conan create” 시 “layout()” 관련 오류
ERROR: ....layout(): self.source_folder is None
원인: exports_sources만 있고 외부 소스를 쓰지 않을 때, layout()에서 self.source_folder를 잘못 참조.
해결법: cmake_layout(self) 사용 시, Conan이 source_folder를 exports_sources 기준으로 설정합니다. conan create는 레시피 디렉터리를 소스로 사용합니다.
에러 8: Windows에서 “fPIC” 옵션 에러
ERROR: option 'fPIC' doesn't exist
원인: Windows에서는 fPIC가 의미 없는데 옵션에 남아 있음. 해결법:
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
에러 9: “Package not found” (upload 후)
원인: remote 순서, 인증, 또는 패키지 참조 형식 오류. 해결법: 아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# remote 확인
conan remote list
# 패키지 검색
conan search mylib -r mycompany
# 인증 (Artifactory)
conan remote add mycompany https://....--insert=0
# 사용자/비밀번호는 conan config set으로 또는 환경변수
에러 10: package_info의 includedirs가 비어 있음
원인: CMake install(DIRECTORY include/ DESTINATION include)로 설치했는데, 패키지 폴더 구조가 다름.
해결법:
다음은 간단한 python 코드 예제입니다. 함수를 통해 로직을 구현합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
def package_info(self):
self.cpp_info.includedirs = [include]
# 또는 실제 구조에 맞게
self.cpp_info.includedirs = [include/mylib]
8. 베스트 프랙티스
8.1 버전 관리
- 시맨틱 버전링:
1.2.3,2.0.0형식 사용 - conanfile.py의 version: 가능하면 단일 소스(예:
scm또는 외부 파일)에서 가져오기 아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 코드를 직접 실행해보면서 동작을 확인해보세요.
from conan.tools.scm import Git
from conan import ConanFile
class MylibConan(ConanFile):
name = "mylib"
version = "1.0.0" # 또는 동적: self.version = ...
8.2 options 설계
- shared: 정적/동적 라이브러리 선택 — 대부분의 C++ 라이브러리가 지원
- fPIC: Linux/macOS에서 공유 라이브러리 시 필요
- with_xxx: 기능 플래그 (예:
with_ssl,with_tests) 아래 코드는 python를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_ssl": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"with_ssl": True,
}
8.3 CMake install 규칙
install(TARGETS ...)로 라이브러리·실행 파일 설치install(DIRECTORY include/ DESTINATION include)로 헤더 설치- Conan의
cmake.install()이CMAKE_INSTALL_PREFIX를 패키지 폴더로 설정하므로, CMake 표준 경로 사용
8.4 test_package 필수화
conan create전에 반드시test_package로 검증- 실제 소비 시나리오(빌드·링크·실행)를 테스트
8.5 package_info 명확화
아래 코드는 python를 사용한 구현 예제입니다. 함수를 통해 로직을 구현합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
def package_info(self):
self.cpp_info.libs = [mylib]
self.cpp_info.includedirs = [include]
# 필요 시
self.cpp_info.defines = [MYLIB_VERSION=100]
self.cpp_info.cxxflags = []
8.6 exports_sources 최소화
- 빌드에 필요한 파일만 포함
*.md,*.txt등 불필요한 파일 제외
exports_sources = "CMakeLists.txt", "src/*", "include/*"
9. 프로덕션 패턴
패턴 1: CI에서 conan create
다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# .github/workflows/conan-package.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Conan
run: pip install conan
- name: Create package
run: conan create . --build=missing
- name: Upload to Artifactory
if: github.ref == 'refs/heads/main'
run: |
conan remote add mycompany ${{ secrets.CONAN_REMOTE_URL }} --insert=0
conan user -r mycompany -p ${{ secrets.CONAN_PASSWORD }} ${{ secrets.CONAN_USER }}
conan upload "mylib/*" -r mycompany --all
패턴 2: 버전 태그와 연동
다음은 간단한 bash 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# Git 태그에서 버전 추출
VERSION=$(git describe --tags --abbrev=0)
conan create . mylib/${VERSION}@
conan upload "mylib/${VERSION}" -r mycompany --all
패턴 3: conan export-pkg (기존 빌드 결과 패키징)
이미 빌드된 바이너리가 있을 때, 다시 빌드하지 않고 패키지로 만들 수 있습니다.
conan export-pkg . mylib/1.0.0@ -pf build/package
패턴 4: 프로필 공유
아래 코드는 text를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
conan/
└── profiles/
├── linux-gcc12
├── windows-msvc2022
└── macos-clang
conan create . -pr=conan/profiles/linux-gcc12
패턴 5: lockfile로 재현 가능한 빌드
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# lockfile 생성
conan lock create .
# lockfile로 create (의존성 버전 고정)
conan create . --lockfile=conan.lock --build=missing
패턴 6: Docker로 멀티 플랫폼 패키지 생성
아래 코드는 dockerfile를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y python3-pip cmake g++ build-essential
RUN pip install conan
WORKDIR /app
COPY . .
RUN conan profile detect --force
RUN conan create . --build=missing
10. 구현 체크리스트
레시피 작성
-
name,version정의 -
settings= “os”, “compiler”, “build_type”, “arch” -
options(shared, fPIC 등) 필요 시 정의 -
config_options()에서 Windows fPIC 제거 -
exports_sources에 빌드 필요 파일만 포함 -
layout()에서cmake_layout(self)사용 -
generate()에서 CMakeToolchain, CMakeDeps 생성 -
build()에서 CMake configure + build -
package()에서 cmake.install() 또는 copy() -
package_info()에서 libs, includedirs 설정
CMake
-
install(TARGETS ...)정의 -
install(DIRECTORY include/ ...)정의 -
target_include_directories에 INSTALL_INTERFACE 포함
test_package
-
test_package/conanfile.py에서self.tested_reference_str()사용 -
test_package에서 실제 사용 시나리오 검증
배포
-
conan create성공 확인 -
conan upload전 remote·인증 설정 - CI에서 자동 create·upload (선택)
정리
| 항목 | 설명 |
|---|---|
| 레시피 | conanfile.py로 패키지 빌드·패키징·정보 정의 |
| 빌드 | conan create로 캐시에 패키지 생성 |
| 검증 | test_package로 소비 가능 여부 확인 |
| 배포 | conan upload로 원격 저장소에 업로드 |
| 에러 | package_info, exports_sources, CMake install 등 점검 |
| 핵심 원칙: |
- package_info()를 반드시 올바르게 작성 — 소비자가 링크·include할 수 있게
- test_package로 패키지 품질 검증
- CMake install과 레시피의
package()연동 - options로 플랫폼·기능별 바이너리 구성
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. 사내 라이브러리를 Conan 패키지로 배포할 때, Conan Center에 없는 라이브러리를 패키징할 때, 오픈소스 프로젝트를 Conan으로 배포할 때 활용합니다. conan install 한 번으로 팀 전체가 동일한 버전을 사용할 수 있습니다.
Q. conanfile.txt와 conanfile.py 중 뭘 써야 하나요?
A. 패키지를 만들 때는 반드시 conanfile.py입니다. 패키지를 쓸 때만 conanfile.txt로 충분합니다. 고급 옵션·조건부 의존성이 필요하면 소비 측에서도 conanfile.py를 씁니다.
Q. 선행으로 읽으면 좋은 글은?
A. vcpkg와 Conan 기초(#40-1)에서 Conan 사용법을 먼저 익히면 좋습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.