Compiling OCaml Projects
This tutorial explains how to compile your OCaml programs into executable form. It addresses, in turn:
The compilation commands
ocamloptprovided with OCaml. It is useful to learn these commands to understand OCaml's compilation model.
ocamlfindfront-end to the compiler, which saves you from worrying about where libraries have been installed on your particular system.
Automatic build systems for OCaml, such as
dune, which release us from details of compiler command invocation, so we never touch
ocamlopt, or even
In "Your First OCaml Program" we jumped straight to using
the automated build system
dune. Now we shall look under the hood.
In this section, we will first see how to compile a simple program using
ocamlopt. Then we will see how to use libraries and how
to take advantage of the
system, which provides the
OCaml comes with two compilers:
ocamlc is the bytecode compiler, and
ocamlopt is the native code compiler. If you don't know which one to use, use
ocamlopt since it provides executables that are faster than bytecode.
Let's assume that our program
program has two source files,
module2.ml. We will compile them to native code,
ocamlopt. For now, we also assume that they do not use any other
library than the standard library, which is automatically loaded. You
can compile the program in one single step:
ocamlopt -o program module1.ml module2.ml
The compiler produces an executable named
program.exe. The order
of the source files matters, and so
module1.ml cannot depend upon things that
are defined in
module2.ml. Please also note that you should avoid creating a file that
conflicts with a module exposed by a library you are using. For instance, if you create
graphics.ml and use the
graphics library, the
Graphics module exposed
graphics library will be hidden by your newly defined module, hence all
of the functions defined in it will be made inaccessible.
The OCaml distribution is shipped with the standard library, plus several other libraries. There are also a large number of third-party libraries, for a wide range of applications, from networking to graphics. You should understand the following:
The OCaml compilers know where the standard library is and use it systematically (try:
ocamlc -where). You don't have to worry much about it.
The other libraries that ship with the OCaml distribution (str, unix, etc.) are installed in the same directory as the standard library.
Third-party libraries may be installed in various places, and even a given library can be installed in different places from one system to another.
If your program uses the unix library in addition to the standard library, for example, the command line would be:
ocamlopt -o program unix.cmxa module1.ml module2.ml
.cmxa is the extension of native code libraries, while
the extension of bytecode libraries. The file
unix.cmxa is found because it
is always installed at the same place as the standard library, and this
directory is in the library search path.
If your program depends upon third-party libraries, you must pass them on the
command line. You must also indicate the libraries on which these libraries
depend. You must also pass the -I option to
ocamlopt for each directory where
they may be found. This becomes complicated, and this information is
installation dependent. So we will use
ocamlfind instead, which does these
jobs for us.
ocamlfind front-end is often used for compiling programs that use
third-party OCaml libraries. Library authors themselves make their library
ocamlfind as well. You can install
ocamlfind using the
opam package manager, by typing
opam install ocamlfind.
Let's assume that all the libraries you want to use have been installed properly with ocamlfind. You can see which libraries are available in your system by typing:
This shows the list of package names, with their versions. Note that most
opam packages install software using ocamlfind, so your list of ocamlfind
libraries will be somewhat similar to your list of installed opam packages
The command for compiling our program using package
pkg will be:
ocamlfind ocamlopt -o program -linkpkg -package pkg module1.ml module2.ml
Multiple packages may be specified using commas e.g
knows how to find any files
ocamlopt may need from the package, for example
.cmxa implementation files or
.cmi interface files, because they have been
packaged together and installed at a known location by ocamlfind. We need only
pkg to refer to them all - ocamlfind does the rest.
Note that you can compile the files separately. This is useful if you want to recompile only some parts of the programs. Here are the equivalent commands that perform a separate compilation of the source files and link them together in a final step:
ocamlfind ocamlopt -c -package pkg module1.ml
ocamlfind ocamlopt -c -package pkg module2.ml
ocamlfind ocamlopt -o program -linkpkg -package pkg module1.cmx module2.cmx
Separate compilation (one command for
module1.ml, another for
and another to link the final output) is usually not performed manually but
only when using an automated build system that will take care of recompiling
only what is necessary.
Interlude: Making a Custom Toplevel
OCaml provides another tool
ocamlmktop to make an interactive toplevel with
libraries accessible. For example:
ocamlmktop -o toplevel unix.cma module1.ml module2.ml
toplevel and get an OCaml toplevel with modules
Module2 all available, allowing us to experiment interactively with our
OCamlfind also supports
ocamlfind ocamlmktop -o toplevel unix.cma -package pkg module1.ml module2.ml
Dune: An Automated Build System
The most popular modern system for building OCaml projects is
dune which may be installed with
opam install dune. It allows one to build OCaml projects from a simple
description of their elements. For example, the dune file for our project might
look like this:
;; our example project
The dune quick-start guide shows you how to write such description files for more complicated situations, and how to structure, build, and run dune projects.