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`. Signed-off-by: Phil Howard <phil@xxxxxxxxxxxxx> --- bindings/python/Makefile.am | 25 +++++++---- bindings/python/build_tests.py | 79 ++++++++++++++++++++++++++++++++++ bindings/python/setup.py | 28 +----------- 3 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 bindings/python/build_tests.py diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am index 079ceb1..36fb66a 100644 --- a/bindings/python/Makefile.am +++ b/bindings/python/Makefile.am @@ -7,19 +7,28 @@ EXTRA_DIST = \ if WITH_TESTS -BUILD_TESTS = 1 +python-tests: + TOP_SRCDIR=$(abs_top_builddir) \ + TOP_BUILDDIR=$(abs_top_builddir) \ + $(PYTHON) build_tests.py + +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 + +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 diff --git a/bindings/python/build_tests.py b/bindings/python/build_tests.py new file mode 100644 index 0000000..b984307 --- /dev/null +++ b/bindings/python/build_tests.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2023 Phil Howard <phil@xxxxxxxxxxxxx> + +""" +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 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()) + + +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], + "version": __version__, + "platforms": ["linux"], + } +) + +try: + from setuptools.logging import configure + + configure() +except ImportError: + from distutils.log import set_verbosity, DEBUG + + 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() diff --git a/bindings/python/setup.py b/bindings/python/setup.py index e8704d5..9607a28 100644 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -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", -- 2.34.1