I'm building a Python module that I'd like to distribute to multiple linux distributions, some of which will have less recent versions of gcc than I am building with, hence I am using manylinux. In particular, I'm using manylinux_2_28, which is alma (Red Hat family) based and provides gcc12.
Having downloaded the image, I've cloned my repo, and have almost gotten CMake configure to work. The problem starts with
find_package(Python3 ${REQUESTED_PYTHON_VERSION} COMPONENTS Interpreter Development)
which gives
Could NOT find Python3 (missing: Python3_LIBRARIES Development Development.Embed) (found version "3.12.3")
and subsequently the configuration errors out when bringing in pybind11.
The image provides Python
CPython 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and PyPy 3.7, 3.8, 3.9, 3.10 installed in /opt/python/-. The directories are named after the PEP 425 tags for each environment --e.g. /opt/python/cp37-cp37m contains a CPython 3.7 build, and can be used to produce wheels named like --cp37-cp37m-.whl.
hence before my configuration I prefix my PATH
with /opt/python/cp312-cp312/bin
so that which python3
=> /opt/python/cp312-cp312/bin/python3
.
My original question was how to overcome the problem. However, with more searching, I found an answer on CMake discourse. I.e. use Development.Module
rather than Development
.
find_package(Python3 ${REQUESTED_PYTHON_VERSION} COMPONENTS Interpreter Development.Module)
As I'd hoped, Python development is already available for each version. But what is going here? What is CMake actually looking for that it finds with Development.Module
rather than Development
, and what are the underlying files that gcc / the linker wants -- presumably these are the files present under include
and lib
in /opt/python/cp312-cp312/
?
Since CMake 3.18, the FindPython module splits Development
into Development.Module
and Development.Embed
. The former is to create Python modules, the latter to create a program that embeds the Python interpreter.
Manylinux has the libraries for creating modules, but not the ones for embedded Python. So on Manylinux you must use Development.Module
.
By the way, you should use find_package(Python …)
instead of find_package(Python3 …)
. The FindPython2
and FindPython3
modules are needed when both Python 2 and 3 must be managed at the same time. Python 2 has been at end of life for a very long time, Python is always Python 3 nowadays. By not explicitly using “Python 3” everywhere, it’ll be easier to transition to Python 4 when that arrives.