이번 글에서는 Python 바인딩 프로젝트를 CMake로 구성하고 설정하는 방법을 알아보겠습니다. C++로 작성된 라이브러리를 Python에서 사용할 수 있도록 바인딩하면 두 언어의 장점을 모두 활용할 수 있습니다. 이를 위해 다양한 라이브러리가 존재하며, 대표적으로 Boost.Python, pybind11, nanobind 등이 있습니다. 이 글에서는 특히 pybind11과 nanobind를 중심으로 설명하겠습니다.
Python 바인딩이란?
Python 바인딩은 C++로 구현된 코드를 Python에서 직접 호출할 수 있도록 연결해주는 기술입니다. 이를 통해 성능이 중요한 부분은 C++로 작성하고, 사용의 편의성은 Python으로 제공할 수 있습니다. 과학 계산, 게임 개발, 머신 러닝 등 다양한 분야에서 활용되고 있습니다.
주요 바인딩 라이브러리 소개
Boost.Python
- Boost.Python은 Boost 라이브러리의 일부로, C++ 코드를 Python에 바인딩하기 위한 강력한 도구입니다.
- 장점:
- 다양한 기능과 유연성 제공
- Boost의 다른 라이브러리와 통합 용이
- 단점:
- 상대적으로 복잡한 문법
- 컴파일 시간이 길고, 종속성이 많음
pybind11
- pybind11은 Boost.Python의 경량 대안으로, 현대적인 C++11/14 문법을 활용하여 간결한 바인딩 코드를 작성할 수 있습니다.
- 장점:
- 간단하고 직관적인 문법
- 컴파일 시간이 짧고, 종속성이 적음
- 단점:
- 일부 고급 기능은 Boost.Python에 비해 제한적
nanobind
- nanobind는 pybind11의 아이디어를 기반으로 더욱 경량화한 라이브러리로, 효율성과 메모리 사용량에 초점을 맞추고 있습니다.
- 장점:
- 매우 작은 바이너리 크기
- 빠른 컴파일 시간
- 단점:
- 상대적으로 새로운 프로젝트로, 문서와 커뮤니티 지원이 제한적일 수 있음
pybind11을 사용한 프로젝트 구성
프로젝트 디렉토리 구조
my_project/
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ └── mymodule.cpp
└── include/
└── mymodule.h
최상위 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyPybindProject)
add_subdirectory(src)
src/CMakeLists.txt
# pybind11 패키지 찾기
find_package(pybind11 REQUIRED)
# 모듈 생성
pybind11_add_module(mymodule mymodule.cpp)
# 필요한 경우 include 디렉토리 추가
target_include_directories(mymodule PRIVATE ${CMAKE_SOURCE_DIR}/include)
mymodule.cpp 예제
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(mymodule, m) {
m.doc() = "pybind11 example module";
m.def("add", &add, "A function which adds two numbers");
}
빌드 및 설치
mkdir build
cd build
cmake ..
make
빌드 후 생성된 mymodule 모듈을 Python에서 사용할 수 있습니다.
Python에서 사용 예시
import mymodule
result = mymodule.add(1, 2)
print(result) # 출력: 3
nanobind를 사용한 프로젝트 구성
프로젝트 디렉토리 구조
my_project/
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ └── mymodule.cpp
└── include/
└── mymodule.h
최상위 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyNanobindProject)
add_subdirectory(src)
nanobind 가져오기
nanobind는 FetchContent를 통해 가져올 수 있습니다.
include(FetchContent)
FetchContent_Declare(
nanobind
GIT_REPOSITORY https://github.com/wjakob/nanobind.git
GIT_TAG v1.2.0
)
FetchContent_MakeAvailable(nanobind)
src/CMakeLists.txt
# nanobind 디렉토리 설정
set(nanobind_DIR ${nanobind_SOURCE_DIR})
# 모듈 생성
add_library(mymodule MODULE mymodule.cpp)
# nanobind 및 Python 라이브러리 링크
target_link_libraries(mymodule PRIVATE nanobind::nanobind)
# 확장자 설정 (플랫폼에 따라 다를 수 있음)
set_target_properties(mymodule PROPERTIES PREFIX "" SUFFIX ".so")
mymodule.cpp 예제
#include <nanobind/nanobind.h>
namespace nb = nanobind;
int add(int i, int j) {
return i + j;
}
NB_MODULE(mymodule, m) {
m.doc() = "nanobind example module";
m.def("add", &add, "A function which adds two numbers");
}
빌드 및 설치
mkdir build
cd build
cmake ..
make
빌드 후 생성된 mymodule 모듈을 Python에서 사용할 수 있습니다.
Python에서 사용 예시
import mymodule
result = mymodule.add(1, 2)
print(result) # 출력: 3
pybind11과 nanobind 비교
특징 pybind11 nanobind
문법 | 직관적이고 간결함 | pybind11과 유사한 문법 |
컴파일 시간 | 빠름 | 매우 빠름 |
바이너리 크기 | 작음 | 더 작음 |
기능 지원 | 다양한 기능과 광범위한 지원 | 핵심 기능에 초점 |
문서 및 커뮤니티 | 풍부한 문서와 활발한 커뮤니티 | 상대적으로 제한적 |
종속성 | 최소화 | 최소화 |
- pybind11은 사용하기 쉽고 문서와 예제가 풍부하여 시작하기에 적합합니다.
- nanobind는 성능과 바이너리 크기에 민감한 프로젝트에 유리하지만, 상대적으로 새로운 프로젝트입니다.
프로젝트 구성 시 고려사항
- Python 버전 호환성: 사용하는 Python 버전에 맞는 라이브러리를 선택하고, CMake 설정에서 Python 해더와 라이브러리를 정확하게 참조해야 합니다.
- 컴파일러 지원: pybind11과 nanobind 모두 C++11 이상을 요구하므로, 컴파일러가 해당 표준을 지원하는지 확인해야 합니다.
- 배포 전략: 빌드된 모듈을 어떻게 배포할지 계획해야 합니다. 예를 들어, setuptools와 scikit-build를 사용하여 Python 패키지로 배포할 수 있습니다.
CMake 설정 추가사항
C++ 표준 설정
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
빌드 타입 설정
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
플랫폼별 설정
플랫폼에 따라 모듈 확장자가 다를 수 있으므로, 이를 설정해야 합니다.
if(WIN32)
set(EXTENSION ".pyd")
else()
set(EXTENSION ".so")
endif()
set_target_properties(mymodule PROPERTIES PREFIX "" SUFFIX ${EXTENSION})
결론
이번 글에서는 Python 바인딩 프로젝트를 CMake로 구성하고 설정하는 방법을 알아보았습니다. pybind11과 nanobind를 사용하여 C++ 코드를 Python에서 사용할 수 있도록 바인딩하는 방법을 살펴보았으며, 각 라이브러리의 특징과 사용 방법을 비교했습니다.
'개발 이야기 > CMake' 카테고리의 다른 글
[모던 CMake] Qt 프로젝트 구성과 빌드 (1) | 2024.12.11 |
---|---|
[모던 CMake] CUDA 프로젝트 구성과 빌드 (0) | 2024.12.10 |
[모던 CMake] 외부 프로젝트와의 통합 및 활용 (0) | 2024.12.08 |
[모던 CMake] 대규모 프로젝트에서의 베스트 프랙티스 (0) | 2024.12.07 |
[모던 CMake] 코드 분석 도구와 포매터 통합 (2) | 2024.12.06 |