freetype-devel libpng-devel zlib-devel \
libxml2-devel glib2-devel libdbi-devel \
perl-devel perl-ExtUtils-MakeMaker \
- python3-devel python3-setuptools \
+ python3-devel python3-setuptools python3-pip python3-wheel \
tcl-devel \
lua-devel \
ruby ruby-devel
run: |
set -e
# Install the distro rrdtool first to prove DB-level coexistence.
- # ruby is pulled in so the bundled ruby binding can be smoke-tested.
- dnf install -y rrdtool ruby
+ # ruby/python3 are pulled in so the bundled bindings can be smoke-tested.
+ dnf install -y rrdtool ruby python3
# Install our /opt package alongside it.
dnf install -y ./out/rrdtool-1-opt-${VERSION}-*.rpm
# Both packages must be in the rpm database at the same time.
test "$(command -v rrdtool)" = /opt/rrdtool/bin/rrdtool
# The relocated ruby binding must load via the RUBYLIB it sets.
ruby -e 'require "RRD"; puts "ruby binding OK"'
+ # The pip-installed python binding must import via the PYTHONPATH it
+ # sets, find librrd through the wheel's embedded RPATH, and run.
+ python3 -c 'import rrdtool; print("python binding OK:", rrdtool.__file__, "librrd", rrdtool.lib_version())'
# ---------------------------------------------------------------------------
# build-deb: per-distro container, builds a .deb via fpm from a staged
libcairo2-dev libpango1.0-dev libxml2-dev libglib2.0-dev libdbi-dev \
libfreetype6-dev libpng-dev zlib1g-dev \
libperl-dev \
- python3-dev python3-setuptools \
+ python3-dev python3-setuptools python3-pip python3-wheel \
tcl-dev \
lua5.4 liblua5.4-dev \
ruby ruby-dev rubygems-integration
run: |
set -e
# Install the distro rrdtool first to prove DB-level coexistence.
- # ruby is pulled in so the bundled ruby binding can be smoke-tested.
- apt-get install -y rrdtool ruby
+ # ruby/python3 are pulled in so the bundled bindings can be smoke-tested.
+ apt-get install -y rrdtool ruby python3
# Install our /opt package alongside it.
apt-get install -y ./out/rrdtool-1-opt_*.deb
# Both packages must be in the dpkg database at the same time.
test "$(command -v rrdtool)" = /opt/rrdtool/bin/rrdtool
# The relocated ruby binding must load via the RUBYLIB it sets.
ruby -e 'require "RRD"; puts "ruby binding OK"'
+ # The pip-installed python binding must import via the PYTHONPATH it
+ # sets, find librrd through the wheel's embedded RPATH, and run.
+ python3 -c 'import rrdtool; print("python binding OK:", rrdtool.__file__, "librrd", rrdtool.lib_version())'
# ---------------------------------------------------------------------------
# publish: only job that mutates the repo. Runs only after every build job
Bugfixes
--------
* The Linux .deb packages were missing the Lua language binding @oetiker
+* The Python binding is now installed with pip into a consistent, distribution-independent location @oetiker
Features
--------
SUBDIRS = $(SUB_tcl) $(SUB_lua)
if ENABLE_RPATH
-PYTHON_RPATH=--rpath=$(libdir)
+PYTHON_RPATH_LIBDIR=$(libdir)
PERL_RPATH=RPATH=$(libdir)
endif
&& ( cd ${builddir}/ruby \
&& $(MAKE) EPREFIX=$(DESTDIR)$(exec_prefix) $(RUBY_MAKE_OPTIONS) install ) \
|| true
- $(AM_V_GEN)test -d ${builddir}/python/build \
- && ( cd ${builddir}/python \
- && env BUILDLIBDIR=${abs_top_builddir}/src/.libs \
- $(PYTHON) ${abs_srcdir}/python/setup.py install \
- --skip-build --root=$(DESTDIR)/// --prefix=$(prefix) \
- --exec-prefix=$(exec_prefix)) \
+ $(AM_V_GEN)test -f ${builddir}/python/dist/*.whl \
+ && ( $(PYTHON) -m pip install --upgrade --no-index --no-deps \
+ --no-cache-dir --disable-pip-version-check \
+ --target=$(DESTDIR)$(libdir)/python3/site-packages \
+ ${builddir}/python/dist/*.whl ) \
|| true
# rules for building the ruby module
ABS_TOP_BUILDDIR=${abs_top_builddir} \
$(RUBY_MAKE_OPTIONS) RUBYARCHDIR= )
-# rules for building the python module
+# Build the python module as a wheel. It lands in ${builddir}/python/dist/
+# and is installed from there (via pip) by install-data-local. RRDTOOL_RPATH
+# tells setup.py to embed the install libdir as the extension's RPATH.
python:
-mkdir -p ${builddir}/$@
cd ${builddir}/$@ \
&& ( test -e rrdtoolmodule.c || ln -s ${abs_srcdir}/$@/rrdtoolmodule.c ) \
+ && rm -rf build dist rrdtool.egg-info \
&& env \
ABS_TOP_SRCDIR=${abs_top_srcdir} \
ABS_TOP_BUILDDIR=${abs_top_builddir} \
- $(PYTHON) ${abs_srcdir}/$@/setup.py build_ext $(PYTHON_RPATH) \
- && env \
- ABS_TOP_SRCDIR=${abs_top_srcdir} \
- ABS_TOP_BUILDDIR=${abs_top_builddir} \
- $(PYTHON) ${abs_srcdir}/$@/setup.py build
+ RRDTOOL_RPATH=$(PYTHON_RPATH_LIBDIR) \
+ $(PYTHON) ${abs_srcdir}/$@/setup.py bdist_wheel
# rules for building the perl module
perl-piped:
&& cd ${builddir}/ruby \
&& ( $(MAKE) clean || true ) \
&& rm -f Makefile )
- -rm -rf ${builddir}/python/build
+ -rm -rf ${builddir}/python/build ${builddir}/python/dist ${builddir}/python/rrdtool.egg-info
##END##
def main():
- module = Extension('rrdtool',
- sources=['rrdtoolmodule.c'],
- library_dirs=[os.path.join(TOP_BUILDDIR, 'src', '.libs')],
- include_dirs=[os.path.join(TOP_BUILDDIR, 'src'),
- os.path.join(TOP_SRCDIR, 'src')],
- libraries=['rrd'])
+ # rrdtool is built as part of the /opt/rrdtool bundle, where the extension
+ # must locate librrd at runtime through an embedded RPATH. The autotools
+ # build passes the install libdir via the RRDTOOL_RPATH environment
+ # variable. When this package is built by other means (a plain
+ # `pip install`), the variable is simply unset and no RPATH is embedded.
+ ext_kwargs = dict(
+ sources=['rrdtoolmodule.c'],
+ library_dirs=[os.path.join(TOP_BUILDDIR, 'src', '.libs')],
+ include_dirs=[os.path.join(TOP_BUILDDIR, 'src'),
+ os.path.join(TOP_SRCDIR, 'src')],
+ libraries=['rrd'],
+ )
+ rpath = os.environ.get('RRDTOOL_RPATH', '')
+ if rpath:
+ ext_kwargs['runtime_library_dirs'] = [rpath]
+
+ module = Extension('rrdtool', **ext_kwargs)
kwargs = dict(
name='rrdtool',
export PERL5LIB="$ROOT/lib/perl${PERL5LIB:+:$PERL5LIB}"
-PY_SP=$(ls -d "$ROOT"/lib*/python*/site-packages 2>/dev/null | head -1)
-[ -n "$PY_SP" ] && export PYTHONPATH="$PY_SP${PYTHONPATH:+:$PYTHONPATH}"
+# The python binding is installed (as a wheel, via `pip install --target`)
+# into a fixed, distro-independent directory by the rrdtool build — see
+# bindings/Makefile.am. No interpreter-scheme guessing needed.
+PY_SP="$ROOT/lib/python3/site-packages"
+[ -d "$PY_SP" ] && export PYTHONPATH="$PY_SP${PYTHONPATH:+:$PYTHONPATH}"
RB_ARCH=$(ls -d "$ROOT"/lib/ruby/*-* 2>/dev/null | head -1)
if [ -n "$RB_ARCH" ]; then
BuildRequires: libxml2-devel, glib2-devel, libdbi-devel
# binding build-deps
BuildRequires: perl-devel, perl-ExtUtils-MakeMaker
-BuildRequires: python3-devel
+BuildRequires: python3-devel, python3-setuptools, python3-pip, python3-wheel
BuildRequires: tcl-devel
BuildRequires: lua-devel
BuildRequires: ruby, ruby-devel