In this tutorial, you will learn how to initialize an OCaml project that can be developed using dune.
Initialize a new project
Section titled “Initialize a new project”Make
duneexecutable available:Terminal window nix shell nixpkgs#dune_3Scaffold a new project using
dune:Terminal window dune init proj 'package_name' 'your-new-project'Enter the project directory:
Terminal window cd 'your-new-project'
Add flake.nix to the project
Section titled “Add flake.nix to the project”Initialize the template from the root directory of the project:
Terminal window nix flake init -t github:akirak/flake-templates#ocaml-duneOpen
flake.nixand set thepnameandversionof the package to be built, e.g.:default = ocamlPackages.buildDunePackage {pname = throw "Name your OCaml package";pname = "hello";version = throw "Version your OCaml package";version = "0.1";duneVersion = "3";src = self.outPath;Add
.envrc:Terminal window use flakeAllow direnv:
Terminal window direnv allow
Developing
Section titled “Developing”Once the Nix shell is enabled, you can use dune inside the project directory, as you would do in a normal OCaml project.
Adding OCaml dependencies
Section titled “Adding OCaml dependencies”To add library dependencies to your OCaml project, follow this instruction. In this example, we will be adding cmdliner as a new dependency.
Add the libraries to
propagatedBuildInputs(orcheckInputsif it's a test dependency) attribute to your package:default = ocamlPackages.buildDunePackage {...src = self.outPath;propagatedBuildInputs = with ocamlPackages; [basecorecore_unixcmdliner];};Add them to
dependsfield of yourpackagein thedune-projectfile:(package(name hello)(allow_empty)(depends(ocaml (>= 4.08.0))(dune (>= 3.16))(cmdliner (>= 1.3.0))(alcotest :with-test)))Also add them to
librariesfield of a suitable stanza in the relevantdunefile.(library(public_name hello)(name hello)(libraries unix)(libraries unix cmdliner))
Adding OCaml dependencies for testing
Section titled “Adding OCaml dependencies for testing”To add dependencies for testing that are not required for production, follow this example. We will be adding alcotest and qcheck as test dependencies.
In
flake.nix, setdoChecktotruein the arguments tobuildDunePackage:default = ocamlPackages.buildDunePackage {...doCheck = true;};Also in the arguments, add
checkInputsfield which should be a list of test-only dependencies:default = ocamlPackages.buildDunePackage {...doCheck = true;checkInputs = with ocamlPackages; [alcotestqcheck-core];};If your
dune-projectfile contains one or morepackageentries, add the dependencies todependsfield of relevant package. The dependencies should have:with-testoption:(package(name hello)(allow_empty)(depends(ocaml (>= 4.08.0))(dune (>= 3.16))(cmdliner (>= 1.3.0)); test-only dependency(alcotest :with-test); test-only dependency with a version constraint(qcheck-core (and :with-test (>= 0.19)))...))Also add the dependencies to the
dunefile for testing (typicallytest/dune):(test(name test_hello)(librariesalcotestqcheck-core))
Generating documentation for the dependencies
Section titled “Generating documentation for the dependencies”To generate documentation of the dependencies, use odig.
To generate a documentation, use a
justfilerecipe bundled in the template:Terminal window just odig-odocTo search through the documentation, you can run a local instance of sherlodoc or open a generated HTML file directly.
Running sherlodoc
Section titled “Running sherlodoc”To run sherlodoc, follow this instruction.
Enable
sherlodocin theflake.nix:devShells = eachSystem ({ pkgs, ocamlPackages, ... }:{default = pkgs.mkShell {inputsFrom = [ self.packages.${pkgs.system}.default ];buildInputs = (with ocamlPackages;[ocaml-lspocamlformatocp-indent...# (sherlodoc.override { enableServe = true; })(sherlodoc.override { enableServe = true; })])# ++ lib.optional pkgs.stdenv.isLinux pkgs.inotify-tools;};});Run
sherlodoc indexon*.odoclfiles. The template contains ajustfilerecipe, so you can just run:Terminal window just sherlodoc-indexTo browse the documentation, use a justfile recipe:
Terminal window just sherlodoc-serve
For a detailed description, consult the documentation of sherlodoc.