[PATCH 4/5] Provide some Python bindings over dyn using SWIG.

* Makefile.am (SUBDIRS): Add swig. * config/pypath.m4: New symlink to ../../m4/pypath.m4. * config/swig.m4: New symlink to ../../m4/swig.m4. * configure.ac: Re-enable and update the configuration of SWIG and Python. * swig/, * swig/python/: New directories. * swig/dyn.i, * swig/run.mk, * swig/Makefile.am, * swig/python/config.py, * swig/python/milena.py, * swig/python/Makefile.am: New. * swig/run.in: New symlink to ../../swilena/run.in. * swig/python/ltihooks.py: New symlink to ../../../swilena/python/ltihooks.py. --- dynamic-use-of-static-c++/ChangeLog | 23 ++++ dynamic-use-of-static-c++/Makefile.am | 2 +- dynamic-use-of-static-c++/config/pypath.m4 | 1 + dynamic-use-of-static-c++/config/swig.m4 | 1 + dynamic-use-of-static-c++/configure.ac | 86 ++++++++++----- dynamic-use-of-static-c++/src/data.hh | 3 + dynamic-use-of-static-c++/{ => swig}/Makefile.am | 8 +- dynamic-use-of-static-c++/swig/dyn.i | 81 ++++++++++++++ dynamic-use-of-static-c++/swig/python/Makefile.am | 116 ++++++++++++++++++++ .../{Makefile.am => swig/python/config.py} | 15 ++- dynamic-use-of-static-c++/swig/python/ltihooks.py | 1 + dynamic-use-of-static-c++/swig/python/milena.py | 51 +++++++++ dynamic-use-of-static-c++/swig/run.in | 1 + .../{Makefile.am => swig/run.mk} | 11 +- 14 files changed, 358 insertions(+), 42 deletions(-) create mode 120000 dynamic-use-of-static-c++/config/pypath.m4 create mode 120000 dynamic-use-of-static-c++/config/swig.m4 copy dynamic-use-of-static-c++/{ => swig}/Makefile.am (76%) create mode 100644 dynamic-use-of-static-c++/swig/dyn.i create mode 100644 dynamic-use-of-static-c++/swig/python/Makefile.am copy dynamic-use-of-static-c++/{Makefile.am => swig/python/config.py} (60%) create mode 120000 dynamic-use-of-static-c++/swig/python/ltihooks.py create mode 100644 dynamic-use-of-static-c++/swig/python/milena.py create mode 120000 dynamic-use-of-static-c++/swig/run.in copy dynamic-use-of-static-c++/{Makefile.am => swig/run.mk} (72%) diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog index baa9f2f..fef105e 100644 --- a/dynamic-use-of-static-c++/ChangeLog +++ b/dynamic-use-of-static-c++/ChangeLog @@ -1,3 +1,26 @@ +2009-10-29 Roland Levillain <roland@lrde.epita.fr> + + Provide some Python bindings over dyn using SWIG. + + * Makefile.am (SUBDIRS): Add swig. + * config/pypath.m4: New symlink to ../../m4/pypath.m4. + * config/swig.m4: New symlink to ../../m4/swig.m4. + * configure.ac: Re-enable and update the configuration of SWIG and + Python. + * swig/, + * swig/python/: + New directories. + * swig/dyn.i, + * swig/run.mk, + * swig/Makefile.am, + * swig/python/config.py, + * swig/python/milena.py, + * swig/python/Makefile.am: + New. + * swig/run.in: New symlink to ../../swilena/run.in. + * swig/python/ltihooks.py: New symlink to + ../../../swilena/python/ltihooks.py. + 2009-10-27 Roland Levillain <roland@lrde.epita.fr> Have configure find libiberty and stop depending on compiled libaries. diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/Makefile.am index a769c69..737a9f9 100644 --- a/dynamic-use-of-static-c++/Makefile.am +++ b/dynamic-use-of-static-c++/Makefile.am @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with Olena. If not, see <http://www.gnu.org/licenses/>. -SUBDIRS = libltdl libmd5 bin src config data test +SUBDIRS = libltdl libmd5 bin src config data test swig ACLOCAL_AMFLAGS = -I config -I libltdl diff --git a/dynamic-use-of-static-c++/config/pypath.m4 b/dynamic-use-of-static-c++/config/pypath.m4 new file mode 120000 index 0000000..6e4faa9 --- /dev/null +++ b/dynamic-use-of-static-c++/config/pypath.m4 @@ -0,0 +1 @@ +../../m4/pypath.m4 \ No newline at end of file diff --git a/dynamic-use-of-static-c++/config/swig.m4 b/dynamic-use-of-static-c++/config/swig.m4 new file mode 120000 index 0000000..c45fb81 --- /dev/null +++ b/dynamic-use-of-static-c++/config/swig.m4 @@ -0,0 +1 @@ +../../m4/swig.m4 \ No newline at end of file diff --git a/dynamic-use-of-static-c++/configure.ac b/dynamic-use-of-static-c++/configure.ac index 09e97a3..2bbb19c 100644 --- a/dynamic-use-of-static-c++/configure.ac +++ b/dynamic-use-of-static-c++/configure.ac @@ -102,34 +102,64 @@ DYN_LIBIBERTY BOOST_FILESYSTEM BOOST_STRING_ALGO -dnl ## ------ ## -dnl ## Swig. ## -dnl ## ------ ## - -dnl AC_ARG_WITH([swig], - dnl [AC_HELP_STRING([--with-swig], - dnl [require Swig modules (defaults to auto)])], - dnl [], - dnl [with_swig=auto]) - -dnl if test x$with_swig != xno; then - dnl has_swig=yes - - dnl # Check for python and swig - - dnl AC_PROG_SWIG([1.3.24]) - dnl if (eval "$SWIG -version") >/dev/null 2>&1; then :; else - dnl has_swig=no - dnl fi - - dnl case $with_swig:$has_swig in - dnl yes:no) - dnl AC_MSG_ERROR([SWIG 1.3.24 is required. - dnl Use `--without-swig' to disable SWIG modules.]);; - dnl esac -dnl fi - -dnl AC_MSG_RESULT([$has_swig]) +## ------ ## +## Swig. ## +## ------ ## + +# FIXME: Unify the Autoconf machinery w.r.t. SWIG and Python with Olena's. + +AC_ARG_WITH([swig], + [AC_HELP_STRING([--with-swig], + [require Swig modules (defaults to auto)])], + [], + [with_swig=auto]) + +if test x$with_swig != xno; then + has_swig=yes + + # Check for Python. + AM_PATH_PYTHON([2.5]) + adl_CHECK_PYTHON + + # Check for Python and SWIG. + save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS -I$PYTHONINC" + AC_CHECK_HEADERS([Python.h], + [python_headers=yes], + [python_headers=no]) + + if test x$python_headers = xno; then + oln_has_swig=no + if test x$with_swig = xyes; then + AC_MSG_ERROR( + [Python.h is required to build SWIG modules. + Add `-I python_include_path' to `CPPFLAGS' + or `--without-swig' to disable SWIG modules.]) + fi + fi + + CPPFLAGS=$save_CPPFLAGS + + AC_PROG_SWIG([1.3.36]) + if (eval "$SWIG -version") >/dev/null 2>&1; then :; else + has_swig=no + fi + + case $with_swig:$has_swig in + yes:no) + AC_MSG_ERROR([SWIG 1.3.36 is required. + Use `--without-swig' to disable SWIG modules.]);; + esac +fi + +AC_MSG_RESULT([$has_swig]) + +AC_CONFIG_FILES([swig/Makefile + swig/python/Makefile]) + +AC_CONFIG_FILES([swig/run], [chmod +x swig/run]) + + # FIXME: Doesn't Autoconf provide something like abs_top_srcdir? my_abs_srcdir=`cd $srcdir && pwd` diff --git a/dynamic-use-of-static-c++/src/data.hh b/dynamic-use-of-static-c++/src/data.hh index f0e1812..812c3cd 100644 --- a/dynamic-use-of-static-c++/src/data.hh +++ b/dynamic-use-of-static-c++/src/data.hh @@ -338,6 +338,9 @@ namespace dyn { data() : proxy_(nil_proxy) {} + /* FIXME: What's the purpose of the second argument? I (Roland) + presume it serve as a desambiguition mechanism w.r.t to ctors + `data<T>(T&)' and `data<T>(const T&)'. If so, document it. */ data(abstract_data* proxy, proxy_tag*) : all_methods(), proxy_(proxy) {} template <class T> diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/Makefile.am similarity index 76% copy from dynamic-use-of-static-c++/Makefile.am copy to dynamic-use-of-static-c++/swig/Makefile.am index a769c69..2d894af 100644 --- a/dynamic-use-of-static-c++/Makefile.am +++ b/dynamic-use-of-static-c++/swig/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE). +# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE). # # This file is part of Olena. # @@ -14,8 +14,8 @@ # You should have received a copy of the GNU General Public License # along with Olena. If not, see <http://www.gnu.org/licenses/>. -SUBDIRS = libltdl libmd5 bin src config data test +SUBDIRS = python -ACLOCAL_AMFLAGS = -I config -I libltdl +EXTRA_DIST = dyn.i -EXTRA_DIST = bootstrap +check_SCRIPTS = run diff --git a/dynamic-use-of-static-c++/swig/dyn.i b/dynamic-use-of-static-c++/swig/dyn.i new file mode 100644 index 0000000..eaeacdf --- /dev/null +++ b/dynamic-use-of-static-c++/swig/dyn.i @@ -0,0 +1,81 @@ +// -*- C++ -*- +// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +/// \file +/// \brief A wrapper of libdyn. + +%module dyn + +%include std_string.i + +%{ +#include "dyn-all.hh" +%} + +// Ignore global objects causing trouble. +%ignore dyn::logger; +%ignore dyn::internal::operator_push; +%ignore dyn::internal::operator_pop; +%ignore dyn::internal::operator_incr; +%ignore dyn::internal::operator_decr; +%ignore dyn::internal::operator_plus; +%ignore dyn::internal::operator_star; +%ignore dyn::internal::operator_equal; +%ignore dyn::internal::operator_not_equal; +%ignore dyn::internal::operator_square_brackets; + +%include "dyn-all.hh"; + +%inline %{ + /* The natural, single-argument ctors of dyn::data manipulate the + encapulsated by reference, which is wrong when these data are of + builtin types of the target language (e.g., Pythons' `int's), + because we have no control on them and they can vanish at any + moment. + + To prevent this, provide construction helpers creating dyn::data + objects manipulating data by value (copy). */ + template <typename T> + dyn::data make_data_by_cpy(T i) + { + dyn::proxy_tag* dummy = 0; + // This dummy pointer passed as second argument is required to + // call the right ctor. + dyn::data d(new dyn::data_proxy_by_cpy<T>(i), dummy); + return d; + } +%} + +// Instantiate make_data_by_cpy ctors for some types. +%template(integer) make_data_by_cpy<int>; +%template(string) make_data_by_cpy<std::string>; + +// Instantiate dyn::data explicit conversion routines for some types. +%extend dyn::data +{ + %template(convert_to_int) convert_to<int>; + %template(convert_to_string) convert_to<std::string>; +} diff --git a/dynamic-use-of-static-c++/swig/python/Makefile.am b/dynamic-use-of-static-c++/swig/python/Makefile.am new file mode 100644 index 0000000..81455f7 --- /dev/null +++ b/dynamic-use-of-static-c++/swig/python/Makefile.am @@ -0,0 +1,116 @@ +# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE). +# +# This file is part of Olena. +# +# Olena is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, version 2 of the License. +# +# Olena is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Olena. If not, see <http://www.gnu.org/licenses/>. + + +## ------------------ ## +## Generic material. ## +## ------------------ ## + +## FIXME: Factor as much as possible. See how we handled this in TC. + +## FIXME: Adjust. + +CLEANFILES = +AM_CPPFLAGS = -I$(PYTHONINC) -I$(top_builddir)/src -I$(top_srcdir)/src +## FIXME: Define an equivalent to Olena's TOOLS_CXXFLAGS? +## TOOLS_CXXFLAGS = @TOOLS_CXXFLAGS@ +## AM_CXXFLAGS = $(TOOLS_CXXFLAGS) +AM_SWIGFLAGS = -Wall -c++ -python -I$(top_builddir)/src -I$(top_srcdir)/src +# We build modules, not plain libs. +AM_LDFLAGS = -avoid-version -module -shared +AM_LIBADD = $(top_builddir)/src/libdyn.la # $(LIBLTDL) + +# Run Swig to create the C++ wrapper files, the Python interface +# files, and the dependency Makefile snippets. +# FIXME: `%'-style patterns rules are not portable. +%-wrap.cc %.py: $(top_srcdir)/swig/%.i + if $(SWIG) $(AM_SWIGFLAGS) $(SWIGFLAGS) -MD -MF "$(DEPDIR)/$*-wrap.Tcc" -o $@ $<; then \ + mv -f "$(DEPDIR)/$*-wrap.Tcc" "$(DEPDIR)/$*-wrap.Pcc";\ + else \ + rm -f "$(DEPDIR)/$*-wrap.Tcc"; exit 1;\ + fi + + +# ltihooks.py: Python import hooks that understand Libtool libraries. +python_PYTHON = ltihooks.py + +# config.py: Configuration values of the package. +EXTRA_DIST = config.py + + +## ----------------- ## +## Wrapped modules. ## +## ----------------- ## + +## FIXME: All of this should be generated. +## Don't forget to add a `deps-reset' target as in TC. + +## FIXME: Dependencies do not work as expected, e.g., touching +## mln/core/point.hh will not void point-wrap.cc, and Swig will not +## regen it (it will merely recompile _point2d.la). See how other +## projects people handle this. + +nodist_python_PYTHON = +pyexec_LTLIBRARIES = + +## dyn. +pyexec_LTLIBRARIES += _dyn.la +nodist__dyn_la_SOURCES = dyn-wrap.cc +_dyn_la_LIBADD = $(AM_LIBADD) +CLEANFILES += $(nodist__dyn_la_SOURCES) dyn.py dyn.py[co] +## Include the dependency files. Copied from Automake's generated +## case for C++. +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_dyn-wrap.Pcc@am__quote@ +nodist_python_PYTHON += dyn.py + + +## ------- ## +## Tests. ## +## ------- ## + +include $(top_srcdir)/swig/run.mk + +TESTS_ENVIRONMENT = \ + abs_top_srcdir="$(abs_top_srcdir)" \ + abs_top_builddir="$(abs_top_builddir)" \ + $(RUN) +# Ensure `run' is rebuilt before the tests are run. +$(TESTS): $(srcdir)/run.stamp +# The dependency is on `run.in' and not `run', since `run' is +# regenerated at distribution time, and voids the time stamps (which +# we don't want!). +EXTRA_DIST += $(srcdir)/run.stamp +$(srcdir)/run.stamp: $(RUN_IN) + @rm -f $@ + @rm -f $@.tmp + @touch $@.tmp + $(MAKE) $(AM_MAKEFLAGS) $(RUN) + @mv -f $@.tmp $@ + +# FIXME: We should not use the `.py' extension: it is not needed, and +# it prevents us from using the same name for both a module (wrapper) +# and a test. Alas, the script `run' expects a file name with an +# extension as argument. We could improve this by adding options such +# as `--python' to `run'. +TESTS = milena.py + +# FIXME: Is this really needed? +EXTRA_DIST += $(TESTS) + +clean-local: clean-repository +.PHONY: clean-repository +clean-repository: + -rm -rf repository diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/python/config.py similarity index 60% copy from dynamic-use-of-static-c++/Makefile.am copy to dynamic-use-of-static-c++/swig/python/config.py index a769c69..1594f5e 100644 --- a/dynamic-use-of-static-c++/Makefile.am +++ b/dynamic-use-of-static-c++/swig/python/config.py @@ -1,4 +1,6 @@ -# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE). +#! /usr/bin/env python + +# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) # # This file is part of Olena. # @@ -14,8 +16,13 @@ # You should have received a copy of the GNU General Public License # along with Olena. If not, see <http://www.gnu.org/licenses/>. -SUBDIRS = libltdl libmd5 bin src config data test +# \file +# \brief Configuration values of the package. + +# FIXME: We might want to turn this into a config.py.in file and +# generate it instead of getting variables from the environment. -ACLOCAL_AMFLAGS = -I config -I libltdl +import os -EXTRA_DIST = bootstrap +abs_top_srcdir = os.environ["abs_top_srcdir"] +abs_milena_dir = os.path.join(abs_top_srcdir, "..", "milena") diff --git a/dynamic-use-of-static-c++/swig/python/ltihooks.py b/dynamic-use-of-static-c++/swig/python/ltihooks.py new file mode 120000 index 0000000..11249fa --- /dev/null +++ b/dynamic-use-of-static-c++/swig/python/ltihooks.py @@ -0,0 +1 @@ +../../../swilena/python/ltihooks.py \ No newline at end of file diff --git a/dynamic-use-of-static-c++/swig/python/milena.py b/dynamic-use-of-static-c++/swig/python/milena.py new file mode 100644 index 0000000..85a1cfc --- /dev/null +++ b/dynamic-use-of-static-c++/swig/python/milena.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python + +# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +# +# This file is part of Olena. +# +# Olena is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, version 2 of the License. +# +# Olena is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Olena. If not, see <http://www.gnu.org/licenses/>. + +# \file +# \brief A Python version of test/test_olena.cc. + +import ltihooks + +import dyn +import config + +dyn.include_dir(config.abs_milena_dir) +dyn.include("mln/core/image/image2d.hh") +dyn.include("mln/data/fill.hh") +dyn.include("mln/debug/iota.hh") +dyn.include("mln/debug/println.hh") + +mk_image2d_int = dyn.ctor("mln::image2d<int>") +fill = dyn.fun("mln::data::fill") +iota = dyn.fun("mln::debug::iota") +println = dyn.fun("mln::debug::println") + +# We'd like to be able to write this: +# +# ima = mk_image2d_int(3, 3) +# +# but we just can't. `mk_image2d_int' only accept `dyn.data' as +# arguments, so we have to encapsulate integers in `dyn.data' objects +# using `dyn.integer' (likewise for strings with `dyn.string'). + +ima = mk_image2d_int(dyn.integer(3), dyn.integer(3)) + +fill(ima, dyn.integer(0)) +println(dyn.string("ima (before) ="), ima) +iota(ima) +println(dyn.string("ima (after) ="), ima) diff --git a/dynamic-use-of-static-c++/swig/run.in b/dynamic-use-of-static-c++/swig/run.in new file mode 120000 index 0000000..585aed6 --- /dev/null +++ b/dynamic-use-of-static-c++/swig/run.in @@ -0,0 +1 @@ +../../swilena/run.in \ No newline at end of file diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/run.mk similarity index 72% copy from dynamic-use-of-static-c++/Makefile.am copy to dynamic-use-of-static-c++/swig/run.mk index a769c69..24aaa09 100644 --- a/dynamic-use-of-static-c++/Makefile.am +++ b/dynamic-use-of-static-c++/swig/run.mk @@ -1,4 +1,4 @@ -# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE). +# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE). # # This file is part of Olena. # @@ -14,8 +14,9 @@ # You should have received a copy of the GNU General Public License # along with Olena. If not, see <http://www.gnu.org/licenses/>. -SUBDIRS = libltdl libmd5 bin src config data test +# A test/script wrapper. -ACLOCAL_AMFLAGS = -I config -I libltdl - -EXTRA_DIST = bootstrap +RUN = $(top_builddir)/swig/run +RUN_IN = $(top_srcdir)/swig/run.in +$(RUN): $(RUN_IN) + cd $(top_builddir)/swig && $(MAKE) $(AM_MAKEFLAGS) run -- 1.6.5
participants (1)
-
Roland Levillain