@@ -7,19 +7,36 @@ EXTRA_DIST = \
if WITH_TESTS
-BUILD_TESTS = 1
+python-tests:
+ TOP_SRCDIR=$(abs_top_builddir) \
+ TOP_BUILDDIR=$(abs_top_builddir) \
+ $(PYTHON) build_tests.py
+
+python-tests-run:
+ PYTHONPATH=$(abs_top_srcdir)/bindings/python
+ LD_LIBRARY_PATH=$(abs_top_builddir)/lib/.libs/:\
+$(abs_top_builddir)/tests/gpiosim/.libs/ \
+ python3 -B -m tests
+
+else
+
+python-tests:
endif
-all-local:
- GPIOD_WITH_TESTS=$(BUILD_TESTS) \
- $(PYTHON) setup.py build_ext --inplace \
- --include-dirs=$(top_srcdir)/include/:$(top_srcdir)/tests/gpiosim/ \
- --library-dirs=$(top_builddir)/lib/.libs/:$(top_srcdir)/tests/gpiosim/.libs/
+clean-local:
+ rm -rf dist
+ rm -f gpiod/_ext.*.so
+ rm -f tests/*/_ext.*.so
+
+all-local: python-tests
+ CFLAGS="-I$(abs_top_srcdir)/include/ -I$(abs_top_srcdir)/tests/gpiosim \
+ -L$(abs_top_builddir)/lib/.libs/ -L$(abs_top_builddir)/tests/gpiosim/.libs/" \
+ $(PYTHON) -m build
install-exec-local:
- GPIOD_WITH_TESTS= \
- $(PYTHON) setup.py install --prefix=$(DESTDIR)$(prefix)
+ $(PYTHON) -m pip install dist/*.whl \
+ --prefix=$(DESTDIR)$(prefix)
SUBDIRS = gpiod
new file mode 100644
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SPDX-FileCopyrightText: 2023 Phil Howard <phil@gadgetoid.com>
+
+"""
+Bring up just enough of setuptools/distutils in order to build the gpiod
+test module C extensions.
+
+Set "build_temp" and "build_lib" so that our source directory is not
+polluted with artefacts in build/
+
+Builds:
+
+ tests/gpiosim/_ext.<target>.so
+ tests/procname/_ext.<target>.so
+
+"""
+
+import glob
+import tempfile
+from os import getenv, path
+
+from setuptools import Distribution, Extension
+from setuptools.command.build_ext import build_ext
+
+TOP_SRCDIR = getenv("TOP_SRCDIR", "../../")
+TOP_BUILDDIR = getenv("TOP_BUILDDIR", "../../")
+
+# __version__
+with open("gpiod/version.py", "r") as fd:
+ exec(fd.read())
+
+# The tests are run in-place with PYTHONPATH set to bindings/python
+# so we need the gpiod extension module too.
+gpiod_ext = Extension(
+ "gpiod._ext",
+ sources=glob.glob("gpiod/ext/*.c"),
+ define_macros=[("_GNU_SOURCE", "1")],
+ libraries=["gpiod"],
+ extra_compile_args=["-Wall", "-Wextra"],
+ include_dirs=[
+ path.join(TOP_SRCDIR, "include"),
+ ],
+ library_dirs=[
+ path.join(TOP_BUILDDIR, "lib/.libs"),
+ ],
+)
+
+gpiosim_ext = Extension(
+ "tests.gpiosim._ext",
+ sources=["tests/gpiosim/ext.c"],
+ define_macros=[("_GNU_SOURCE", "1")],
+ libraries=["gpiosim"],
+ extra_compile_args=["-Wall", "-Wextra"],
+ include_dirs=[
+ path.join(TOP_SRCDIR, "include"),
+ path.join(TOP_SRCDIR, "tests/gpiosim"),
+ ],
+ library_dirs=[
+ path.join(TOP_BUILDDIR, "lib/.libs"),
+ path.join(TOP_BUILDDIR, "tests/gpiosim/.libs"),
+ ],
+)
+
+procname_ext = Extension(
+ "tests.procname._ext",
+ sources=["tests/procname/ext.c"],
+ define_macros=[("_GNU_SOURCE", "1")],
+ extra_compile_args=["-Wall", "-Wextra"],
+)
+
+dist = Distribution(
+ {
+ "name": "gpiod",
+ "ext_modules": [gpiosim_ext, procname_ext, gpiod_ext],
+ "version": __version__,
+ "platforms": ["linux"],
+ }
+)
+
+try:
+ from setuptools.logging import configure
+
+ configure()
+except ImportError:
+ from distutils.log import DEBUG, set_verbosity
+
+ set_verbosity(DEBUG)
+
+with tempfile.TemporaryDirectory(prefix="libgpiod-") as temp_dir:
+ command = build_ext(dist)
+ command.inplace = True
+ command.build_temp = temp_dir
+ command.build_lib = temp_dir
+ command.finalize_options()
+ command.run()
@@ -13,7 +13,6 @@ from setuptools.errors import BaseError
LINK_SYSTEM_LIBGPIOD = getenv("LINK_SYSTEM_LIBGPIOD") == "1"
LIBGPIOD_MINIMUM_VERSION = "2.1"
LIBGPIOD_VERSION = getenv("LIBGPIOD_VERSION")
-GPIOD_WITH_TESTS = getenv("GPIOD_WITH_TESTS") == "1"
SRC_BASE_URL = "https://mirrors.edge.kernel.org/pub/software/libs/libgpiod/"
TAR_FILENAME = "libgpiod-{version}.tar.gz"
ASC_FILENAME = "sha256sums.asc"
@@ -189,11 +188,6 @@ class build_ext(orig_build_ext):
super().run()
- # We don't ever want the module tests directory in our package
- # since this might include gpiosim._ext or procname._ext from a
- # previous dirty build tree.
- rmtree(path.join(self.build_lib, "tests"), ignore_errors=True)
-
class sdist(orig_sdist):
"""
@@ -226,32 +220,12 @@ gpiod_ext = Extension(
extra_compile_args=["-Wall", "-Wextra"],
)
-gpiosim_ext = Extension(
- "tests.gpiosim._ext",
- sources=["tests/gpiosim/ext.c"],
- define_macros=[("_GNU_SOURCE", "1")],
- libraries=["gpiosim"],
- extra_compile_args=["-Wall", "-Wextra"],
-)
-
-procname_ext = Extension(
- "tests.procname._ext",
- sources=["tests/procname/ext.c"],
- define_macros=[("_GNU_SOURCE", "1")],
- extra_compile_args=["-Wall", "-Wextra"],
-)
-
-extensions = [gpiod_ext]
-if GPIOD_WITH_TESTS:
- extensions.append(gpiosim_ext)
- extensions.append(procname_ext)
-
setup(
name="gpiod",
url="https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git",
packages=find_packages(exclude=["tests", "tests.*"]),
python_requires=">=3.9.0",
- ext_modules=extensions,
+ ext_modules=[gpiod_ext],
cmdclass={"build_ext": build_ext, "sdist": sdist},
version=__version__,
author="Bartosz Golaszewski",
Move extension definitions and tooling for building tests into `build_tests.py` and update Makefile.am to call it with appropriate path prefixes. `build_tests.py` will perform a standalone build of the text extensions, keeping any build noise in a temporary directory and copying the final built modules automatically out to `tests/gpiosim` and `tests/procname`. Add "python-tests-run" to Makefile.am so it's clear how to run the tests. Add .so object files generated by build_test.py to Makefile.am's clean-local. Signed-off-by: Phil Howard <phil@gadgetoid.com> --- bindings/python/Makefile.am | 33 +++++++++--- bindings/python/build_tests.py | 95 ++++++++++++++++++++++++++++++++++ bindings/python/setup.py | 28 +--------- 3 files changed, 121 insertions(+), 35 deletions(-) create mode 100644 bindings/python/build_tests.py