在manylinux构建Python二进制模块:find_package(Python3)仅支持Development.Module
背景
我正在构建一个要分发到多个Linux发行版的Python模块,由于部分发行版gcc版本低于我本地使用的版本,所以采用manylinux环境,具体用的是基于AlmaLinux(红帽系)、提供gcc12的manylinux_2_28镜像。
镜像的/opt/python/路径下预装了多个版本的CPython(3.6至3.13)和PyPy(3.7至3.10),目录以PEP 425标签命名(比如/opt/python/cp37-cp37m对应CPython 3.7),用来生成对应格式的wheel包。我已经把PATH环境变量前缀设为/opt/python/cp312-cp312/bin,确保which python3指向该路径下的Python 3.12。
遇到的CMake配置问题
执行以下CMake命令时:
find_package(Python3 ${REQUESTED_PYTHON_VERSION} COMPONENTS Interpreter Development)
出现报错:
Could NOT find Python3 (missing: Python3_LIBRARIES Development Development.Embed) (found version "3.12.3")
后续引入pybind11时配置失败。
已找到的解决方案
将CMake命令改为:
find_package(Python3 ${REQUESTED_PYTHON_VERSION} COMPONENTS Interpreter Development.Module)
配置即可正常完成。
疑问与解答
疑问1:CMake使用Development.Module而非Development组件时,具体查找的内容是什么?
CMake的FindPython3模块中,Development是一个复合组件,默认包含Development.Module和Development.Embed两个子组件:
Development.Embed是给把Python解释器嵌入到C/C++程序用的,需要查找完整的Python静态库或可嵌入共享库;Development.Module则专门针对构建Python扩展模块(比如pybind11编写的模块),只查找扩展模块编译链接必需的最小依赖:- Python核心头文件(如
Python.h、pyconfig.h) - 扩展模块链接所需的符号库(Linux下通常是
libpythonX.Y.so) - 扩展模块构建的配置信息
- Python核心头文件(如
manylinux镜像里的预装Python是针对wheel打包优化的版本,默认没有提供Development.Embed需要的完整嵌入依赖,所以用Development组件会因找不到Development.Embed对应的文件报错,换成Development.Module就只找扩展模块需要的内容,自然能匹配上。
疑问2:gcc/链接器所需的底层文件是否为/opt/python/cp312-cp312/include和lib目录下的文件?
是的,这两个目录就是gcc编译、链接Python扩展模块的核心依赖来源:
include目录:存放Python的头文件,编译时需要这些文件解析Python的API定义;lib目录:存放Python的共享库,链接时需要它关联Python运行时的符号。
CMake的Development.Module组件会自动定位到这两个目录,确保编译链接流程能找到所需文件。
内容的提问来源于stack exchange,提问作者TooTone

