Skip to content

Commit d90fe69

Browse files
committed
Add post about portable lock directories in dune
Signed-off-by: Stephen Sherratt <[email protected]>
1 parent b3b5fb0 commit d90fe69

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
title: Portable Lock Directories for Dune Package Management
3+
tags: [dune, developer-preview]
4+
---
5+
6+
_Discuss this post on [Discuss](https://discuss.ocaml.org/t/portable-lock-directories-for-dune-package-management/16669)!_
7+
8+
We've recently made a change to how lock directories work in the [Dune Developer
9+
Preview](https://preview.dune.build/).
10+
11+
Previously when Dune would solve dependencies for a project and generate a lock
12+
directory, the lock directory would be specialized for the computer where it was
13+
generated, with no guarantee it would work on a different computer. This posed a
14+
problem for checking lock directories into version control for projects with
15+
multiple developers, since one developer might lock the project on their Mac,
16+
say, only for another developer on Linux to be unable to build it due to its
17+
MacOS-specific lock directory.
18+
19+
This post is to announce that Dune now supports generating _portable_ lock
20+
directories; a lock directory generated on one computer will now contain a
21+
dependency solution for a range of different computers, making it safe to check
22+
lock directories into version control.
23+
24+
## Technical Details
25+
26+
In Opam the dependencies of a package can be different depending on properties
27+
of the computer where the package is being installed. A package might have a
28+
different set of dependencies when being installed on MacOS verses Linux verses
29+
Windows, or the dependencies might vary depending on the CPU architecture. It's
30+
even possible (though quite rare in practice) for the dependencies of a package
31+
to vary between operating system distributions, or even operating system
32+
versions.
33+
34+
This expressive power makes Opam very flexible as it allows packages to be
35+
specialized for the environment where they will be installed. The drawback of
36+
this approach is that there might not be a single solution to a dependency
37+
problem that works everywhere. Each combination of
38+
OS/architecture/distro/version could, in theory, require a different dependency
39+
solution. There are way too many combinations of those properties to run Dune's
40+
dependency solver once for each combination in a reasonable amount of time.
41+
Instead we elected to compromise and have Dune only generate a solution for
42+
common platforms by default, while allowing users to specify a custom list of
43+
platforms to solve for in their `dune-workspace` file.
44+
45+
Lockfiles now look a little different to account for the fact that they now
46+
contain multiple different platform-specific dependency solutions. For example,
47+
formerly, the lockfile for the `ocaml-compiler` package on an x86 machine running
48+
Windows, you might have had a `depends` field like:
49+
50+
```scheme
51+
(depends arch-x86_64 system-mingw mingw-w64-shims flexdll)
52+
```
53+
54+
Most of these dependencies are specific to Windows; it's unlikely that you'll be
55+
able to install any of these dependencies on Linux or MacOS.
56+
57+
With the portable lock directories feature enabled, this field now might look like:
58+
59+
```scheme
60+
(depends
61+
(choice
62+
((((arch x86_64)
63+
(os linux))
64+
((arch arm64)
65+
(os linux))
66+
((arch x86_64)
67+
(os macos)
68+
(os-distribution homebrew)
69+
(os-family homebrew))
70+
((arch arm64)
71+
(os macos)
72+
(os-distribution homebrew)
73+
(os-family homebrew)))
74+
())
75+
((((arch x86_64)
76+
(os win32)
77+
(os-distribution cygwin)
78+
(os-family windows)))
79+
(arch-x86_64 system-mingw mingw-w64-shims flexdll))
80+
((((arch arm64)
81+
(os win32)
82+
(os-distribution cygwin)
83+
(os-family windows)))
84+
(system-mingw mingw-w64-shims flexdll))))
85+
```
86+
87+
This new syntax is similar to a match-statement, listing the dependencies for
88+
each platform for which Dune's solver ran. You can change the platforms Dune
89+
will solve for by adding something like this to `dune-workspace`:
90+
91+
```scheme
92+
(lock_dir
93+
(solve_for_platforms
94+
((arch arm64)
95+
(os openbsd))
96+
((arch x86_32)
97+
(os win32))))
98+
```
99+
100+
After running `dune pkg lock` again, the lockfile for `ocaml-compiler` will be
101+
updated with these dependencies:
102+
103+
```scheme
104+
(depends
105+
(choice
106+
((((arch arm64) (os openbsd))) ())
107+
((((arch x86_32)
108+
(os win32)))
109+
(system-mingw ocaml-option-bytecode-only flexdll))))
110+
```
111+
112+
A few other fields of lockfiles now also use the new syntax. Dune lockfiles
113+
contain the commands needed to build and install each package, as well as the
114+
names of any system packages needed by the Opam package, and each of these fields
115+
can also have platform-specific values.
116+
117+
Lockfile names now include the version number of the package. The
118+
`ocaml-compiler` package used to have a lockfile named `ocaml-compiler.pkg` but
119+
now has a name like `ocaml-compiler.5.3.0.pkg` instead. This is because it's
120+
possible that different platforms may require different versions of the same
121+
package in the dependency solution, so the lock directory needs to be able to
122+
contain multiple lockfiles for the same package without them colliding on
123+
filename.
124+
125+
## How do I get it?
126+
127+
This feature is live in the latest version of the [Dune Developer
128+
Preview](https://preview.dune.build/). Follow the instructions on that page to
129+
install a version of Dune with this feature. With portable lock directories
130+
enabled, Dune will temporarily remain backwards compatible with the original
131+
lock directory format, though support will likely be dropped at some point.
132+
Generate a new lock directory by running `dune pkg lock`. You'll know your lock
133+
directory is portable if each file inside it has a version number in its
134+
filename.
135+
136+
Happy reproducible building!

0 commit comments

Comments
 (0)