python311Packages.{pytensor,pymc}: fix hash (#357486)
[NixPkgs.git] / doc / languages-frameworks / ocaml.section.md
blobacefddc7c2f23084ef3ea2e5579a63567516d34d
1 # OCaml {#sec-language-ocaml}
3 ## User guide {#sec-language-ocaml-user-guide}
5 OCaml libraries are available in attribute sets of the form `ocaml-ng.ocamlPackages_X_XX` where X is to be replaced with the desired compiler version. For example, ocamlgraph compiled with OCaml 4.12 can be found in `ocaml-ng.ocamlPackages_4_12.ocamlgraph`. The compiler itself is also located in this set, under the name `ocaml`.
7 If you don't care about the exact compiler version, `ocamlPackages` is a top-level alias pointing to a recent version of OCaml.
9 OCaml applications are usually available top-level, and not inside `ocamlPackages`. Notable exceptions are build tools that must be built with the same compiler version as the compiler you intend to use like `dune` or `ocaml-lsp`.
11 To open a shell able to build a typical OCaml project, put the dependencies in `buildInputs` and add `ocamlPackages.ocaml` and `ocamlPackages.findlib` to `nativeBuildInputs` at least.
12 For example:
13 ```nix
14 let
15  pkgs = import <nixpkgs> {};
16  # choose the ocaml version you want to use
17  ocamlPackages = pkgs.ocaml-ng.ocamlPackages_4_12;
19 pkgs.mkShell {
20   # build tools
21   nativeBuildInputs = with ocamlPackages; [ ocaml findlib dune_2 ocaml-lsp ];
22   # dependencies
23   buildInputs = with ocamlPackages; [ ocamlgraph ];
25 ```
27 ## Packaging guide {#sec-language-ocaml-packaging}
29 OCaml libraries should be installed in `$(out)/lib/ocaml/${ocaml.version}/site-lib/`. Such directories are automatically added to the `$OCAMLPATH` environment variable when building another package that depends on them or when opening a `nix-shell`.
31 Given that most of the OCaml ecosystem is now built with dune, nixpkgs includes a convenience build support function called `buildDunePackage` that will build an OCaml package using dune, OCaml and findlib and any additional dependencies provided as `buildInputs` or `propagatedBuildInputs`.
33 Here is a simple package example.
35 - It defines an (optional) attribute `minimalOCamlVersion` (see note below)
36   that will be used to throw a descriptive evaluation error if building with
37   an older OCaml is attempted.
39 - It uses the `fetchFromGitHub` fetcher to get its source.
41 - It also accept `duneVersion` parameter (valid value are `"1"`, `"2"`, and
42   `"3"`). The recommended practice it to set only if you don't want the default
43   value and/or it depends on something else like package version. You might see
44   a not-supported argument `useDune2`. The behavior was `useDune2 = true;` =>
45   `duneVersion = "2";` and `useDune2 = false;` => `duneVersion = "1";`. It was
46   used at the time when dune3 didn't existed.
48 - It sets the optional `doCheck` attribute such that tests will be run with
49   `dune runtest -p angstrom` after the build (`dune build -p angstrom`) is
50   complete, but only if the Ocaml version is at at least `"4.05"`.
52 - It uses the package `ocaml-syntax-shims` as a build input, `alcotest` and
53   `ppx_let` as check inputs (because they are needed to run the tests), and
54   `bigstringaf` and `result` as propagated build inputs (thus they will also be
55   available to libraries depending on this library).
57 - The library will be installed using the `angstrom.install` file that dune
58   generates.
60 ```nix
61 { lib,
62   fetchFromGitHub,
63   buildDunePackage,
64   ocaml,
65   ocaml-syntax-shims,
66   alcotest,
67   result,
68   bigstringaf,
69   ppx_let }:
71 buildDunePackage rec {
72   pname = "angstrom";
73   version = "0.15.0";
75   minimalOCamlVersion = "4.04";
77   src = fetchFromGitHub {
78     owner  = "inhabitedtype";
79     repo   = pname;
80     rev    = version;
81     hash   = "sha256-MK8o+iPGANEhrrTc1Kz9LBilx2bDPQt7Pp5P2libucI=";
82   };
84   checkInputs = [ alcotest ppx_let ];
85   buildInputs = [ ocaml-syntax-shims ];
86   propagatedBuildInputs = [ bigstringaf result ];
87   doCheck = lib.versionAtLeast ocaml.version "4.05";
89   meta = {
90     homepage = "https://github.com/inhabitedtype/angstrom";
91     description = "OCaml parser combinators built for speed and memory efficiency";
92     license = lib.licenses.bsd3;
93     maintainers = with lib.maintainers; [ sternenseemann ];
94   };
96 ```
98 Here is a second example, this time using a source archive generated with `dune-release`. It is a good idea to use this archive when it is available as it will usually contain substituted variables such as a `%%VERSION%%` field. This library does not depend on any other OCaml library and no tests are run after building it.
100 ```nix
101 { lib, fetchurl, buildDunePackage }:
103 buildDunePackage rec {
104   pname = "wtf8";
105   version = "1.0.2";
107   minimalOCamlVersion = "4.02";
109   src = fetchurl {
110     url = "https://github.com/flowtype/ocaml-${pname}/releases/download/v${version}/${pname}-v${version}.tbz";
111     hash = "sha256-d5/3KUBAWRj8tntr4RkJ74KWW7wvn/B/m1nx0npnzyc=";
112   };
114   meta = {
115     homepage = "https://github.com/flowtype/ocaml-wtf8";
116     description = "WTF-8 is a superset of UTF-8 that allows unpaired surrogates";
117     license = lib.licenses.mit;
118     maintainers = [ lib.maintainers.eqyiel ];
119   };
123 The build will automatically fail if two distinct versions of the same library
124 are added to `buildInputs` (which usually happens transitively because of
125 `propagatedBuildInputs`). Set `dontDetectOcamlConflicts` to true to disable this
126 behavior.