Proposal: exports
field in findlib
META files
Note: in what follows I use, following dune
terminology, the term library names for what is formally ocamlfind
package names.
Recently I have deprecated a few libraries names in some packages. Namely vg.svg
, uunf.string
and uuseg.string
.
To do so I made empty libraries in the META
files installed by these packages. These empty libraries simply requires
their replacement library and warn on usage with a warning
field (sample).
However this can’t work if you have a build system with correct dependencies – a.k.a implicit_transitive_deps
set to false
in dune
.
In this mode the includes (-I
) of the requires
of a specified library dependency are not added during the compilation phase. So using the requires
field to proxy a library for another one can’t work.
While it seems that correct dependencies break in all sorts of obscure ways, upstream has integrated support for hidden includes (-H
) in the upcoming OCaml 5.2. But in order to be able to proper use it we need to extend the metadata we keep about libraries to know which of the libraries need to be included with -H
and those that need to be included with -I
.
Proposal
Add an exports
field to META
files which has exactly the same syntax as requires
, a list of library names. Libraries mentioned in a library’s requires
are not exposed to code compiling against the library while those in exports
are.
In the compilation phase this means that libraries mentioned in requires
get included with -H
while those in exports get included with -I
.
More precisely the semantics of requires
and exports
are as a follows.
Compiling with correct dependencies (OCaml >= 5.2)
Given a sequence of library names libs
to compile and link against.
Let exported_libs
be the smallest set of library names that includes libs
, and their
transitive exports
.
Let hidden_libs
be the smallest set of library names that includes the transitive requires
of libs
, the transitive requires
of the exports
of libs
and the transitive exports
of any library found in requires
that are not in exported_libs
.
-
Compilation phase. For each library in the set of
exported_libs
we include its library directory with a-I
. For each of library inhidden_libs
with include its library directory with a-H
. -
Linking phase. The library archives of
hidden_libs
andexported_libs
need to be provided, sorted in stable topological order.
Compiling with incorrect dependencies (OCaml < 5.2)
Given a sequence of library names libs
to compile and link against.
Let overshoot_libs
be the smallest set of library names that includes libs
and their transitive exports
and requires
library names.
-
Compilation phase. For each of the library in the set
overshoot_libs
we include its library directory with-I
. -
Linking phase. The library archives of
overshoot_libs
need to be provided, sorted in stable topological order.
Backward compatibility
For backward compatibility with systems that do not understand exports
and are oblivious of -H
. In META
files, the library names mentioned in the exports
field of a library must be replicated in its requires
field. Implementers of correct dependencies must remove from requires
the names that exist in exports
.
Since ocamlfind
doesn’t mind fields it doesn’t know, no changes are immediately needed in ocamlfind
and the proposal can be used from now on.
Usage
The exports
field can be used for two things:
- Along with a
warning
field a library name can be deprecated and be transparently replaced by a list of other libraries. - A library name can be defined to define a “meta” library which represents a bunch of other libraries against which to compile and link. This library can also provide code itself.
Note that these two usages formally existed in the incorrect dependency world but is no longer possible in the correct dependency world. The exports
field allows to bring it back.
37 posts - 8 participants