2020-06-08 23:30:43 +02:00
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# python-pybind
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
|
2022-01-04 13:39:00 +01:00
|
|
|
PYTHON_PYBIND_VERSION = 2.9.0
|
2020-06-08 23:30:43 +02:00
|
|
|
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
|
2020-06-08 23:30:43 +02:00
|
|
|
|
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))
|