Toolchain = compiler + tools that must match the project's OCaml version.
Dune manages toolchains transparently: download, build, cache, and select the right compiler for each build context.
| Source | Description | Use Case |
|---|---|---|
| System | OCaml from PATH | Quick builds, system-managed compiler |
| Locked | From dune.lock |
Reproducible builds, pinned compiler version |
| Workspace | Built from workspace sources | Compiler development, custom patches |
- Explicit
(toolchain ...)in dune-project - Locked compiler in
dune.lock - System compiler from PATH
; dune-project
(lang dune 3.18)
(package
(name my-project)
(depends
(ocaml (>= 5.2))))After dune pkg lock, the compiler is locked like any other package.
For compiler development or custom patches:
; dune-project
(lang dune 3.18)
(toolchain
(source workspace)
(package ocaml))This builds the compiler from workspace sources (e.g., vendored or local).
; dune-project
(lang dune 3.18)
(toolchain
(source system))Uses whatever ocaml is in PATH. No version management.
Locked toolchains are built as relocatable: they work from any installation path.
~/.cache/dune/
├── db/files/v5/<hash>/ # Content-addressed compiler
└── index/
└── ocaml.5.2.0-a1b2c3d4 -> ../db/files/v5/<hash>
Benefits:
- Share compiled toolchains across projects
- No recompilation when moving projects
- Works with dune's content-addressed cache
Dune patches the compiler during build:
- Relative paths for stdlib lookup
OCAMLLIBenvironment variable support- Wrapper scripts that set up the environment
For targeting multiple platforms from one host:
; dune-project
(lang dune 3.18)
(toolchain
(name native))
(toolchain
(name windows)
(target x86_64-w64-mingw32)); dune-workspace
(context
(default
(targets native windows)))This creates two build contexts:
_build/default/- native compilation_build/default.windows/- cross-compiled for Windows
For each context, dune selects the appropriate toolchain:
| Context | Toolchain | OCAMLFIND_TOOLCHAIN |
|---|---|---|
default |
native |
(not set) |
default.windows |
windows |
windows |
_build/
├── .toolchains/
│ ├── native/ # Native compiler install
│ └── windows/ # Cross-compiler install
├── default/ # Native build output
└── default.windows/ # Cross-compiled output
Packages that provide toolchain components use the (toolchain) field:
; duniverse/dune
(vendor ocaml.5.2.0
(toolchain native))
(vendor ocaml-windows.5.2.0
(toolchain windows))Dune builds toolchain packages first, before any other packages.
dune toolchain list # Show available toolchains
dune toolchain which # Show active toolchain for context
dune toolchain exec -- ocaml # Run command with toolchain in PATHShould toolchains have separate lock files from project dependencies?
dune.lock # Project dependencies
dune.toolchain.lock # Compiler and build tools
This would allow updating project deps without re-locking the compiler.
With relocatable compilers cached globally, multiple workspaces can share the same compiled toolchain. Should dune expose this explicitly?
dune toolchain install ocaml.5.2.0 # Pre-install for sharing