Platforms, Packaging, Progress
Richard Mortier · August 28, 2017 · #tech #ocaml #opam #ocalI recently decided to refresh and update my ocal package,1 primarily to port it to use the excellent notty before adding support for indicating week-of-year. At the same time, I took the opportunity to update the build infrastructure now that the OCaml world has some shiny new packaging and build tools to go with OPAM, namely topkg
and jbuilder
. So, starting from Dave Scott’s wiki entry about how to package Mirage libraries, here’s what I had to do…
A somewhat over-featured replacement for the standard UNIX cal
utility, because I got irritated by its American-centricity and my initial Python replacement was just too slow…
Remove Oasis remnants
&& && &&
|
Although we’re removing the ocal.opam/descr
file, we’re not going to lose the content: we’re going to let topkg opam pkg
use its default --readme
option to extract the relevant info from the first marked up section of the README.md
:
We also remove but don’t lose the functionality of the .merlin
and OPAM ocal.install
files, as jbuilder will generate them for us.
Create src/jbuild
file
|
This corresponds to the 0.2.0 release of ocal. Note that the name
parameter refers to the module that contains the entrypoint for the executable, and that we turn on all warnings (A
) except for three that we wish to ignore:
44
: Open statement shadows an already defined identifier.48
: Implicit elimination of optional arguments.52
: (see 8.5.1) Fragile constant pattern.
After I did some tidying up of the code to deal with the newly imposed warnings, make
and make install
satisfactorily (and quickly!) used jbuilder to build and install the executable as ~/.opam/system/bin/ocal
(thanks to the public_name
stanza in the src/jbuild
file, above). make uninstall
then caused jbuilder to remove it, before I opam
pinned it and then reinstall through opam
to check that workflow worked as well:
Create the topkg
skeletons
Having refreshed the basic build infrastructure, next it’s time to update the packaging workflow. For a simple library we could use the automatic jbuilder/topkg plugin per the wiki entry:
|
However, this isn’t a library so we don’t have documentation to build so we don’t bother with the odoc
skeleton. As a result we also need to customise pkg/pkg.ml
so as to stop topkg publish
failing when it can’t build docs:
#!/usr/bin/env ocaml
#use "topfind"
#require "topkg-jbuilder"
let publish =
~artefacts: (
publish
let ( =
~publish (
describe
Prepare a release
Finally, we follow the standard topkg workflow to prepare a release. First, add an entry to CHANGES.md
with the correct formatting and commit the result, and then:
:
…which creates tokens for accessing the GitHub repo for this project (if they don’t already exist), creates a release tag based on entries in CHANGES.md
, and then creates the release tarballs (without the edits to pkg/pkg.ml
this would also build the docs, but we have none).
Publish a release
Finally, we publish the release to GitHub and issue a pull request to the OPAM repository to add the new release into OPAM after linting and tests have passed.
:
Given that this repo has only a single package, we could in fact simply issue
topkg tag && topkg bistro
Also, as an alternative to customising the pkg/pkg.ml
as indicated above, we could simply remember to indicate the appropriate customisation on the command line:
topkg publish distrib
…but topkg bistro
wouldn’t then work.
Conclusion
So that’s it: a simple executable distribution taken from old-school Oasis and OCamlBuild infrastructure to shiny new modern jbuilder and topkg. The new scheme seems to me to be an improvement: faster build times, simpler (to my eyes) metadata, autogeneration of more of the repeated metadata (.merlin
etc), and a reasonably simple Makefile
that I actually think I understand. Definitely progress :)