Chapter 1. Libraries and Packages

Reusability is one of the keywords in software engineering today. It simply means to have source code that can be shared by several programs. Usually, modules are combined to libraries, and the library archive files can be linked into programs. As the idea might be simple, its practical implementation is complex because sharing of source code has an impact on all steps and phases in software production. This document only addresses the following administrative problems:

Objective Caml has a variety of language means to support reusability. Most important, polymorphic functions can be written which generalize the types of input arguments and the type of the result value. There are many examples in the core library such that I assume that the reader is familiar with this feature. Second, modules and functors must be mentioned which not only generalize types of values, but can even generalize structures, i.e. types with associated operations. Third, the class construct allows us to adopt the object-oriented techniques of abstraction such as inheritage and dynamic method lookup.

In the following, we are only analyzing the problem of making and using libraries from a purely software-technical point of view. This means, we ignore how to make functions polymorphic, and how to create functors and classes. Instead, we only look at how to invoke the O'Caml compiler to create, manage, and use libraries. Especially, we are interested in the administration of systems of libraries that have dependencies.

One of the complex operations on such a system is the replacement of a library by a newer version. Because of the strict compatibility checks of O'Caml, it is usually necessary to rebuild and reinstall all dependent libraries as well. With the help of findlib, one can find out which are the dependent libraries. (However, findlib does not provide a framework to rebuild them. For example, the GODI system includes such a framework.)

The library is also called a "package" when it is seen as a removeable and replaceable set of files. Findlib requires that there is a certain directory structure; it is not possible to install the files at arbitrary places (findlib does not even maintain a file list). For simplicity, every library is usually stored into its own directory, i.e. the library archive files and the interface files.

From the perspective of the compiler, the library is made accessible by adding the package directory to the search path of the compiler. By doing so, the modules of the library are added to the namespace universe, and thus can be opened by modules using them. This means that the approach "one package = one directory" can be naturally translated into language operations modifying the namespace scope.

When linking a program, it must be specified which link operation is necessary to use a certain library. Often, only a single archive file needs to be linked in, but sometimes additional archives or system libraries must be linked, too. Furthermore, the link operations often depends on certain conditions, e.g. whether a single- or multi-threaded program is being created.

The findlib library is my suggestion for a package manager suitable for Objective Caml. It is a library (stored as a package itself) which can answer the following questions:

Furthermore, there is a frontend for this library called ocamlfind. It is a command-line interface for the library, but has also some additional abilities:

As you'll see in the following chapters, the usage of this library is really simple. If you want only to link in packages written by other people, you must only change the command that invokes the compiler, e.g. instead of calling "ocamlc" invoke "ocamlfind ocamlc -package name_of_package_to_use -linkpkg", and you can refer to the named package within If you want to turn your collection of modules into a package, you need only to write one adminstrative file (META) containing all extra information such as required other packages.