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(a)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(a)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