Skip to content

Commit

Permalink
Document incremental build solutions with opam
Browse files Browse the repository at this point in the history
  • Loading branch information
lthls committed Jun 3, 2020
1 parent 0ca651b commit bfb9441
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions HACKING.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,74 @@ opam switch create my-switch-name --empty
opam pin add ocaml-variants.$VERSION+branch git+https://$REPO#branch
----

=== Incremental builds with `opam`

If you want to fix a bug that needs opam packages to reproduce, or want to try
a new feature that you're still actively developing on opam packages, you will
likely need a faster feedback loop than re-creating a new switch or recompiling
every package each time you make a small change to your code.

There are two mostly orthogonal steps you can take to accelerate this:
- Use your locally built copy, and only run the install step
- Prevent your changes from automatically triggering the rebuild of all packages

For the first step, one solution is to use the `--assume-built` flag to
`opam install` to skip the compilation and only run the installation instructions.
This, however, requires that your working directory is in a state suitable for
running `make install`. This means it should be configured to the correct prefix,
have all the programs that need to be installed built (including `ocamldoc`,
the `otherlibs` libraries, and `tools`, if you want to install them), and
you need to be sure that there aren't any mismatch between bytecode and native
versions of the binaries. If you don't want to rebuild the native versions,
you need to ensure they get removed before running the install steps.

Here are some sample instructions using the setup from above:

-----
-opam switch create . --empty
# Using --inplace-build ensures the working directory is configured properly
-opam install . --inplace-build
# Now you can edit the compiler's files, compile locally, then when you're ready:
-opam reinstall . --assume-built
-----
Note that `--assume-built` has bugs in the versions of opam up to 2.1~alpha1,
so you may need a very specific version to get this to work.

The second step is not supported directly by opam. Fortunately, for the compiler
we can take advantage of the way the various compiler-related packages are setup:
there is one main package, `ocaml`, that most packages depends on, and specific
packages like `ocaml-variants` or `ocaml-system`, that `ocaml` depends on that
will do the actual building and installation. By modifying the dependency in
the `ocaml` package to a build-only dependency, reinstallation of the
`ocaml-variants` package will not trigger reinstallation of the `ocaml`
package anymore, saving us from having to recompile the whole world.
The drawback is that if you're not careful you could end up removing the
`ocaml-variants` package, leaving you with a broken switch, or installing a
compiler that has a different format for compilation artifacts, that will
fail with strange errors when you try to read the artifacts already present.

To do this, you can either copy the official `ocaml.opam` file locally and
modify it, or pin and edit the `ocaml` package from the default repository.

Assuming the second solution, this can be done with:
-----
-opam pin edit ocaml
# Here opam will prompt you for an editor, and will open a file for you to modify.
# You should modify the depends: fields in the following way:
# Add the condition { build } after the "ocaml-config" package
# Adapt the condition on ocaml-variants by appending & build
# Save and exit your editor
-----
After this step, you will need to rebuild all packages once because the `ocaml`
package has changed, so it's better to do it before installing packages.

You also need to modify the file `ocaml-variants.opam` so that the `{ = "x.xx.x" & post }`
condition attached to the `ocaml` dependency is replaced by `{ = "x.xx.x" & post & build }`.

Now, you should be able to reinstall new versions of the compiler without requiring
a full recompilation. You can always require recompilation of individual packages
using `opam reinstall <package>`, or of all packages using `opam reinstall ocaml`.

=== Useful Makefile targets

Besides the targets listed in link:INSTALL.adoc[] for build and
Expand Down

0 comments on commit bfb9441

Please sign in to comment.