support/testing: add test for python-pybind

The way that python-pybind can be used is fairly complicated, so a
runtime test for it is convenient. In addition, this test validates that
the headers actually work at runtime.

Signed-off-by: Guillaume W. Bres <guillaume.bressaix@gmail.com>
[Arnout:
 - Retain python3 only.
 - python-pybind is a target package, not host.
 - Select python-pybind instead of depend.
 - Simplify python-pybind-example package.
 - Check in python-pybind-example build if pybind11.get_include()
   produces output.
 - Don't use python3 -m pybind11 --includes: it includes the main python
   includes, which are for the host, not for the target.
 - Use TestPythonPackageBase instead of open-coding something imported
   with host python.
]
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
This commit is contained in:
Guillaume W. Bres 2022-01-04 13:39:01 +01:00 committed by Arnout Vandecappelle (Essensium/Mind)
parent a19b822239
commit 87f2b7004e
9 changed files with 88 additions and 0 deletions

View file

@ -1124,6 +1124,9 @@ F: package/liquid-dsp/
F: package/pixiewps/
F: package/python-pybind/
F: package/reaver/
F: support/testing/tests/package/br2-external/python-pybind
F: support/testing/tests/package/sample_python_pybind.py
F: support/testing/tests/package/test_python_pybind.py
N: Guo Ren <ren_guo@c-sky.com>
F: arch/Config.in.csky

View file

@ -0,0 +1 @@
source "$BR2_EXTERNAL_PYTHON_PYBIND_PATH/package/python-pybind-example/Config.in"

View file

@ -0,0 +1 @@
name: PYTHON_PYBIND

View file

@ -0,0 +1 @@
include $(sort $(wildcard $(BR2_EXTERNAL_PYTHON_PYBIND_PATH)/package/*/*.mk))

View file

@ -0,0 +1,6 @@
config BR2_PACKAGE_PYTHON_PYBIND_EXAMPLE
bool "python-pybind-example"
depends on BR2_PACKAGE_PYTHON3
select BR2_PACKAGE_PYTHON_PYBIND
help
This test creates a cpp macro later used on target in python

View file

@ -0,0 +1,16 @@
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add (int i, int j) {
return i + j;
}
PYBIND11_MODULE (example, m) {
// optional module description
m.doc() = "pybind11 example plugin";
// test a module method
m.def("add", &add, "example::add adds two integer numbers");
// test a module attribute
py::object hello = py::cast("Hello World");
m.attr("says") = hello;
}

View file

@ -0,0 +1,41 @@
################################################################################
#
# python-pybind-example
#
################################################################################
# this builds a C++ macro "add(a,b)"
# that we expose to host-python with a custom install
# and that the python test script will later use
PYTHON_PYBIND_EXAMPLE_DEPENDENCIES = python-pybind
PYTHON_PYBIND_EXAMPLE_PYBIND_INCLUDE = \
$(shell $(HOST_DIR)/usr/bin/python3 -c 'import pybind11; print(pybind11.get_include())')
PYTHON_PYBIND_EXAMPLE_CXX_FLAGS = \
$(TARGET_CXXFLAGS) \
-Wall -shared -std=c++11 -fPIC \
-I$(PYTHON_PYBIND_EXAMPLE_PYBIND_INCLUDE) \
$(shell $(STAGING_DIR)/usr/bin/python3-config --includes --libs --ldflags)
# .so to be installed must have exact suffix
# otherwise import() in python will not work
HOST_LIB_BINARY_SUFFIX = \
$(shell $(STAGING_DIR)/usr/bin/python3-config --extension-suffix)
define PYTHON_PYBIND_EXAMPLE_BUILD_CMDS
if [ -z "$(PYTHON_PYBIND_EXAMPLE_PYBIND_INCLUDE)" ]; then \
echo "pybind11.get_include() returned empty"; \
exit 1; \
fi
$(TARGET_CXX) $(PYTHON_PYBIND_EXAMPLE_CXX_FLAGS) \
$(PYTHON_PYBIND_EXAMPLE_PKGDIR)/example.cpp \
-o $(@D)/example$(HOST_LIB_BINARY_SUFFIX)
endef
define PYTHON_PYBIND_EXAMPLE_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 755 $(@D)/example$(HOST_LIB_BINARY_SUFFIX) \
$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/example$(HOST_LIB_BINARY_SUFFIX)
endef
$(eval $(generic-package))

View file

@ -0,0 +1,4 @@
#!/usr/bin/env python
import example
print(example.add(1, 2))
print(example.says)

View file

@ -0,0 +1,15 @@
import os
import infra
import subprocess
from tests.package.test_python import TestPythonPackageBase
class TestPythonPybind (TestPythonPackageBase):
__test__ = True
config = TestPythonPackageBase.config + \
"""
BR2_PACKAGE_PYTHON3=y
BR2_PACKAGE_PYTHON_PYBIND_EXAMPLE=y
"""
sample_scripts = ["tests/package/sample_python_pybind.py"]
# ship examples macro & installs it to host
br2_external = [infra.filepath("tests/package/br2-external/python-pybind")]