kumquat-buildroot/package/python-pybind/python-pybind.mk

29 lines
941 B
Makefile
Raw Normal View History

################################################################################
#
# python-pybind
#
################################################################################
PYTHON_PYBIND_VERSION = 2.9.0
PYTHON_PYBIND_SITE = $(call github,pybind,pybind11,v$(PYTHON_PYBIND_VERSION))
PYTHON_PYBIND_LICENSE = BSD-3-Clause
PYTHON_PYBIND_LICENSE_FILES = LICENSE
package/python-pybind: switch to cmake package pybind11 is not really a Python module; it is actually a set of headers that is used to wrap Python objects in C++. Since pybind version 2.6.1, it uses CMake internally. This causes a number of build issues for Buildroot because either no cmake is present or it is too old. pybind in fact has three parts: the C++ headers, a python module pybind11, and the tests. The python package's only purpose is to serve as a configure script for users of pybind. CMake is mainly used to build and run the tests, which use the (mock-installed) pybind11 module to find the (mock-installed) C++ headers. CMake is also used to install the headers. The setup.py script calls into CMake to install the headers and CMake support files to a temporary directory, then copies that together with the pybind11 module into the Python directory. The pybind11 module then returns the include and cmake paths relative to its install location (using __file__ to determine the install location). This is not at all compatible with how Buildroot expects things to be organised. - The include and CMake files are installed somewhere within the Python directories, where nobody will find them. - The Python module is installed for the target, but at build time Python modules are read from the host directory only. Therefore, a user of pybind can't actually load the module. To solve this, several options are possible: - Treat pybind as a host package. This causes users of pybind to build with an include path pointing into the host directory. This happens to work because pybind is a header-only library and because it is installed in a specific location which is not contaminated by other headers. However, it is philosophically wrong - a build for the target should never have an include path pointing to the host directory. - Install pybind in the usual way into staging, and add a stub module to the host directory that returns paths to the staging directory. This leaves a useless pybind11 module in the staging directory, and puts the headers and cmake files in an unusual location. In addition it is not so simple - we need to jump through hoops to make sure that cmake is called correctly when it goes through python-package. - Install the headers and cmake files using CMake, and add a (stub) python module in the host directory that points users to the staging directory. This puts the headers in the usual place (STAGING_DIR/usr/include) and still makes it possible to find them from a python package at build time. We choose the latter solution. First of all, convert to cmake-package. This installs just the headers and the cmake support files. We need to pass PYBIND11_NOPYTHON=ON because there is a cmake module that tries to find the python binary. It sometimes finds the system python, sometimes the host python. In either case, it checks whether this python's bitness and endianness correspond to that of the compiler - which generally it doesn't in cross-compilation. PYBIND_NOPYTHON bypasses this check. Install in staging and not in target. Before, it was installed to target but the python module would point to the target directory so it worked anyway; now, however, we can properly use the staging directory. Since it is no longer a python-package, the python module is not installed automatically. Install them manually in a post-staging-install hook. Since the python module is supposed to be used at build time, install it in the host directory rather than in staging. The python module normally looks in its current directory to find the include and cmake paths, but for cross-compilation this is wrong. Add a non-upstreamable patch that checks for STAGING_DIR in the environment. If it is set (which is the case in Buildroot), use that instead of the current directory. Add an explicit dependency on python3. The headers include Python.h, so any user of pybind needs to implicitly depend on python3. While we're at it, change it to support python3 only - even though pybind currently still supports python2, adding support for it in Buildroot is a little bit complicated and python2 will be removed soon anyway. Cc: Esben Haabendal <esben@geanix.com> Cc: Andreas Naumann <dev@andin.de> Co-Developed-by: Jagan Teki <jagan@amarulasolutions.com> Co-Developed-by: Guillaume W. Bres <guillaume.bressaix@gmail.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
2022-01-07 15:09:08 +01:00
PYTHON_PYBIND_INSTALL_STAGING = YES
PYTHON_PYBIND_INSTALL_TARGET = NO # Header-only library
PYTHON_PYBIND_DEPENDENCIES = python3
package/python-pybind: switch to cmake package pybind11 is not really a Python module; it is actually a set of headers that is used to wrap Python objects in C++. Since pybind version 2.6.1, it uses CMake internally. This causes a number of build issues for Buildroot because either no cmake is present or it is too old. pybind in fact has three parts: the C++ headers, a python module pybind11, and the tests. The python package's only purpose is to serve as a configure script for users of pybind. CMake is mainly used to build and run the tests, which use the (mock-installed) pybind11 module to find the (mock-installed) C++ headers. CMake is also used to install the headers. The setup.py script calls into CMake to install the headers and CMake support files to a temporary directory, then copies that together with the pybind11 module into the Python directory. The pybind11 module then returns the include and cmake paths relative to its install location (using __file__ to determine the install location). This is not at all compatible with how Buildroot expects things to be organised. - The include and CMake files are installed somewhere within the Python directories, where nobody will find them. - The Python module is installed for the target, but at build time Python modules are read from the host directory only. Therefore, a user of pybind can't actually load the module. To solve this, several options are possible: - Treat pybind as a host package. This causes users of pybind to build with an include path pointing into the host directory. This happens to work because pybind is a header-only library and because it is installed in a specific location which is not contaminated by other headers. However, it is philosophically wrong - a build for the target should never have an include path pointing to the host directory. - Install pybind in the usual way into staging, and add a stub module to the host directory that returns paths to the staging directory. This leaves a useless pybind11 module in the staging directory, and puts the headers and cmake files in an unusual location. In addition it is not so simple - we need to jump through hoops to make sure that cmake is called correctly when it goes through python-package. - Install the headers and cmake files using CMake, and add a (stub) python module in the host directory that points users to the staging directory. This puts the headers in the usual place (STAGING_DIR/usr/include) and still makes it possible to find them from a python package at build time. We choose the latter solution. First of all, convert to cmake-package. This installs just the headers and the cmake support files. We need to pass PYBIND11_NOPYTHON=ON because there is a cmake module that tries to find the python binary. It sometimes finds the system python, sometimes the host python. In either case, it checks whether this python's bitness and endianness correspond to that of the compiler - which generally it doesn't in cross-compilation. PYBIND_NOPYTHON bypasses this check. Install in staging and not in target. Before, it was installed to target but the python module would point to the target directory so it worked anyway; now, however, we can properly use the staging directory. Since it is no longer a python-package, the python module is not installed automatically. Install them manually in a post-staging-install hook. Since the python module is supposed to be used at build time, install it in the host directory rather than in staging. The python module normally looks in its current directory to find the include and cmake paths, but for cross-compilation this is wrong. Add a non-upstreamable patch that checks for STAGING_DIR in the environment. If it is set (which is the case in Buildroot), use that instead of the current directory. Add an explicit dependency on python3. The headers include Python.h, so any user of pybind needs to implicitly depend on python3. While we're at it, change it to support python3 only - even though pybind currently still supports python2, adding support for it in Buildroot is a little bit complicated and python2 will be removed soon anyway. Cc: Esben Haabendal <esben@geanix.com> Cc: Andreas Naumann <dev@andin.de> Co-Developed-by: Jagan Teki <jagan@amarulasolutions.com> Co-Developed-by: Guillaume W. Bres <guillaume.bressaix@gmail.com> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
2022-01-07 15:09:08 +01:00
PYTHON_PYBIND_CONF_OPTS = \
-DPYBIND11_INSTALL=ON \
-DPYBIND11_TEST=OFF \
-DPYBIND11_NOPYTHON=ON
PYTHON_PYBIND_INSTALL_PATH = $(HOST_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/pybind11
define PYTHON_PYBIND_INSTALL_MODULE
mkdir -p $(PYTHON_PYBIND_INSTALL_PATH)
cp -dpf $(@D)/pybind11/*.py $(PYTHON_PYBIND_INSTALL_PATH)
endef
PYTHON_PYBIND_POST_INSTALL_STAGING_HOOKS += PYTHON_PYBIND_INSTALL_MODULE
$(eval $(cmake-package))