Dune Build System
repository·main·Indexed 23 days ago
https://github.com/ocaml/duneA composable build system for OCaml that manages compilation, dependency resolution, and development tool configuration using S-expression-based metadata files. It supports parallel builds, watch mode via RPC, and sandboxing on Linux (via bubblewrap) and macOS (via sandbox-exec). Key commands include `dune build` for target execution, `dune runtest` for testing, and `dune clean` for removing generated files.
What's inside Dune
- Dune is a composable build system designed for OCaml projects. It allows developers to build executables and libraries, run tests, and manage complex project workflows.
Summary of core Dune features covered in tutorials
mainDune provides several key stanzas and workflows for managing OCaml projects:
- Stanzas: Use
executable,library, andteststanzas to define the primary components of your build. - Testing: Implement
cram testsfor integration testing and use thepromotionworkflow to manage build artifacts across different environments. - C Interop: Use
foreign stubsto create bindings between OCaml and C code. - Metaprogramming: Utilize
ppx deriversto extend the OCaml language during the compilation process.
- Stanzas: Use
Understand the roles of OCaml ecosystem tools
mainThe OCaml ecosystem consists of several distinct layers that work together to manage code from source to package:
- OCaml Compiler (
ocamlc,ocamlopt): The low-level tool that converts source files (.ml,.mli) into executables and libraries. It operates at the module level. - Findlib (
ocamlfind): Manages library metadata viaMETAfiles, allowing libraries to depend on one another. It provides a wrapper around the compilers to handle linking with external libraries. - Opam: The package manager. It handles dependency resolution, fetching, and building. It manages environments called switches and uses an
opam-repositoryto find package definitions. - Dune: The build system. It orchestrates the compilation process by mapping your project's structure (executables, libraries, tests) to the underlying compiler and ecosystem tools.
- OCaml Compiler (
How Dune Package Management works
mainDune's package management provides a local, reproducible, and project-scoped way to manage OCaml dependencies. Unlike
opam, which relies on global state, Dune manages everything within the project using configuration files (dune-projectand optionallydune-workspace).Core Principles:
- No global state: Everything is local to the project.
- Single source of truth: Dependencies are primarily declared in
dune-project(though.opamfiles are still supported for compatibility). - Reproducibility: Uses lockfiles (stored in a lock directory) to ensure consistent builds.
- Isolation: Builds can only access packages explicitly declared as dependencies.
- Compatibility: Uses the same
opamrepositories, meaning Dune packages remain installable viaopam.
Manage developer tools with `dune tools`
mainThe
dune toolscommand group allows you to manage developer tools (likeocamlformat,ocamllsp, orutop) that are useful for development but not required for building or deploying the project. Dune automatically handles resolving, locking, building, and running these tools in a separate lock directory (typically_build/.dev-tools.locks) to avoid polluting your project environment.Warning: The
dune toolscommand group is experimental. Its subcommands, flags, and behavior may change in future versions without notice.Project structure of hello_world
mainThe
hello_worldproject follows a standard layout where components are organized into subdirectories:lib/: Contains thehello_worldlibrary definition.bin/: Contains thehello_worldexecutable definition.test/: Contains the project tests.hello_world.opam: A required file at the project toplevel that allows Dune to recognize the directory as thehello_worldproject.
What is the Dune engine?
mainThe engine is the core, reusable component of Dune that provides the composable primitives required for a build system. It is decoupled from the rule generation logic (the
rulespart), allowing it to serve as a backend for other build systems.In a standard Dune installation, the engine is responsible for:
- Tracking directories and the rules contained within them.
- Executing builds using those rules.
- Managing various caches, including the local
_builddirectory and the shared cache.
What is a dune-workspace file?
mainA
dune-workspacefile marks the root of a Dune workspace. It allows you to define compilation contexts and specify settings that are common to all Dune projects contained within that workspace.By default, a workspace contains a single build context named
default, which corresponds to the environment in whichduneis executed. To define multiple contexts, you must use adune-workspacefile.Understand package kinds in install layouts
mainWhen using
(deps (package ...)), Dune classifies packages into three categories which affect how they are handled:Local: Workspace packages defined in yourdune-project. These receive both layout file dependencies and environment variables.Build: Lock-dir packages fromdune.lock. Using(deps (package foo))will run the package's build action, but (currently) does not set up environment variables for the consuming action.Installed: Externally installed packages (found viafindlib). These are depended on directly and are already present in the systemOCAMLPATH. In a lock-dir context, these resolve asBuildpackages if they are indune.lock, or are not found otherwise.
Notes on using revdep aliases
mainWhen using
@revdepaliases, keep the following in mind:- No Overhead: These aliases only perform work when explicitly requested; they do not add overhead to regular builds.
- Directory Scoping: If multiple libraries are defined within the same
dunefile, the@dir/revdepalias covers the dependents of any library in that directory.
What are sites in Dune?
mainSites are locations used when a package requires additional resources outside its primary binary. A site can be defined by a package and corresponds to a list of directories that act like layers; the first directories in the list have higher priority. This mechanism is useful for plugins or packages that need to add resources to other packages.Use special variables to refer to compilation artifacts
mainDune provides special variables to refer to individual compilation artifacts without needing to know Dune's internal naming conventions or directory layouts. These variables follow the format
%{<ext>:<path>}, where<path>is interpreted relative to the current directory.Usage Rules:
- They can be used anywhere a dependency specification is expected.
- They can be used inside
actions(e.g., in apostorprestanza). When used inside an action, they implicitly declare a dependency on that artifact. - The expanded path always points inside the build context (e.g.,
_build/<context>).