--------------------------------------------------------------------- This is the O'Caml Runtime Environment ---------------------------------------------------------------------- This distribution contains a subset of the O'Caml language, namely the runtime environment. The runtime system has been slightly modified and extended in order to allow dynamic loading of system libraries. This means that the ocamlre interpreter is able to run any O'Caml executable that uses the following libraries: - bigarray - dbm - graph - labltk - num - str - threads (only bytecode threads are supported) - unix - dynlink The libraries are only loaded when needed. EXAMPLE: Run any bytecode file f using: ocamlre f <arg> ... You can also prepend a #! /location/of/ocamlre line to the bytecode file f: echo "#! /location/of/ocamlre" >aux cat aux f >f_new chmod a+x f_new Then, ./f_new automatically uses ocamlre to execute the bytecode. ERROR DIAGNOSTICS: If you get the message: ocamlre: Primitive xyz not found a library is missing. You can check which libraries ocamlre includes by just calling ocamlre without arguments. HOW TO BUILD AN APPLICATION FOR OCAMLRE: - Build your application using ocamlc as usual. However, the last step should be changed into a "-use-runtime" linker invocation: ocamlc -o my-executable -use-runtime my-interpreter module.cmo ... Here, my-interpreter has been previously built by ocamlc -o my-interpreter -make-runtime libxxx.cma ... If you do not change the last step, the resulting executable may be larger than necessary (because another runtime engine may be included into the file). - Test: Try to run your application with your custom interpreter: my-interpreter my-executable ... - Finally, you can throw away my-interpreter and start your application using ocamlre: ocamlre my-executable Note that my-interpreter is only necessary because we need a reference interpreter. ---------------------------------------------------------------------- This is an alpha release! ---------------------------------------------------------------------- ocamlre is currently a three-day hack, and there was up to now not very much time to test it. I've been able to compile it on my Linux box and to run several applications; however: - I have not tried it under many operating systems (see below) - I have not tried all libraries So be prepared that there may be problems. ---------------------------------------------------------------------- Operating Systems ---------------------------------------------------------------------- There are two "flovours": - ELF-based systems: these can dlopen the libraries. Tested with Linux and Solaris. - Other systems: as an alternate scheme, it is possible to build several executables that contain sets of libraries. The appropriate executable is selected at run-time. Tested with AIX. ---------------------------------------------------------------------- Compiling ocamlre ---------------------------------------------------------------------- First call ./configure. This is almost the same configure script as distributed with the O'Caml compiler, and the same arguments apply (see INSTALL.ocaml). EXAMPLE: ./configure -bindir /opt/ocaml-3.01/bin -libdir /opt/ocaml-3.01/ocamlre Note that -with-pthread is not supported. Into the -bindir directory the runtime engine "ocamlre" will be installed. The -libdir directory will contain the shared libraries. Do not specify a system-wide library directory such as /usr/lib or /usr/local/lib, but a private directory only for ocamlre. There is an additional option: --with-dlopen (or --without-dlopen). This option controls whether the dlopen loader should be used or not. You may try --without-dlopen if the dlopen loader does not work. Then do: make If everything works well, there is now the ocamlre executable in the top level directory. Now a make install installs the following files: ocamlre into the binary directory lib*.so, lib*.prims into the library directory Note that "ocamlre" is not relocatable, i.e. you cannot change the directories after the compilation. The "ocamlre" binary contains the path of the library directory hard-coded (such that you do not need to set the LD_LIBRARY_PATH variable, or to enable the directory by other means). ---------------------------------------------------------------------- Deployment ---------------------------------------------------------------------- A bytecode executable created by O'Caml 3.01 can only be executed by ocamlre-3.01, i.e. the ocaml and ocamlre versions must be the same. For system-wide, non-experimental installations I recommend to include the version number into the library directory. Example: A hypothetical installation of ocamlre-3.01 and ocamlre-3.02: /usr/local/bin/ocamlre: symlink to ocamlre-3.02 /usr/local/bin/ocamlre-3.01 interpreter for version 3.01 /usr/local/bin/ocamlre-3.02 interpreter for version 3.02 /usr/local/lib/ocamlre-3.01/... libraries for version 3.01 /usr/local/lib/ocamlre-3.02/... libraries for version 3.02 A bytecode executable for version 3.01 would begin with #! /usr/local/bin/ocamlre-3.01 and an executable for version 3.02 would begin with #! /usr/local/bin/ocamlre-3.02 The symlink /usr/local/bin/ocamlre indicates the default version. It must not occur in executables. ---------------------------------------------------------------------- How it works ---------------------------------------------------------------------- 1) DLOPEN: You may have noticed that ocamlre is very small (usually < 20 kB). It loads everything it needs from the shared libraries. The first step is that libocamlrun.so is loaded, the core interpreter. Now ocamlre tries to find out which additional libraries are needed. For every library libxxx.so there is a corresponding list of primitives, libxxx.prims. The bytecode file to run contains a list of needed primitives. ocamlre searches these primitives in the libxxx.prims files, and loads the associated libraries. Note that this approach of handling dynamic linking has the fundamental disadvantage that libraries with overlapping sets of primitives cannot be distinguished. For example, it is impossible to install both camltk and labltk at the same time, as many primitives have equal names. 2) EXEC: As an alternative, it is possible to build several runtime executables, and ocamlre selects the right executable after inspecting the required primitives. You need *.libs files in this case, and these files must contain the names of the libraries that are supported by the *.x executables. ----------------------------------------------------------------------- How to install additional libraries --------------------------------------------------------------------- - Make sure that the object files only contain position-independent code. - Create a shared object libxxx.so - Enumerate all your primitive names in a text file libxxx.prims, simply one primitive per line - Install both libxxx.so and libxxx.prims in the configured library directory That's all. The ocamlre build process bases now on GNU libtool. To see how libtool is called, look into the Makefiles, especially those named Makefile.ocamlre. ---------------------------------------------------------------------- PATCHED FILES ---------------------------------------------------------------------- The ocamlre package contains a subset of the full O'Caml distribution. Most files are unmodified, except of the following: configure byterun/startup.c otherlibs/unix/access.c (because of a cygwin problem) The modified lines/regions have been marked as PATCHED. The toplevel directory contains additional files (libltdl, loader.c etc). Furthermore, there is in every directory a Makefile.ocamlre that includes the original Makefile, and that defines the additional rules dealing with libtool. ---------------------------------------------------------------------- Contact ---------------------------------------------------------------------- Gerd Stolpmann gerd(at)gerd-stolpmann.de