OCaml: Difference between revisions
Updated OCaml language by providing additional references to Nixpkgs manual. |
Clarified interaction with Opam. |
||
| Line 1: | Line 1: | ||
[[File:OCaml Logo.svg|alt=The OCaml logo: an orange background with a white foreground of a camel.|thumb|OCaml logo]] | [[File:OCaml Logo.svg|alt=The OCaml logo: an orange background with a white foreground of a camel.|thumb|OCaml logo]] | ||
According to the official [ocaml.org Ocaml website]:<blockquote> | According to the official [ocaml.org Ocaml website]:<blockquote> | ||
| Line 9: | Line 7: | ||
Most packages related to OCaml, in particular the OCaml compiler and many libraries, belong to the | Most packages related to OCaml, in particular the OCaml compiler and many libraries, belong to the <code>ocamlPackages</code> attribute set of nixpkgs. Tools for OCaml development are, in particular, available: | ||
* the [https://dune.build/ dune] builder; | * the [https://dune.build/ dune] builder; | ||
| Line 16: | Line 14: | ||
=== Build tooling === | === Build tooling === | ||
Modern development | Modern development in OCaml tend to use <code>dune</code>, a build system dedicated for OCaml projects. Nixpkgs provide a dedicated helper [https://nixos.org/manual/nixpkgs/stable/#sec-language-ocaml-packaging buildDuneProject] to facilitate integration with <code>dune</code>. | ||
An example minimal flake for OCaml development is available below: | |||
{{Code|1=// flake.nix | |||
{ | |||
description = "Minimal flake for OCaml projects."; | |||
inputs = { | |||
flake-utils.url = "github:numtide/flake-utils"; | |||
nixpkgs.url = "nixpkgs"; | |||
}; | |||
outputs = | |||
{ | |||
self, | |||
flake-utils, | |||
nixpkgs, | |||
... | |||
}: | |||
flake-utils.lib.eachDefaultSystem ( | |||
system: | |||
let | |||
pkgs = nixpkgs.legacyPackages.${system}; | |||
in | |||
{ | |||
packages = { | |||
default = | |||
buildDunePackage { | |||
pname = "My Ocaml Package"; | |||
duneVersion = "3"; | |||
version = "0.1"; | |||
minimalOCamlVersion = "4.14"; | |||
installTargets = "all doc"; | |||
src = ./.; | |||
nativeBuildInputs = with p; [ | |||
dune_3 | |||
]; | |||
}; | |||
}; | |||
devShells = { | |||
default = pkgs.mkShell { | |||
name = "Ocaml development shell environment."; | |||
inputsFrom = [ self.packages.${system}.default ]; | |||
packages = with pkgs.ocaml-ng.ocamlPackages; [ | |||
ocamlformat | |||
ocaml-lsp | |||
utop | |||
pkgs.gnumake | |||
]; | |||
shellHook = '' | |||
echo "Welcome in the devshell." | |||
''; | |||
}; | |||
}; | |||
} | |||
); | |||
}|lang=nix}} | |||
<code>nix develop</code> followed by <code>dune init project myproject</code> will drop you in a development shell. | |||
==== Opam ==== | |||
OCaml has its own package manager, [https://opam.ocaml.org/ opam]. Trying to use it imperatively with Nix will result in errors. However, <code>opam</code> can generate a <code>.opam</code> file, which can be ingested by tools like [https://github.com/tweag/opam-nix opam-nix] to automatically generate a Nix derivation. | |||
==== | ==== Manual build with ocamlc, findlib, ocamlfind ==== | ||
OCaml libraries are usually located using [http://projects.camlcity.org/projects/findlib.html findlib] and the associated | OCaml libraries are usually located using [http://projects.camlcity.org/projects/findlib.html findlib] and the associated <code>ocamlfind</code> tool. These tools are found under the <code>ocamlPackages.findlib</code> attribute and rely on the <code>OCAMLPATH</code> environment variable. | ||
A hook in the | A hook in the <code>findlib</code> package will automatically populate this variable with the paths to the other libraries. For instance, when starting a shell with | ||
<code>nix-shell --packages ocamlPackages.findlib ocamlPackages.batteries</code> | <code>nix-shell --packages ocamlPackages.findlib ocamlPackages.batteries</code> | ||
will set the | will set the <code>OCAMLPATH</code> variable so that <code>ocamlfind</code> can locate the <code>batteries</code> library. | ||
This hook also sets the | This hook also sets the <code>CAML_LD_LIBRARY_PATH</code> environment variable that is used for locating the dynamically loaded shared libraries (aka stublibs). | ||
=== Scripting with OCaml === | === Scripting with OCaml === | ||
| Line 46: | Line 100: | ||
<code>nix-env -iA nixpkgs.emacsPackagesNg.tuareg</code>. | <code>nix-env -iA nixpkgs.emacsPackagesNg.tuareg</code>. | ||
Emacs must be configured to be able to find this package: you may need to add a line like this to your | Emacs must be configured to be able to find this package: you may need to add a line like this to your <code>.emacs</code> file, somewhere between <code>(require 'package)</code> and <code>(package-initialize)</code>: | ||
<syntaxHighlight lang=emacs> | <syntaxHighlight lang=emacs> | ||
| Line 58: | Line 112: | ||
Beware that merlin is specific to one particular version of OCaml (it won’t work correctly with a compiler of a different version). | Beware that merlin is specific to one particular version of OCaml (it won’t work correctly with a compiler of a different version). | ||
To configure Emacs and enable the merlin mode, add the following to your | To configure Emacs and enable the merlin mode, add the following to your <code>.emacs</code>: | ||
<syntaxHighlight lang=emacs> | <syntaxHighlight lang=emacs> | ||
| Line 66: | Line 120: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
Also, a specific variable ( | Also, a specific variable (<code>merlin-command</code>) of the merlin mode must be overridden (its default is <code>opam</code>): | ||
<syntaxHighlight lang=emacs> | <syntaxHighlight lang=emacs> | ||
| Line 74: | Line 128: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
A useful complement to merlin is [https://www.typerex.org/ocp-indent.html '''ocp-indent'''], a customizable tool to indent OCaml code. It can be installed using <code>nix-env -iA nixpkgs.ocamlPackages.ocpIndent</code>. To enable it in Emacs, don’t forget to add the following line to your | A useful complement to merlin is [https://www.typerex.org/ocp-indent.html '''ocp-indent'''], a customizable tool to indent OCaml code. It can be installed using <code>nix-env -iA nixpkgs.ocamlPackages.ocpIndent</code>. To enable it in Emacs, don’t forget to add the following line to your <code>.emacs</code>: | ||
<syntaxHighlight lang=emacs> | <syntaxHighlight lang=emacs> | ||
| Line 81: | Line 135: | ||
=== Specific version of the OCaml compiler === | === Specific version of the OCaml compiler === | ||
Various versions of the | Various versions of the <code>ocamlPackage</code> attribute set are available, corresponding to various versions of OCaml. For instance, the attribute set <code>ocaml-ng.ocamlPackages_4_04</code> contains the OCaml compiler at version 4.04 and OCaml libraries compiled with that particular compiler. | ||
==== Custom version ==== | ==== Custom version ==== | ||
So as to get the set of OCaml libraries built with/for a custom version of the OCaml compiler, e.g., to enable | So as to get the set of OCaml libraries built with/for a custom version of the OCaml compiler, e.g., to enable <code>flambda</code> support, you may use the <code>ocamlPackages.overrideScope</code> function: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||