ocaml / ocamlfind

The OCaml findlib library manager
Other
30 stars 30 forks source link

Overhaul the detection of separately-installed packages #12

Closed dra27 closed 3 years ago

dra27 commented 3 years ago

This PR fixes two problems. Since 4.08 it's been possible to disable all of the "otherlibraries" individually (bigarray, unix, etc.) - it's always been possible to do by editing Makefile.config. ocamlfind requires the Unix library, and this is now checked by configure.

However, it fixes a bigger problem, demonstrated by this Dockerfile (courtesy of @kit-ty-kate, as was nailing down the cause of this problem!):

FROM ocaml/opam:debian-10-opam
RUN opam switch create numbug ocaml-base-compiler.4.05.0
RUN sudo apt-get install -yy m4
ENV OPAMPRECISETRACKING=1
RUN opam install -y num.0
RUN opam install -y ocamlfind
RUN opam exec -- ocamlfind query num
RUN opam reinstall -y ocamlfind
RUN opam exec -- ocamlfind query num

The problem occurs in opam because ocamlfind is built before the installed ocamlfind is removed and so configure detects things about the installation and makes incorrect assumptions about separately installed packages. In this case, at the opam reinstall stage configure will incorrectly determine that num is available as a separate package, despite it having been installed by the previous opam install ocamlfind.

However, this just as readily happens if you build findlib "by hand" (e.g. if upgrading) and affects ocamlbuild, camlp4 and dbm in the same way.

The fundamental problem is that configure cannot infer the existence of a META file in the installation as meaning that the package was installed separately - it's a flawed assumption. The fix I propose here is in two parts: a fix to the problem, and compatibility with existing installations.

configure now generates the list of META files in site-lib-src which have been generated. This list is written to Makefile.packages and this file is installed as part of the findlib ocamlfind package. If configure detects this file in this installation then it will parse the single line from it to get the list of generated META files which were installed by the previous findlib. That knowledge is then used to prune the list of META files which configure will generate. For OCaml < 4.06, this means that num and num-top are always generated while keeping the correct behaviour for 4.06+. It's also generic and ready for any future removals from OCaml (even the stdlib and compiler-libs!!).

This obviously doesn't work for existing installations. Here, configure notes that the sitelib directory exists - i.e. that there is an installation already and continues as normal. For OCaml 4.06+, this will cause configure to generate the num META files (and build num-top). However, just prior to make install (or make uninstall) the sitelib is rescanned and the list pruned if separately installed META files are detected.

The detection works by looking for the characteristic "[distributed with Ocaml]" line. The reason for doing it just prior to make install is paranoia - doing it at install instead of configure really guarantees that if META was there at configure for a package then it will definitely still be there afterwards too!

gerdstolpmann commented 3 years ago

This is a great idea. i like it.