From: Phil Howard <phil@gadgetoid.com>
To: Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Kent Gibson <warthog618@gmail.com>,
Bartosz Golaszewski <brgl@bgdev.pl>
Cc: linux-gpio@vger.kernel.org, Phil Howard <phil@gadgetoid.com>
Subject: [libgpiod][PATCH v3 1/1] bindings: python: optionally include module in sdist
Date: Fri, 13 Oct 2023 12:28:12 +0100 [thread overview]
Message-ID: <20231013112812.148021-2-phil@gadgetoid.com> (raw)
In-Reply-To: <20231013112812.148021-1-phil@gadgetoid.com>
Build libgpiod into Python module for build_ext or bdist_wheel.
Include libgpiod source in sdist so that the Python module
can be built from source by end users, even with a missing
or mismatched system libgpiod.
Add optional environment variable "LINK_SYSTEM_LIBGPIOD=1" to
generate a module via build_ext or bdist_wheel that links
against system libgpiod.
Update build to pass "GPIOD_VERSION_STR" as an environment
variable when calling setup.py. This is saved to
"gpiod-version-str.txt" and included in the sdist for
standalone builds.
The old make/make install behaviour is preserved by
supplying "LINK_SYSTEM_LIBGPIOD=1" and an additional sdist
package is built and saved into dist/ for upload to pypi.
Signed-off-by: Phil Howard <phil@gadgetoid.com>
---
bindings/python/MANIFEST.in | 5 ++
bindings/python/Makefile.am | 5 ++
bindings/python/setup.py | 107 ++++++++++++++++++++++++++++++------
3 files changed, 101 insertions(+), 16 deletions(-)
diff --git a/bindings/python/MANIFEST.in b/bindings/python/MANIFEST.in
index c7124d4..acf9391 100644
--- a/bindings/python/MANIFEST.in
+++ b/bindings/python/MANIFEST.in
@@ -2,6 +2,7 @@
# SPDX-FileCopyrightText: 2023 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
include setup.py
+include gpiod-version-str.txt
recursive-include gpiod *.py
recursive-include tests *.py
@@ -11,3 +12,7 @@ recursive-include gpiod/ext *.h
recursive-include tests/gpiosim *.c
recursive-include tests/procname *.c
+
+recursive-include lib *.c
+recursive-include lib *.h
+recursive-include include *.h
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
index 079ceb1..fda8f94 100644
--- a/bindings/python/Makefile.am
+++ b/bindings/python/Makefile.am
@@ -12,10 +12,15 @@ BUILD_TESTS = 1
endif
all-local:
+ GPIOD_VERSION_STR=$(VERSION_STR) \
GPIOD_WITH_TESTS=$(BUILD_TESTS) \
+ LINK_SYSTEM_LIBGPIOD=1 \
$(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/
+ GPIOD_VERSION_STR=$(VERSION_STR) \
+ $(PYTHON) setup.py sdist
+
install-exec-local:
GPIOD_WITH_TESTS= \
diff --git a/bindings/python/setup.py b/bindings/python/setup.py
index df10e18..878c38d 100644
--- a/bindings/python/setup.py
+++ b/bindings/python/setup.py
@@ -1,10 +1,43 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
-from os import environ, path
+from os import environ, path, unlink
from setuptools import setup, Extension, find_packages
from setuptools.command.build_ext import build_ext as orig_build_ext
-from shutil import rmtree
+from setuptools.command.sdist import sdist as orig_sdist
+from shutil import rmtree, copytree
+
+
+def get_gpiod_version_str():
+ try:
+ return environ["GPIOD_VERSION_STR"]
+ except KeyError:
+ return open("gpiod-version-str.txt", "r").read()
+
+
+def copy_libgpiod_files(func):
+ """
+ In order to include the lib and include directories in the sdist
+ we must temporarily copy them up into the python bindings directory.
+
+ If "./lib" exists we are building from an sdist package and will not
+ try to copy the files again.
+ """
+
+ def wrapper(self):
+ copy_src = not path.exists("./lib")
+ if copy_src:
+ gpiod_version_str = get_gpiod_version_str()
+ open("gpiod-version-str.txt", "w").write(gpiod_version_str)
+ copytree("../../lib", "./lib")
+ copytree("../../include", "./include")
+ func(self)
+ if copy_src:
+ unlink("gpiod-version-str.txt")
+ rmtree("./lib")
+ rmtree("./include")
+
+ return wrapper
class build_ext(orig_build_ext):
@@ -14,24 +47,69 @@ class build_ext(orig_build_ext):
were built (and possibly copied to the source directory if inplace is set).
"""
+ @copy_libgpiod_files
def run(self):
super().run()
rmtree(path.join(self.build_lib, "tests"), ignore_errors=True)
+class sdist(orig_sdist):
+ """
+ Wrap sdist so that we can copy the lib and include files into . where
+ MANIFEST.in will include them in the source package.
+ """
+
+ @copy_libgpiod_files
+ def run(self):
+ super().run()
+
+
+with open("gpiod/version.py", "r") as fd:
+ exec(fd.read())
+
+sources = [
+ # gpiod Python bindings
+ "gpiod/ext/chip.c",
+ "gpiod/ext/common.c",
+ "gpiod/ext/line-config.c",
+ "gpiod/ext/line-settings.c",
+ "gpiod/ext/module.c",
+ "gpiod/ext/request.c",
+]
+
+if environ.get("LINK_SYSTEM_LIBGPIOD") == "1":
+ libraries = ["gpiod"]
+ include_dirs = ["gpiod"]
+else:
+ sources += [
+ # gpiod library
+ "lib/chip.c",
+ "lib/chip-info.c",
+ "lib/edge-event.c",
+ "lib/info-event.c",
+ "lib/internal.c",
+ "lib/line-config.c",
+ "lib/line-info.c",
+ "lib/line-request.c",
+ "lib/line-settings.c",
+ "lib/misc.c",
+ "lib/request-config.c",
+ ]
+ libraries = []
+ include_dirs = ["include", "lib", "gpiod/ext"]
+
+
gpiod_ext = Extension(
"gpiod._ext",
- sources=[
- "gpiod/ext/chip.c",
- "gpiod/ext/common.c",
- "gpiod/ext/line-config.c",
- "gpiod/ext/line-settings.c",
- "gpiod/ext/module.c",
- "gpiod/ext/request.c",
- ],
+ libraries=libraries,
+ sources=sources,
define_macros=[("_GNU_SOURCE", "1")],
- libraries=["gpiod"],
- extra_compile_args=["-Wall", "-Wextra"],
+ include_dirs=include_dirs,
+ extra_compile_args=[
+ "-Wall",
+ "-Wextra",
+ '-DGPIOD_VERSION_STR="{}"'.format(get_gpiod_version_str()),
+ ],
)
gpiosim_ext = Extension(
@@ -54,15 +132,12 @@ if environ.get("GPIOD_WITH_TESTS") == "1":
extensions.append(gpiosim_ext)
extensions.append(procname_ext)
-with open("gpiod/version.py", "r") as fd:
- exec(fd.read())
-
setup(
name="libgpiod",
packages=find_packages(exclude=["tests", "tests.*"]),
python_requires=">=3.9.0",
ext_modules=extensions,
- cmdclass={"build_ext": build_ext},
+ cmdclass={"build_ext": build_ext, "sdist": sdist},
version=__version__,
author="Bartosz Golaszewski",
author_email="brgl@bgdev.pl",
--
2.34.1
next prev parent reply other threads:[~2023-10-13 11:28 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-13 11:28 [libgpiod][PATCH v3 0/1] bindings: python: optionally include module in sdist Phil Howard
2023-10-13 11:28 ` Phil Howard [this message]
2023-10-16 13:10 ` [libgpiod][PATCH v3 1/1] " Bartosz Golaszewski
2023-10-16 13:45 ` Phil Howard
2023-10-16 14:24 ` Bartosz Golaszewski
2023-10-16 14:41 ` Bartosz Golaszewski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231013112812.148021-2-phil@gadgetoid.com \
--to=phil@gadgetoid.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=brgl@bgdev.pl \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=warthog618@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).