Skip to content

附录A: CMake完整模板

CMake 是 pybind11 项目最常用的构建系统。本附录提供从最小配置到完整配置的完整模板。

最小可运行配置,仅需最少的文件即可编译 pybind11 模块:

cmake_minimum_required(VERSION 3.15)
project(example_module)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(pybind11 REQUIRED)
pybind11_add_module(example example.cpp)
example.cpp
#include <pybind11/pybind11.h>
PYBIND11_MODULE(example, m) {
m.def("add", [](int a, int b) { return a + b; });
}

如果想跟随源码树中的 pybind11,或不想依赖系统安装:

cmake_minimum_required(VERSION 3.15)
project(example_module)
add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

包含所有常用选项的完整配置:

cmake_minimum_required(VERSION 3.18)
project(my_module VERSION 1.0.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(Python COMPONENTS Interpreter Development REQUIRED)
include_directories(${Python_INCLUDE_DIRS})
link_directories(${Python_LIBRARY_DIRS})
find_package(pybind11 CONFIG REQUIRED)
message(STATUS "pybind11 version: ${pybind11_VERSION}")
pybind11_add_module(my_module
src/module1.cpp
src/module2.cpp
)
set_target_properties(my_module PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build"
)
install(TARGETS my_module
LIBRARY DESTINATION "${Python_SITEARCHS}"
ARCHIVE DESTINATION "${Python_SITEARCHS}"
RUNTIME DESTINATION "${Python_SITEARCHS}"
)

处理 Windows、macOS、Linux 不同平台的配置:

cmake_minimum_required(VERSION 3.18)
project(cross_platform_module)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(WIN32)
message(STATUS "Windows detected")
# Windows 特定配置
add_definitions(-D_WIN32_WINNT=0x0601)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(/Od /Zi /MDd)
else()
add_definitions(/O2 /Oi /GL /MD)
endif()
elseif(APPLE)
message(STATUS "macOS detected")
# macOS 特定配置
set(CMAKE_MACOSX_RPATH ON)
# 支持 Apple Silicon
if(CMAKE_OSX_ARCHITECTURES STREQUAL "")
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
endif()
elseif(UNIX)
message(STATUS "Linux detected")
# Linux 特定配置
add_definitions(-DLINUX)
endif()
find_package(Python COMPONENTS Interpreter Development REQUIRED)
message(STATUS "Python version: ${Python_VERSION}")
message(STATUS "Python executable: ${Python_EXECUTABLE}")
message(STATUS "Python include dir: ${Python_INCLUDE_DIR}")
message(STATUS "Python library: ${Python_LIBRARY}")
find_package(pybind11 CONFIG REQUIRED)
file(GLOB SOURCES "src/*.cpp")
pybind11_add_module(core_module ${SOURCES})
set_target_properties(core_module PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
if(MSVC)
# 禁用一些警告
add_compile_options(/W3 /wd4127 /wd4267 /wd4800)
# 运行时库
foreach(OUTPUTCONFIG IN CMAKE_CONFIGURATION_TYPES)
string(TOUPPER "${OUTPUTCONFIG}" OUTPUTCONFIG)
set(CMAKE_CXX_FLAGS_${OUTPUTCONFIG} "/MD${PYTHON_MSVC_DEBUG_SUFFIX}")
endforeach()
endif()
变量说明示例值
Python_EXECUTABLEPython 解释器路径/usr/bin/python3
Python_INCLUDE_DIRPython 头文件目录/usr/include/python3.10
Python_LIBRARYPython 库文件/usr/lib/libpython3.10.so
Python_VERSIONPython 版本3.10.4
Python_SITEARCH站点包安装目录/usr/lib/python3.10/site-packages
PYBIND11_CASE_INSENSIVE_EXCEPTIONS异常名称大小写不敏感ON/OFF
变量说明默认值
CMAKE_CXX_STANDARDC++ 标准版本17
CMAKE_BUILD_TYPE构建类型Release
CMAKE_POSITION_INDEPENDENT_CODE位置无关代码ON
变量说明
pybind11_DIRpybind11 CMake 配置目录
PYBIND11_INSTALL是否创建安装目标
PYBIND11_TEST是否编译测试

有时直接通过环境变量指定 Python 路径更方便:

Terminal window
export Python_ROOT="/usr/local/python"
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release