94 lines
4.4 KiB
ReStructuredText
94 lines
4.4 KiB
ReStructuredText
The OCaml Ecosystem
|
|
===================
|
|
|
|
The OCaml ecosystem is not monolithic: the compiler and tools are not
|
|
maintained by the same entities. As such, it can be difficult to understand the
|
|
history and roles of the various pieces of this ecosystem. The goal of this
|
|
page is to give a quick overview of the situation and the role that Dune
|
|
plays in it.
|
|
|
|
The OCaml Compiler Distribution: Compiling and Linking
|
|
------------------------------------------------------
|
|
|
|
The `OCaml compiler distribution <https://github.com/ocaml/ocaml>`_ contains
|
|
"core" tools including the compilers (``ocamlc`` and ``ocamlopt``). They turn
|
|
source files (with extensions ``.ml`` and ``.mli``) into executables and
|
|
libraries. Dependencies between compiled objects only exist at the module
|
|
level, so this is a low-level tool.
|
|
|
|
Findlib: Metadata for Libraries
|
|
-------------------------------
|
|
|
|
Findlib_ is a tool that defines the concept of library, so that libraries can
|
|
depend on other libraries on top of the notion of module. Definitions of
|
|
libraries, and other pieces of metadata, are stored in ``META`` files.
|
|
|
|
Findlib ships an executable named ``ocamlfind`` that can be used as a wrapper
|
|
on top of the compilers to perform tasks such as producing an executable from
|
|
compiled object files and external libraries.
|
|
|
|
.. _findlib: https://github.com/ocaml/ocamlfind
|
|
|
|
Opam: a Collection of Software Projects
|
|
---------------------------------------
|
|
|
|
Opam is a package manager. It is used to determine which packages are
|
|
necessary, and how to fetch and build them. Packages can contain libraries,
|
|
executables, and other kinds of files.
|
|
|
|
The notion of version is specific to opam. If your project uses a function
|
|
named ``Png.read_file`` but this function has been added only in version
|
|
``1.2.0`` of that package, opam needs to know about it.
|
|
|
|
Opam manages collections of installed packages, called switches. Using your
|
|
project's dependencies (names and version constraints), it is able to create a
|
|
switch that you'll be using to develop your project.
|
|
|
|
Public definitions of packages are available in a database called
|
|
``opam-repository`` which is maintained as a public Git repository. Publishing a
|
|
package on opam (to make sure that external users can use your project)
|
|
consists in adding its definition to ``opam-repository``.
|
|
|
|
Dune: Giving Structure to Your Source Tree
|
|
------------------------------------------
|
|
|
|
Dune is a build system. It is used to orchestrate the compilation of source
|
|
files into executables and libraries.
|
|
|
|
Assuming you have a development switch set up, you communicate to Dune about how your
|
|
project is organized in terms of executables, libraries, and tests. It is then able to assemble the source files of your projects, with the dependencies installed in an opam switch, to create compiled assets for your project.
|
|
|
|
How Dune Integrates With the Ecosystem
|
|
--------------------------------------
|
|
|
|
Dune is designed to integrate with the tools mentioned above:
|
|
|
|
- By knowing how the OCaml compilers operate, it knows which build commands should be
|
|
re-executed if some source files change.
|
|
- It outputs metadata like dependency information into ``META`` files that
|
|
Findlib is able to make use of. This ensures that even if a project does not use Dune, it
|
|
can use a library that has been produced by Dune. Conversely, it can read
|
|
these files to determine dependency information for dependencies that have
|
|
not been produced by Dune.
|
|
- It is able to generate opam files with filenames consistent with how opam
|
|
looks for them. The generated files use build commands that make use of the
|
|
:doc:`/reference/aliases/install` and ``@runtest`` :term:`aliases <alias>` so
|
|
that the Dune abstractions map to the opam ones.
|
|
|
|
Dune is Opinionated
|
|
-------------------
|
|
|
|
As described above, the OCaml ecosystem does not have a centralized toolchain.
|
|
Units such as modules, libraries, and packages operate at different levels, and
|
|
the relation between these can be confusing to users.
|
|
|
|
Dune tries to simplify the picture by reducing the difference between these
|
|
objects:
|
|
|
|
- By default, a library will only expose a single top-level module named after
|
|
the library (this is called a wrapped library).
|
|
- A library can only be installed in the package of the same name. This means
|
|
that the names found in ``dune-project`` and ``opam`` files (package names)
|
|
are consistent with the names found in ``dune`` files (library names). More
|
|
precisely, libraries ``foo``, ``foo.bar`` and ``foo.baz`` are part of the
|
|
``foo`` package.
|