I finally found a way to get it working.
To be sure to have a platform like in the old days, I created a machine with systemd-nspawn as explained there and set up a Ubuntu bionic (18.04) machine.
In that machine, I installed the latest revision of opam : I tried opam 2.0, but it could not solve the dependencies for installing utop.
I clone the ocaml repo in some folder. Therein, I prepared a base opam switch
opam init --bare # answer yes to setup questions
opam repository add archive git+https://github.com/ocaml/opam-repository-archive --set-default
opam switch create . --empty
eval $(opam env)
opam install ocaml=4.07.1 ocaml-base-compiler=4.07.1 --fake
Since opam does not do it, I manually added a file _opam/share/ocaml-config/gen_ocaml_config.ml
with content
let () =
let ocaml_version =
let v = Sys.ocaml_version in
try String.sub v 0 (String.index v '+') with Not_found -> v
in
if ocaml_version <> Sys.argv.(1) then
(Printf.eprintf
"OCaml version mismatch: %s, expected %s"
ocaml_version Sys.argv.(1);
exit 1)
else
let oc = open_out (Sys.argv.(2) ^ ".config") in
let exe = ".exe" in
let (ocaml, suffix) =
let s = Sys.executable_name in
if Filename.check_suffix s exe then
(Filename.chop_suffix s exe, exe)
else
(s, "")
in
let ocamlc = ocaml^"c"^suffix in
let libdir =
if Sys.command (ocamlc^" -where > where") = 0 then
(* Must be opened in text mode for Windows *)
let ic = open_in "where" in
let r = input_line ic in
close_in ic; r
else
failwith "Bad return from 'ocamlc -where'"
in
let stubsdir =
let ic = open_in (Filename.concat libdir "ld.conf") in
let rec r acc = try r (input_line ic::acc) with End_of_file -> acc in
let lines = List.rev (r []) in
close_in ic;
String.concat ":" lines
in
let p fmt = Printf.fprintf oc (fmt ^^ "\n") in
p "opam-version: \"2.0\"";
p "variables {";
p " native: %b"
(Sys.file_exists (ocaml^"opt"^suffix));
p " native-tools: %b"
(Sys.file_exists (ocamlc^".opt"^suffix));
p " native-dynlink: %b"
(Sys.file_exists (Filename.concat libdir "dynlink.cmxa"));
p " stubsdir: %S"
stubsdir;
p " preinstalled: false";
p " compiler: \"4.07.1\"";
p "}";
close_out oc
and a file _opam/.opam-switch/config/ocaml.config
with content (you will need to adapt the paths)
opam-version: "2.0"
variables {
native: true
native-tools: true
native-dynlink: true
stubsdir:
"/home/yann/ocaml/_opam/lib/ocaml/stublibs:/home/yann/ocaml/_opam/lib/ocaml"
preinstalled: false
compiler: "4.07.1"
}
I added the things that will be needed later, and copied the whole thing to another directory to avoid doing this step each time (I had to specify the version for dune because opam would try to install a later version that uses Unix.open_process_args_out
, which was added in 4.08 and does not exist for all of the commits I am interested in — I wonder why opam does that since it believes it has a 4.07.1 compiler) :
opam install ocaml-secondary-compiler
opam install utop=2.9.2 dune=2.9.3 --download-only
cp -r _opam ../baseswitch
Then we start bisecting :
git bisect start
git bisect good 4.07.1
git bisect bad 4.08.0
git will checkout intermediate commits automatically.
Not sure if this is needed, but I manually modified the VERSION
file to pretend that this is version 4.07.1+dev0-2018-04-09
. Since this is an outstanding change in the working copy of the repo, git will not overwrite the file when bisecting, so no need to do it each time.
Then we setup everything, in one line so we do not have to attend it :
git clean -fxd && ./configure --prefix $PWD/_opam && make world.opt -j 4 && cp -r ../baseswitch/ _opam && make install && opam install utop=2.9.2 dune=2.9.3 --yes