| name | ocaml-dune-migration |
| description | Migrating OCaml projects from ocamlbuild/topkg to dune. Use when discussing _tags files, .mllib files, pkg/pkg.ml, topkg, or build system migration. |
| license | ISC |
OCaml Build System Migration
When to Use This Skill
Invoke this skill when:
- Converting a project from ocamlbuild to dune
- Discussing _tags, .mllib, or pkg.ml files
- Migrating from topkg to dune
- Understanding ocamlbuild artifacts
Process Overview
1. Analyze the Existing Build
Read these files to understand the project:
_tags- ocamlbuild compilation flags and package dependenciespkg/pkg.ml- topkg package descriptionpkg/META- findlib metadata*.mllibfiles - module lists for librariesopam- package dependencies
2. Create dune-project
(lang dune 3.20)
(name <package-name>)
(generate_opam_files true)
3. Create Library dune Files
For each library (from .mllib files):
(library
(name <library_name>)
(public_name <package.subname>)
(libraries <dependencies>))
For optional libraries (from pkg/pkg.ml):
(library
(name <library_name>)
(public_name <package.subname>)
(optional)
(libraries <dependencies>))
4. Handle Toplevel Init Files
Files like *_top_init.ml shouldn't be compiled as modules:
(library
(name lib_name)
(modules lib_module) ; Explicitly list modules
(libraries deps))
(install
(package pkg)
(section lib)
(files lib_top_init.ml))
5. Handle Warnings
If the original code triggers warnings:
(library
(name lib)
(flags (:standard -w -27)))
Common warnings to suppress in vendored code:
-w -27- unused variable
6. Create Test dune File
(test
(name test_name)
(libraries lib_name alcotest))
For optional tests:
(executable
(name test_optional)
(modules test_optional)
(optional)
(libraries lib some_optional_lib))
7. Update opam File
- Rename
opamto<package>.opam - Remove ocamlbuild/topkg dependencies
- Add dune:
depends: [
"ocaml" {>= "4.14.0"}
"dune" {>= "3.0"}
]
- Update build commands:
build: [
["dune" "subst"] {dev}
["dune" "build" "-p" name "-j" jobs]
["dune" "runtest" "-p" name "-j" jobs] {with-test}
["dune" "build" "@doc" "-p" name "-j" jobs] {with-doc}
]
8. Documentation dune File
If there's a doc/ directory:
(documentation
(package <package-name>))
9. Remove ocamlbuild Files
Files to delete:
_tags.merlinpkg/pkg.mlpkg/META*.mllibfiles*.itargetfiles- The
pkg/directory
Mapping Reference
| ocamlbuild | dune |
|---|---|
_tags: package(foo) |
(libraries foo) |
_tags: thread |
(libraries threads) |
foo.mllib with Foo |
(library (name foo) (modules foo)) |
pkg/pkg.ml: Pkg.mllib ~cond:x |
(library ... (optional)) |
pkg/META |
Auto-generated by dune |
opam |
<package>.opam |
Common Issues
"Library not found" for optional deps
Use (optional) on the library stanza.
Unused variable warnings
Add (flags (:standard -w -27)).
Module in wrong library
Use (modules ...) to explicitly list modules.
Toplevel init files
Exclude from library with (modules ...) and use (install ...).
Verification
After migration:
dune build @check # Verify syntax
dune build # Build project
dune runtest # Run tests
dune build @doc # Build docs