[lttng-dev] [PATCH babeltrace] Build Python bindings with distutils for consistent installs
Francis Deslauriers
francis.deslauriers at efficios.com
Mon Feb 20 16:47:36 UTC 2017
I noticed some shortcomings for this patch. I will send an updated
version shortly.
Francis
2017-02-17 15:59 GMT-05:00 Francis Deslauriers
<francis.deslauriers at efficios.com>:
> This patch changes the build system used to compile and install the
> Python Bindings. Distutils is used to find the right install directory.
> When the install directory generated from the install prefix is not in
> the Python search path (PYTHON_PATH), we print a warning explaining what
> can be done to include it.
> It uses Distutils which is part of the Python standard library.
>
> To be applied on top of 1.5.
>
> Signed-off-by: Francis Deslauriers <francis.deslauriers at efficios.com>
> ---
> .gitignore | 10 +++--
> bindings/python/Makefile.am | 39 +++++++++++++++-
> bindings/python/babeltrace/Makefile.am | 31 -------------
> bindings/python/babeltrace/__init__.py.in | 25 +++++++++++
> bindings/python/setup.py.in | 75 +++++++++++++++++++++++++++++++
> configure.ac | 14 +++---
> m4/python_modules.m4 | 23 ----------
> 7 files changed, 153 insertions(+), 64 deletions(-)
> delete mode 100644 bindings/python/babeltrace/Makefile.am
> create mode 100644 bindings/python/babeltrace/__init__.py.in
> create mode 100644 bindings/python/setup.py.in
> delete mode 100644 m4/python_modules.m4
>
> diff --git a/.gitignore b/.gitignore
> index a7c9e3c..9259b6f 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -47,8 +47,12 @@ converter/babeltrace-log
> core
> formats/ctf/metadata/ctf-parser.output
> stamp-h1
> -bindings/python/babeltrace.i
> -bindings/python/babeltrace.py
> -bindings/python/babeltrace_wrap.c
> +bindings/python/setup.py
> +bindings/python/installed_files.txt
> +bindings/python/build
> +bindings/python/babeltrace/__init__.py
> +bindings/python/babeltrace/babeltrace.i
> +bindings/python/babeltrace/babeltrace.py
> +bindings/python/babeltrace/babeltrace_wrap.c
> babeltrace.pc
> babeltrace-ctf.pc
> diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
> index d6b3648..ab75a3a 100644
> --- a/bindings/python/Makefile.am
> +++ b/bindings/python/Makefile.am
> @@ -1,3 +1,40 @@
> if USE_PYTHON
> -SUBDIRS = babeltrace
> +
> +SUBDIRS = .
> +
> +AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I$(srcdir)/babeltrace/
> +
> +# Since the shared object used by the python bindings is not built with libtool
> +# we need to manually set the `rpath` during linkage
> +AM_LDFLAGS=-L$(top_builddir)/formats/ctf/.libs -L$(top_builddir)/lib/.libs -Wl,-rpath,$(prefix)/lib
> +
> +INSTALLED_FILES=installed_files.txt
> +
> +all-local:
> + CC="$(CC)" CFLAGS="$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(GLIB_CFLAGS) $(AM_CFLAGS)" CPPFLAGS="$(AM_CPPFLAGS) $(CPPFLAGS)" LDFLAGS="$(AM_LDFLAGS) $(LDFLAGS)" $(PYTHON) $(builddir)/setup.py build_ext --swig-opts="-Wall -I$(top_srcdir)"
> + $(PYTHON) $(builddir)/setup.py build
> +
> +# This target installs the Python package and saves the path of all the
> +# installed files in the INSTALLED_FILES text file to be used during this
> +# uninstallation
> +install-exec-local:
> + @opts="--prefix=$(prefix) --verbose --record $(INSTALLED_FILES) --no-compile $(DISTSETUPOPTS)"; \
> + if [ "$(DESTDIR)" != "" ]; then \
> + opts="$$opts --root=$(DESTDIR)"; \
> + fi; \
> + $(PYTHON) $(builddir)/setup.py install $$opts;
> +
> +clean-local:
> + rm -rf $(builddir)/build
> +
> +# Distutils' setup.py does not include an uninstall target, we thus need to do it
> +# manually. We use the INSTALLED_FILES file produced during the install to
> +# clean up the install folder and delete the folder it self.
> +uninstall-local:
> + cat $(INSTALLED_FILES) | xargs rm -rf
> + cat $(INSTALLED_FILES) | $(GREP) "__init__.py" | xargs dirname | xargs rmdir
> + rm -f $(INSTALLED_FILES)
> +
> +CLEANFILES = babeltrace/babeltrace_wrap.c babeltrace/babeltrace.py
> +DISTCLEANFILES = babeltrace/__init__.py babeltrace/babeltrace.i
> endif
> diff --git a/bindings/python/babeltrace/Makefile.am b/bindings/python/babeltrace/Makefile.am
> deleted file mode 100644
> index 11dcdf0..0000000
> --- a/bindings/python/babeltrace/Makefile.am
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -babeltrace.i: babeltrace.i.in
> - sed "s/BABELTRACE_VERSION_STR/Babeltrace $(PACKAGE_VERSION)/g" < \
> - $(top_srcdir)/bindings/python/babeltrace/babeltrace.i.in > \
> - $(top_builddir)/bindings/python/babeltrace/babeltrace.i
> -
> -AM_CFLAGS = $(PYTHON_INCLUDE) -I$(top_srcdir)/include/ \
> - -I$(top_srcdir)/bindings/python/babeltrace
> -
> -EXTRA_DIST = babeltrace.i.in
> -nodist_python_PYTHON = babeltrace.py
> -pyexec_LTLIBRARIES = _babeltrace.la
> -
> -MAINTAINERCLEANFILES = babeltrace_wrap.c babeltrace.py
> -
> -nodist__babeltrace_la_SOURCES = babeltrace_wrap.c
> -_babeltrace_la_SOURCES = python-complements.h python-complements.c
> -_babeltrace_la_LDFLAGS = -module
> -
> -_babeltrace_la_CFLAGS = $(GLIB_CFLAGS) $(AM_CFLAGS)
> -
> -_babeltrace_la_LIBS = $(GLIB_LIBS)
> -
> -_babeltrace_la_LIBADD = $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
> - $(top_builddir)/formats/ctf-text/libbabeltrace-ctf-text.la
> -
> -# SWIG 'warning md variable unused' fixed after SWIG build:
> -babeltrace_wrap.c: babeltrace.i
> - $(SWIG) -python -Wall -I. -I$(top_srcdir)/include \
> - $(top_builddir)/bindings/python/babeltrace/babeltrace.i
> -
> -CLEANFILES = babeltrace.i babeltrace.py babeltrace_wrap.c
> diff --git a/bindings/python/babeltrace/__init__.py.in b/bindings/python/babeltrace/__init__.py.in
> new file mode 100644
> index 0000000..eb1e76a
> --- /dev/null
> +++ b/bindings/python/babeltrace/__init__.py.in
> @@ -0,0 +1,25 @@
> +# The MIT License (MIT)
> +#
> +# Copyright (C) 2017 - Francis Deslauriers <francis.deslauriers at efficios.com>
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a copy
> +# of this software and associated documentation files (the "Software"), to deal
> +# in the Software without restriction, including without limitation the rights
> +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> +# copies of the Software, and to permit persons to whom the Software is
> +# furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice shall be included in
> +# all copies or substantial portions of the Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> +# THE SOFTWARE.
> +
> +from .babeltrace import *
> +
> +__version__ = '@PACKAGE_VERSION@'
> diff --git a/bindings/python/setup.py.in b/bindings/python/setup.py.in
> new file mode 100644
> index 0000000..7d11cca
> --- /dev/null
> +++ b/bindings/python/setup.py.in
> @@ -0,0 +1,75 @@
> +# The MIT License (MIT)
> +#
> +# Copyright (C) 2017 - Francis Deslauriers <francis.deslauriers at efficios.com>
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a copy
> +# of this software and associated documentation files (the "Software"), to deal
> +# in the Software without restriction, including without limitation the rights
> +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> +# copies of the Software, and to permit persons to whom the Software is
> +# furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice shall be included in
> +# all copies or substantial portions of the Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> +# THE SOFTWARE.
> +
> +import sys
> +
> +from distutils.core import setup, Extension
> +
> +PY_PATH_WARN_MSG= """
> +-------------------------------------WARNING------------------------------------
> +The install directory used:\n ({})\nis not included in your PYTHON_PATH.
> +
> +To add this directory to your Python search path permanently you can add the
> +following command to your .bashrc/.zshrc:
> + export PYTHONPATH="${{PYTHONPATH}}:{}"
> +--------------------------------------------------------------------------------
> +"""
> +
> +def main():
> + babeltrace_ext = Extension('babeltrace/_babeltrace',
> + sources=['babeltrace/babeltrace.i','babeltrace/python-complements.c'],
> + libraries=['babeltrace', 'babeltrace-ctf'],)
> +
> + dist = setup(name='babeltrace',
> + version='@PACKAGE_VERSION@',
> + description='Babeltrace Python Bindings',
> + packages=['babeltrace'],
> + package_dir={'babeltrace': 'babeltrace'},
> + options={'build': {'build_base': 'build'}},
> + url='http://diamon.org/babeltrace',
> + ext_modules=[babeltrace_ext],
> + license='MIT',
> + classifiers=[
> + 'Development Status :: 5 - Production/Stable',
> + 'Intended Audience :: Developers',
> + 'License :: OSI Approved :: The MIT License',
> + 'Programming Language :: Python :: 3'
> + 'Topic :: System :: Logging',
> + ])
> +
> +# After the installation, we check that the install directory is included in
> +# the Python search path and we print a warning message when it's not.
> +# We need to do this because Python search path differs depending on the distro
> +# and some distros don't include any /usr/local/ in the search path. This is
> +# also useful for out-of-tree installs and tests.
> +# It's only relevant to make this check on the `install` command.
> +
> + if 'install' in dist.command_obj:
> + install_dir = dist.command_obj['install'].install_libbase
> + if install_dir not in sys.path:
> + # We can't consider this an error because if affects every
> + # distro differently. We only warn the user that some
> + # extra configuration is needed to use the bindings
> + print(PY_PATH_WARN_MSG.format(install_dir, install_dir))
> +
> +if __name__ == "__main__":
> + main()
> diff --git a/configure.ac b/configure.ac
> index 56255d0..e7d98b9 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -235,11 +235,6 @@ if test "x${enable_python:-yes}" = xyes; then
> AX_PKG_SWIG($swig_version, [], [ AC_MSG_ERROR([SWIG $swig_version or newer is needed]) ])
> AM_PATH_PYTHON
>
> - AM_PATH_PYTHON_MODULES([PYTHON])
> - # pythondir is the path where extra modules are to be installed
> - pythondir=$PYTHON_PREFIX/$PYTHON_MODULES_PATH
> - # pyexecdir is the path that contains shared objects used by the extra modules
> - pyexecdir=$PYTHON_EXEC_PREFIX/$PYTHON_MODULES_PATH
> AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing python-config])
> AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])
> AS_IF([test -z "$PYTHON_INCLUDE"], [
> @@ -327,7 +322,9 @@ AC_CONFIG_FILES([
> include/Makefile
> bindings/Makefile
> bindings/python/Makefile
> - bindings/python/babeltrace/Makefile
> + bindings/python/setup.py
> + bindings/python/babeltrace/babeltrace.i
> + bindings/python/babeltrace/__init__.py
> tests/Makefile
> tests/bin/Makefile
> tests/bin/intersection/Makefile
> @@ -351,6 +348,11 @@ AC_CONFIG_FILES([tests/bin/intersection/test_intersection], [chmod +x tests/bin/
> AC_CONFIG_FILES([tests/bin/intersection/bt_python_helper.py])
> AC_CONFIG_FILES([tests/bin/test_packet_seq_num], [chmod +x tests/bin/test_packet_seq_num])
>
> +# Create link for Babeltrace complements files for out-of-tree builds
> +AC_CONFIG_LINKS([
> + bindings/python/babeltrace/python-complements.c:bindings/python/babeltrace/python-complements.c
> +])
> +
> AC_OUTPUT
>
> #
> diff --git a/m4/python_modules.m4 b/m4/python_modules.m4
> deleted file mode 100644
> index 132c4c2..0000000
> --- a/m4/python_modules.m4
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -# python_modules.m4 -- Get the Python modules install path
> -#
> -# Copyright (C) 2014 - Jérémie Galarneau <jeremie.galarneau at efficios.com>
> -#
> -# This file is free software; the Free Software Foundation gives
> -# unlimited permission to copy and/or distribute it, with or without
> -# modifications, as long as this notice is preserved.
> -
> -# While extra Python modules are generaly installed in the Python
> -# interpreter's "site-packages" directory, Debian prefers using the
> -# "dist-packages" nomenclature. This macro uses the interpreter
> -# designated by the PYTHON variable to check the interpreter's PATH
> -# and sets the PYTHON_MODULES_PATH by taking the prefix into account.
> -
> -# AM_PATH_PYTHON_MODULES(PYTHON)
> -# ---------------------------------------------------------------------------
> -AC_DEFUN([AM_PATH_PYTHON_MODULES],
> - [prog="import sys
> -for path in sys.path:
> - if path.endswith(\"-packages\"):
> - print(path[[path.find(\"/lib\"):]])
> - break"
> - PYTHON_MODULES_PATH=`${$1} -c "$prog"`])
> --
> 2.7.4
>
--
Francis Deslauriers
Software developer
EfficiOS inc.
More information about the lttng-dev
mailing list