library

The library stanza must be used to describe OCaml libraries. The format of library stanzas is as follows:

(library
 (name <library-name>)
 <optional-fields>)

<library-name> is the real name of the library. It determines the names of the archive files generated for the library as well as the module name under which the library will be available, unless (wrapped false) is used (see below). It must be a valid OCaml module name, but it doesn’t need to start with an uppercase letter.

For instance, the modules of a library named foo will be available as Foo.XXX, outside of foo itself; however, it is allowed to write an explicit Foo module, which will be the library interface. You are free to expose only the modules you want.

Please note: by default, libraries and other things that consume OCaml/Reason modules only consume modules from the directory where the stanza appear. In order to declare a multi-directory library, you need to use the include_subdirs stanza.

<optional-fields> are:

  • (public_name <name>) - the name under which the library can be referred as a dependency when it’s not part of the current workspace, i.e., when it’s installed. Without a (public_name ...) field, the library won’t be installed by Dune. The public name must start with the package name it’s part of and optionally followed by a dot, then anything else you want. The package name must also be one of the packages that Dune knows about, as determined by the logic described in Packages.

  • (package <package>) installs a private library under the specified package. Such a library is now usable by public libraries defined in the same project. The Findlib name for this library will be <package>.__private__.<name>; however, the library’s interface will be hidden from consumers outside the project.

  • (synopsis <string>) should give a one-line description of the library. This is used by tools that list installed libraries

  • (modules <modules>) specifies what modules are part of the library. By default, Dune will use all the .ml/.re files in the same directory as the dune file. This includes ones present in the file system as well as ones generated by user rules. You can restrict this list by using a (modules <modules>) field. <modules> uses the Ordered Set Language, where elements are module names and don’t need to start with an uppercase letter. For instance, to exclude module Foo, use (modules (:standard \ foo)). Starting in Dune 3.13, one can also use special forms (:include <file>) and variables such as %{read-lines:<file>} in this field to customize the list of modules using Dune rules. The dependencies introduced in this way must live in a different directory that the stanza making use of them.

  • (libraries <library-dependencies>) specifies the library’s dependencies. See Library Dependencies for more details.

  • (wrapped <boolean>) specifies whether the library modules should be available only through the top-level library module, or if they should all be exposed at the top level. The default is true, and it’s highly recommended to keep it this way. Because OCaml top-level modules must all be unique when linking an executables, polluting the top-level namespace will make your library unusable with other libraries if there is a module name clash. This option is only intended for libraries that manually prefix all their modules by the library name and to ease porting of existing projects to Dune.

  • (wrapped (transition <message>)) is the same as (wrapped true), except it will also generate unwrapped (not prefixed by the library name) modules to preserve compatibility. This is useful for libraries that would like to transition from (wrapped false) to (wrapped true) without breaking compatibility for users. The deprecation notices for the unwrapped modules will include <message>.

  • (preprocess <preprocess-spec>) specifies how to preprocess files when needed. The default is no_preprocessing, and other options are described in Preprocessing Specification.

  • (preprocessor_deps (<deps-conf list>)) specifies extra preprocessor dependencies preprocessor, i.e., if the preprocessor reads a generated file. The specification of dependencies is described in Dependency Specification.

  • (optional) - if present, it indicates that the library should only be built and installed if all the dependencies are available, either in the workspace or in the installed world. Use this to provide extra features without adding hard dependencies to your project

  • (foreign_stubs <foreign-stubs-spec>) specifies foreign source files, e.g., C or C++ stubs, to be compiled and packaged together with the library. See the section Foreign Sources, Archives, and Objects for more details. This field replaces the now-deleted fields c_names, c_flags, cxx_names, and cxx_flags.

  • (foreign_archives <foreign-archives-list>) specifies archives of foreign object files to be packaged with the library. See the section Foreign Archives for more details. This field replaces the now-deleted field self_build_stubs_archive.

  • (install_c_headers (<names>)) - if your library has public C header files that must be installed, you must list them in this field, without the .h extension. You should favor the public_headers field starting from 3.8.

  • (public_headers (<files>)) - if your library has public C header files that must be installed, you must list them in this field. This field accepts globs in the form of (glob_files_rec <glob>) and (glob_files <glob>) fields to specify multiple files.

    The advantage of this field over install_c_headers is that it preserves the directory structures of the headers relative to the library stanza. Additionally, it allows to specify the extensions of the header files, which allows alternative extensions such as .hh or .hpp.

  • (modes <modes>) is for modes which should be built by default. The most common use for this feature is to disable native compilation when writing libraries for the OCaml toplevel. The following modes are available: byte, native and best. best is native or byte when native compilation isn’t available.

  • (no_dynlink) disables dynamic linking of the library. This is for advanced use only. By default, you shouldn’t set this option.

  • (kind <kind>) sets the type of library. The default is normal, but other available choices are ppx_rewriter and ppx_deriver. They must be set when the library is intended to be used as a PPX rewriter or a [@@deriving ...] plugin. The reason ppx_rewriter and ppx_deriver are split is historical, and hopefully we won’t need two options soon. Both PPX kinds support an optional field: (cookies <cookies>), where <cookies> is a list of pairs (<name> <value>) with <name> being the cookie name and <value> a string that supports Variables evaluated by each preprocessor invocation (note: libraries that share cookies with the same name should agree on their expanded value).

  • (ppx_runtime_libraries (<library-names>)) is for when the library is a ppx rewriter or a [@@deriving ...] plugin, and has runtime dependencies. You need to specify these runtime dependencies here.

  • (virtual_deps (<opam-packages>). Sometimes opam packages enable a specific feature only if another package is installed. For instance, the case of ctypes will only install ctypes.foreign if the dummy ctypes-foreign package is installed. You can specify such virtual dependencies here, but you don’t need to do so unless you use Dune to synthesize the depends and depopts sections of your opam file.

  • js_of_ocaml sets options for JavaScript compilation, see js_of_ocaml.

  • For flags, ocamlc_flags, and ocamlopt_flags, see OCaml Flags.

  • (library_flags (<flags>)) is a list of flags passed to ocamlc and ocamlopt when building the library archive files. You can use this to specify -linkall, for instance. <flags> is a list of strings supporting Variables.

  • (c_library_flags <flags>) specifies the flags passed to the C compiler when constructing the library archive file for the C stubs. <flags> uses the Ordered Set Language and supports (:include ...) forms. When you write bindings for a C library named bar, you should typically write -lbar here, or whatever flags are necessary to link against this library.

  • (modules_without_implementation <modules>) specifies a list of modules that have only a .mli or .rei but no .ml or .re file. Such modules are usually referred as mli only modules. They are not officially supported by the OCaml compiler; however, they are commonly used. Such modules must only define types. Since it isn’t reasonably possible for Dune to check this is the case, Dune requires the user to explicitly list such modules to avoid surprises. Note that the modules_without_implementation field isn’t merged in modules, which represents the total set of modules in a library. If a directory has more than one stanza, and thus a modules field must be specified, <modules> still needs to be added in modules.

  • (private_modules <modules>) specifies a list of modules that will be marked as private. Private modules are inaccessible from outside the libraries they are defined in. Note that the private_modules field is not merged in modules, which represents the total set of modules in a library. If a directory has more than one stanza and thus a modules field must be specified, <modules> still need to be added in modules.

  • (allow_overlapping_dependencies) allows external dependencies to overlap with libraries that are present in the workspace.

  • (enabled_if <blang expression>) conditionally disables a library. A disabled library cannot be built and will not be installed. The condition is specified using the Boolean Language, and the field allows for the %{os_type} variable, which is expanded to the type of OS being targeted by the current build. Its value is the same as the value of the os_type parameter in the output of ocamlc -config.

  • (inline_tests) enables inline tests for this library. They can be configured through options using (inline_tests <options>). See Inline Tests for a reference of corresponding options.

  • (root_module <module>) this field instructs Dune to generate a module that will contain module aliases for every library specified in dependencies. This is useful whenever a library is shadowed by a local module. The library may then still be accessible via this root module

  • (ctypes <ctypes field>) instructs Dune to use ctypes stubgen to process your type and function descriptions for binding system libraries, vendored libraries, or other foreign code. See Stub Generation with Dune Ctypes for a full reference. This field is available since the 3.0 version of the Dune language.

  • (empty_module_interface_if_absent) causes the generation of empty interfaces for every module that does not have an interface file already. Useful when modules are used solely for their side-effects. This field is available since the 3.0 version of the Dune language.

Note that when binding C libraries, Dune doesn’t provide special support for tools such as pkg-config; however, it integrates easily with Configurator by using (c_flags (:include ...)) and (c_library_flags (:include ...)).