Am Dienstag, den 09.07.2013, 20:41 +0000 schrieb talex5:
> --- In firstname.lastname@example.org, Gerd Stolpmann <gerd@...>
> > Am Montag, den 08.07.2013, 19:23 +0000 schrieb talex5:
> > > In particular, it seems that bytecode that uses the Unix module is
> > > portable between Unix and Windows (the source code is, just not
> > > bytecode):
> > >
> > >
> > >
> > > I see from the OCaml source code that there are actually two
> > > implementations of the same unix.mli interface:
> > > and otherlibs/win32unix/unix.ml. Since my program should run on
> > > either, I want to include both versions in my executable and
> > > the correct one at runtime.
> > This phenomenon is not limited to the unix library. In the ocaml
> > distribution the same problem occurs also for threads, and if you
> > using third-party libraries, you'll discover more implementations
> > vary with the platform (not only unix vs. windows, but also linux
> > bsd, 32 vs. 64 bits, etc.).
> I tried compiling my program (which uses Unix, Xmlm and Yojson
> libraries) on a 32-bit Ubuntu system and then ran the bytecode on a
> 64-bit Arch system and it worked. What kind of problems are likely to
E.g. you cannot load an int outside the supported range. Some libraries
have such issues, although rare (e.g. they want to pack as many bits as
possible into an int, and make compile-time optimizations). Here is an
extreme example where even the representation is different (well, it's
from me, but other developers have probably had similar ideas):
I'm currently not even sure whether the 32 bit version would run on 64
> > A relatively easy workaround is not to link the bytecode files to an
> > executable, but leave them as cma's, and just load them into a
> > That means compile all your stuff so you get mylib.cma, and then
> > (or generate) a script like
> > #!/usr/bin/env ocaml
> > #directory "/where/my/stuff/is/installed";;
> > #load "unix.cma";;
> > #load "mylib.cma";;
> > (For Windows, provide a .bat driver side-by-side.)
> (no need for a .bat script; 0install provides a cross-platform
> replacement for #! lines)
> But I don't see how this would help. Either unix.cma is shipped with
> my program (in which case it's the unix.cma for the build system, not
> for the platform running the program), or it's the unix.cma shipped
> with the platform, in which case the hashes won't match.
Right. But on the other hand, there is absolutely no guarantee that
bytecode produced with one version of ocaml can be run on other versions
of ocaml. E.g. the representation of lazy values changed several times.
Recently the hash algorithm was changed. You would have to go through
all changes to ensure that your bytecode is still compatible.
> As far as I can tell, when you compile something like:
> Foo.bar ()
> the name "bar" isn't included in the bytecode.
You just access the n-th value of the module, so the name turns into a
> Instead, you get something like "call function#3 from Foo". OCaml
> prevents that from calling the wrong function by refusing to link if
> anything in the interface has changed ("inconsistent assumptions over
Yes, you can view the hashes with ocamlobjinfo.
> Has the cma trick worked for you?
I'm actually not using it anymore - many years ago I used that for
running ocaml on a machine I did not have a compile environment for
(essentially, no shell access). In this case, I was able to create a
compatible environment with exactly the same ocaml version on another
I don't think it is possible to produce universally runnable bytecode
executables without shipping the version of ocamlrun together with the
bytecode. It is just not made for this use case - don't mix this up with
strictly controlled environments like jvm.
Gerd Stolpmann, Bad Nauheimer Str.3, 64289 Darmstadt,Germany
Phone: +49-6151-153855 Fax: +49-6151-997714