Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak Python bindings to create standalone sdist package #2

Closed
wants to merge 3 commits into from

Conversation

Gadgetoid
Copy link
Owner

@Gadgetoid Gadgetoid commented Sep 29, 2023

⚠️ Replaced by #3


This changeset vendors the gpiod library into the Python package.

This works by symlinking the lib and include directories up to the parent module, and updating MANIFEST.in to include the source files.

If "USE_SYSTEM_GPIOD=1" is not specified then the gpiod._ext C Extension is amended to include all of the C sources for gpiod, so it can be built as a standalone module without depending upon a shared distro library.

Why?

So that it can produce an sdist that is installable irrespective of the availability or version of a distro-supplied libgpiod. This prevents a libgpiod pypi package install balking because the distro libgpiod is outdated or otherwise incompatible. This happens with the currently available libgpiod on pypi.

This also ensures that libgpiod can be installed via pypi into an isolated virtual environment, specified as a dependency for Python packages and allow Python developers to target the newest API version.

Fallback to system libgpiod

Installing from an sdist with a "USE_SYSTEM_GPIOD=1" environment variable will drop the vendored library in favour of the system, however the system library must be compatible with the bindings.

Testing

This package should, in theory, work on any platform with Python >= 3.10.0 and GPIO character device support.

To see if you have any supported devices:

ls /dev/gpiochip*

Next, make sure you've set yourself up a venv, activate it and pip install --upgrade pip wheel for a recent build environment, eg:

python3 -m venv test-gpiod
source test-gpiod/bin/activate
pip install --upgrade pip wheel

You'll also need to sudo apt install python3-dev.

Then:

git clone https://github.com/Gadgetoid/libgpiod/ -b python-bindings
cd libgpiod/bindings/python
python3 setup.py sdist
pip install dist/libgpiod-2.0.1.tar.gz

⚠️ Make sure you don't try to import gpiod or run the below from the libgpiod/bindings/python directory.

Finally, the following test script should toggle line 15 1000 times and report how long it took-

import gpiod
import time

CONSUMER = "Benchmark"
LINE = 15

chip = gpiod.Chip("/dev/gpiochip4")

lines = chip.request_lines(consumer=CONSUMER, config={
    LINE: gpiod.LineSettings(
        direction=gpiod.line.Direction.OUTPUT,
        output_value=gpiod.line.Value.INACTIVE
    ) 
})

t_start = time.time()

n = 1000

for x in range(n):
    lines.set_value(LINE, gpiod.line.Value.ACTIVE)
    lines.set_value(LINE, gpiod.line.Value.INACTIVE)

t_end = time.time()

print(f"Toggling {n} times took: {(t_end - t_start) * 1000:0.4f}ms")

@Gadgetoid
Copy link
Owner Author

Gadgetoid commented Sep 29, 2023

On my Raspbian Buster Pi 4 1.1, with Python 3.7.3, importing this package produces the following error:

>>> import gpiod
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/libgpiod/lib/python3.7/site-packages/gpiod/__init__.py", line 10, in <module>
    from . import _ext
ImportError: /home/pi/libgpiod/lib/python3.7/site-packages/gpiod/_ext.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: PyModule_AddObjectRef

This is used in:

gpiod/ext/module.c:	ret = PyModule_AddObjectRef(module, "__all__", all);

Docs say "Part of the Stable ABI since version 3.10." So this package would have to target Python >= 3.10 by adding:

python_requires='>=3.10.0'

To setup.py.

SO that it fails early with:

libgpiod requires Python '>=3.10.0' but the running Python is 3.7.3

Build gpiod into Python module.

Optional environment var USE_SYSTEM_GPIO=1 to
generate a module that depends upon system gpiod.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
Add pyproject.toml to prevent spurious deprecation warnings from pip.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
Required minimum version for PyModule_AddType helper.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant