diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html
index 92666f08b..80a40bb79 100644
--- a/Doc/Manual/Ocaml.html
+++ b/Doc/Manual/Ocaml.html
@@ -62,11 +62,12 @@ best way to determine whether your system will work is to compile the
examples and test-suite which come with SWIG. You can do this by running
make check from the SWIG root directory after installing SWIG.
The Ocaml module has been tested using the system's dynamic linking (the
-usual -lxxx against libxxx.so, but not using the explicit dynamic linking
-provided by the Dl package http://www.ocaml-programming.de/packages/documentation/dl/
- , although I suspect that it will work without a problem. If anyone
-would like to evaluate this support, I will share the results here.
+usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's
+Dl package
+. The ocaml_dynamic and ocaml_dynamic_cpp targets in the
+file Examples/Makefile illustrate how to compile and link SWIG modules that
+will be loaded dynamically. This has only been tested on Linux so far.
16.1.1 Running SWIG
diff --git a/Examples/GIFPlot/Ocaml/full/Makefile b/Examples/GIFPlot/Ocaml/full/Makefile
index 5b1e907f3..4f35c43f9 100644
--- a/Examples/GIFPlot/Ocaml/full/Makefile
+++ b/Examples/GIFPlot/Ocaml/full/Makefile
@@ -19,6 +19,13 @@ static::
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static
+dynamic::
+ $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
+ IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \
+ SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \
+ INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_dynamic
+
clean::
$(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean
rm -f *.gif
diff --git a/Examples/GIFPlot/Ocaml/simple/Makefile b/Examples/GIFPlot/Ocaml/simple/Makefile
index 52d2a49a4..50492efc7 100644
--- a/Examples/GIFPlot/Ocaml/simple/Makefile
+++ b/Examples/GIFPlot/Ocaml/simple/Makefile
@@ -19,6 +19,13 @@ static::
INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static
+dynamic::
+ $(MAKE) -f $(TOP)/Makefile TOP='$(TOP)' \
+ IOBJS='$(IOBJS)' PROGFILE='$(PROGFILE)' \
+ SRCS='$(SRCS)' SWIG='$(SWIG)' MLFILE='$(MLFILE)' \
+ INCLUDES='$(INCLUDES)' LIBS='$(LIBS)' SWIGOPT='$(SWIGOPT)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ocaml_static
+
clean::
$(MAKE) -f $(TOP)/Makefile MLFILE='$(MLFILE)' ocaml_clean
rm -f *.gif
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index d5aacd194..3ebedbbcf 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -508,6 +508,8 @@ mzscheme_clean:
##################################################################
OCC=@OCAMLC@
+OCAMLDLGEN=@OCAMLDLGEN@
+OCAMLFIND=@OCAMLFIND@
NOLINK ?= false
ocaml_static: $(SRCS)
@@ -522,9 +524,25 @@ ocaml_static: $(SRCS)
$(PROGFILE:%.ml=%.cmo) \
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
+ocaml_dynamic: $(SRCS)
+ $(SWIG) -ocaml $(SWIGOPT) $(INTERFACE)
+ $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCS)
+ $(CXXSHARED) $(CCSHARED) $(CFLAGS) -o $(INTERFACE:%.i=%@SO@) \
+ $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
+ $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
+ $(INTERFACE:%.i=%_dynamic.ml)
+ mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
+ rm $(INTERFACE:%.i=%.mli)
+ $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
+ test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
+ $(OCC) -c $(PROGFILE)
+ $(NOLINK) || $(OCAMLFIND) \
+ $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
+ -package dl -linkpkg \
+ $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
+
ocaml_static_cpp: $(SRCS)
- $(SWIG) -ocaml -c++ $(SWIGOPT) \
- $(INTERFACE)
+ $(SWIG) -ocaml -c++ $(SWIGOPT) $(INTERFACE)
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
$(OCC) -cc '$(CXX)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
$(ICXXSRCS:%.cxx=%.c) $(SRCS) $(CXXSRCS)
@@ -535,7 +553,29 @@ ocaml_static_cpp: $(SRCS)
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
$(INTERFACE:%.i=%.cmo) \
$(PROGFILE:%.ml=%.cmo) \
- $(INTERFACE:%.i=%_wrap.@OBJEXT@) -cclib "$(LIBS)" -cc '$(CXX)'
+ $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
+ -cclib "$(LIBS)" -cc '$(CXX)'
+
+ocaml_dynamic_cpp: $(SRCS)
+ $(SWIG) -ocaml -c++ $(SWIGOPT) $(INTERFACE)
+ cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
+ $(OCC) -cc '$(CXX)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \
+ $(ICXXSRCS:%.cxx=%.c) $(SRCS) $(CXXSRCS) -ccopt -fPIC
+ $(CXXSHARED) $(CXXFLAGS) -o $(INTERFACE:%.i=%@SO@) \
+ $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
+ $(CPP_DLLIBS) $(LIBS)
+ $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
+ $(INTERFACE:%.i=%_dynamic.ml)
+ mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
+ rm $(INTERFACE:%.i=%.mli)
+ $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
+ test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \
+ $(OCC) -c $(PROGFILE)
+ $(NOLINK) || $(OCAMLFIND) \
+ $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom \
+ -o $(TARGET) \
+ -package dl -linkpkg \
+ $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX)'
ocaml_static_multi_cpp: $(SRCS)
$(SWIG) -c -ocaml -c++ $(SWIGOPT) \
diff --git a/Examples/ocaml/simple/Makefile b/Examples/ocaml/simple/Makefile
index bac7edf47..e16df0113 100644
--- a/Examples/ocaml/simple/Makefile
+++ b/Examples/ocaml/simple/Makefile
@@ -9,6 +9,12 @@ OBJS = example.o
all:: static
+dynamic::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MLFILE='$(MLFILE)' \
+ PROGFILE='$(PROGFILE)' OBJS='$(OBJS)' \
+ ocaml_dynamic
+
static::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' MLFILE='$(MLFILE)' \
diff --git a/Examples/ocaml/std_string/Makefile b/Examples/ocaml/std_string/Makefile
index a281386a6..572b1866f 100644
--- a/Examples/ocaml/std_string/Makefile
+++ b/Examples/ocaml/std_string/Makefile
@@ -12,6 +12,11 @@ static::
PROGFILE='$(PROGFILE)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
ocaml_static_cpp
+dynamic::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ PROGFILE='$(PROGFILE)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
+ ocaml_dynamic_cpp
+
clean::
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' ocaml_clean
diff --git a/Examples/ocaml/std_vector/Makefile b/Examples/ocaml/std_vector/Makefile
index a281386a6..572b1866f 100644
--- a/Examples/ocaml/std_vector/Makefile
+++ b/Examples/ocaml/std_vector/Makefile
@@ -12,6 +12,11 @@ static::
PROGFILE='$(PROGFILE)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
ocaml_static_cpp
+dynamic::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ PROGFILE='$(PROGFILE)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
+ ocaml_dynamic_cpp
+
clean::
$(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' ocaml_clean
diff --git a/configure.in b/configure.in
index 23d7a10ea..9216a312e 100644
--- a/configure.in
+++ b/configure.in
@@ -914,6 +914,22 @@ AC_SUBST(PHP4INC)
AC_ARG_WITH(ocaml,[ --with-ocaml=path Set location of ocaml executable],[ OCAMLBIN="$withval"], [OCAMLBIN=])
AC_ARG_WITH(ocamlc,[ --with-ocamlc=path Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=])
+AC_ARG_WITH(ocamldlgen,[ --with-ocamldlgen=path Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=])
+AC_ARG_WITH(ocamlfind,[ --with-ocamlfind=path Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=])
+
+AC_MSG_CHECKING(for Ocaml DL load generator)
+if test -z "$OCAMLDLGEN"; then
+AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen, ocamldlgen)
+else
+OCAMLDLGEN="$OCAMLDLGEN"
+fi
+
+AC_MSG_CHECKING(for Ocaml package tool)
+if test -z "$OCAMLFIND"; then
+AC_CHECK_PROGS(OCAMLFIND, ocamlfind, ocamlfind)
+else
+OCAMLFIND="$OCAMLFIND"
+fi
AC_MSG_CHECKING(for Ocaml compiler)
if test -z "$OCAMLC"; then
@@ -945,10 +961,14 @@ fi
export OCAMLINC
export OCAMLBIN
export OCAMLC
+export OCAMLDLGEN
+export OCAMLFIND
AC_SUBST(OCAMLINC)
AC_SUBST(OCAMLBIN)
AC_SUBST(OCAMLC)
+AC_SUBST(OCAMLDLGEN)
+AC_SUBST(OCAMLFIND)
#----------------------------------------------------------------
# Look for Pike