
From: levill_r <levill_r@4aad255d-cdde-0310-9447-f3009e2ae8c0> * src/function_loader.cc (dyn::function_loader_t::cxx_compile): New method. * src/config.hh.in (DYN_DATADIR): New macro. * configure.ac (my_abs_builddir): New variable. (DYN_DATADIR): New (substituted) variable. git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@4662 4aad255d-cdde-0310-9447-f3009e2ae8c0 --- dynamic-use-of-static-c++/ChangeLog | 10 +++ dynamic-use-of-static-c++/configure.ac | 4 + dynamic-use-of-static-c++/src/config.hh.in | 1 + dynamic-use-of-static-c++/src/function_loader.cc | 81 ++++++++++++++++++++++ 4 files changed, 96 insertions(+), 0 deletions(-) diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog index b17fe73..c5493fb 100644 --- a/dynamic-use-of-static-c++/ChangeLog +++ b/dynamic-use-of-static-c++/ChangeLog @@ -1,5 +1,15 @@ 2009-10-22 Roland Levillain <roland@lrde.epita.fr> + Provide a C++ implementation of the compile-at-runtime routine. + + * src/function_loader.cc (dyn::function_loader_t::cxx_compile): + New method. + * src/config.hh.in (DYN_DATADIR): New macro. + * configure.ac (my_abs_builddir): New variable. + (DYN_DATADIR): New (substituted) variable. + +2009-10-22 Roland Levillain <roland@lrde.epita.fr> + Have libdyn depend on Boost Filesystem and Boost String Algorithms. * src/Makefile.am (libdyn_la_LIBADD): Add $(BOOST_FILESYSTEM_LIBS). diff --git a/dynamic-use-of-static-c++/configure.ac b/dynamic-use-of-static-c++/configure.ac index 9eea7df..fbaa31c 100644 --- a/dynamic-use-of-static-c++/configure.ac +++ b/dynamic-use-of-static-c++/configure.ac @@ -111,10 +111,14 @@ dnl AC_MSG_RESULT([$has_swig]) # FIXME: Doesn't Autoconf provide something like abs_top_srcdir? my_abs_srcdir=`cd $srcdir && pwd` +# FIXME: Likewise. +my_abs_builddir=`pwd` # FIXME: Remove me when function_loader will be pure C++ AC_SUBST([DYNDIR], [$my_abs_srcdir/src]) +AC_SUBST([DYN_DATADIR], [$my_abs_builddir/data]) + AC_SUBST([DYN_FIXTURES], [$my_abs_srcdir/test/fixtures]) # Absolute path to Milena. diff --git a/dynamic-use-of-static-c++/src/config.hh.in b/dynamic-use-of-static-c++/src/config.hh.in index 7dbbbb0..1327cf4 100644 --- a/dynamic-use-of-static-c++/src/config.hh.in +++ b/dynamic-use-of-static-c++/src/config.hh.in @@ -1,3 +1,4 @@ #define DYNDIR "@DYNDIR@" +#define DYN_DATADIR "@DYN_DATADIR@" #define DYN_FIXTURES "@DYN_FIXTURES@" #define MILENA_DIR "@MILENA_DIR@" diff --git a/dynamic-use-of-static-c++/src/function_loader.cc b/dynamic-use-of-static-c++/src/function_loader.cc index 57b20d1..863452c 100644 --- a/dynamic-use-of-static-c++/src/function_loader.cc +++ b/dynamic-use-of-static-c++/src/function_loader.cc @@ -1,16 +1,24 @@ #ifndef DYN_FUNCTION_LOADER_CC # define DYN_FUNCTION_LOADER_CC +# include <cstdlib> # include <ltdl.h> # include <map> // FIXME: Use and improve the logger to avoid use of std::cerr. # include <iostream> +# include <boost/filesystem.hpp> +# include <boost/filesystem/fstream.hpp> +# include <boost/algorithm/string/replace.hpp> + # include "data.hh" # include "function_loader.hh" # include "ruby_stream.hh" +namespace bfs = boost::filesystem; +namespace ba = boost::algorithm; + template <typename InputIterator, typename T, typename OStream> OStream& join(const InputIterator& begin, const InputIterator& end, const T& elt, OStream& ostr) @@ -256,6 +264,79 @@ namespace dyn { ldflags_.push_back(elt); } + // A C++ implementation of function_loader.rb's `compile'. + void + cxx_compile(const std::string& cxx, const std::string& identifier, + const std::string& cflags, const std::string& ldflags) + { + bfs::path dyn_datadir(DYN_DATADIR); + + bfs::path repository("repository"); + if (!bfs::exists(repository)) + { + bfs::create_directory(repository); + bfs::create_symlink(dyn_datadir / "Makefile.repository", + repository / "Makefile"); + } + + bfs::path dir = repository / identifier; + if (!bfs::exists(dir)) + { + bfs::create_directory(dir); + + bfs::ifstream makefile_orig_str(dyn_datadir / "Makefile.template"); + std::stringstream makefile_orig; + makefile_orig << makefile_orig_str.rdbuf(); + bfs::ofstream makefile(dir / "Makefile"); + /* FIXME: We might want to use boost::format in several + places here, since + + (boost::format("libdyn_%1%.la") % identifier).str() + + may be more elegant than + + std::string("libdyn_") + identifier + ".la") + */ + /* FIXME: It would be more elegant if we could replace + `libdyn_function.la' on the fly while copying the + Makefile (as we would do with Perl). See what Boost + proposes. */ + makefile << + ba::replace_all_copy(makefile_orig.str(), + "libdyn_function.la", + std::string("libdyn_") + identifier + ".la"); + makefile << "CXXFLAGS += " << cflags << std::endl; + makefile << "LDFLAGS += " << ldflags << std::endl; + + bfs::create_directory(dir / ".deps"); + bfs::ofstream(dir / ".deps" / "libdyn_function_la-function.Plo"); + + bfs::path file = dir / "function.cc"; + bfs::ofstream function(file); + function << cxx; + } + + bfs::path out = dir / "make.out"; + // FIXME: Same remark wrt boost::format. + std::string cmd = + std::string("cd ") + dir.string() + " && make >make.out 2>&1"; + if (system(cmd.c_str()) == 0) + { + if (bfs::exists(out)) + bfs::remove(out); + } + else + { + bfs::ifstream out_log(out); + std::cerr << "JIT: Error when compiling this code" << std::endl + << cxx << std::endl + << cmd << std::endl + << out_log.rdbuf() << std::endl; + // FIXME: Isn't this a bit too violent? + std::exit(1); + } + } + void* load(fun_kind kind, const std::string& name, -- 1.6.5