Skip to content

Commit f2e0079

Browse files
Stop calling ocamlfind to determine the library search/installation directory (#4281)
Signed-off-by: Jeremie Dimino <[email protected]>
1 parent 3e80d1c commit f2e0079

File tree

5 files changed

+87
-98
lines changed

5 files changed

+87
-98
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ Unreleased
6565

6666
- Enable cram tests by default (#4262, @rgrinberg)
6767

68+
- Stop calling `ocamlfind` to determine the library search path or
69+
library installation directory. This makes the behavior of Dune
70+
simpler and more reproducible (#...., @jeremiedimino)
71+
6872
2.8.2 (21/01/2021)
6973
------------------
7074

bin/install_uninstall.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ let get_dirs context ~prefix_from_command_line ~libdir_from_command_line =
1919
| None ->
2020
let open Fiber.O in
2121
let* prefix = Context.install_prefix context in
22-
let libdir =
22+
let+ libdir =
2323
match libdir_from_command_line with
2424
| None -> Memo.Build.run (Context.install_ocaml_libdir context)
2525
| Some l -> Fiber.return (Some (Path.relative prefix l))
2626
in
27-
let+ libdir = libdir in
2827
(prefix, libdir)
2928

3029
let resolve_package_install setup pkg =

doc/usage.rst

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -302,17 +302,24 @@ Finding external libraries
302302
When a library is not available in the workspace, dune will look it
303303
up in the installed world, and expect it to be already compiled.
304304

305-
It looks up external libraries using a specific list of search paths. A
306-
list of search paths is specific to a given build context and is
307-
determined as follows:
308-
309-
#. if the ``ocamlfind`` is present in the ``PATH`` of the context, use each line
310-
in the output of ``ocamlfind printconf path`` as a search path
311-
#. otherwise, if ``opam`` is present in the ``PATH``, use the output of ``opam
312-
config var lib``
313-
#. otherwise, take the directory where ``ocamlc`` was found, and append
314-
``../lib`` to it. For instance if ``ocamlc`` is found in ``/usr/bin``, use
315-
``/usr/lib``
305+
It looks up external libraries using a specific list of search paths
306+
and each build context has a specific list of search paths.
307+
308+
When running inside an opam environment, Dune will look for installed
309+
libraries in ``$OPAM_SWITCH_PREFIX/lib``. This includes both opam
310+
build context configured via the ``dune-workspace`` file and the
311+
default build context when the variable ``$OPAM_SWITCH_PREFIX`` is
312+
set.
313+
314+
Otherwise, Dune takes the directory where ``ocamlc`` was found, and
315+
append `../lib`` to it. For instance if ``ocamlc`` is found in
316+
``/usr/bin``, Dune looks for installed libraries in ``/usr/lib``.
317+
318+
In addition to the two above rules, Dune always inspect the
319+
``OCAMLPATH`` environment variable and use the paths defined in this
320+
variable. ``OCAMLPATH`` always has precedence and can have different
321+
value in different build contexts. For instance, you can set it
322+
manually in a specific build context via the ``dune-workspace`` file.
316323

317324
.. _running-tests:
318325

src/dune_rules/context.ml

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
467467
| None -> []
468468
| Some s -> Bin.parse_path s ~sep:ocamlpath_sep
469469
in
470-
let default_findlib_paths () =
470+
let default_library_search_path () =
471471
match Build_environment_kind.query ~kind ~findlib_toolchain ~env with
472472
| Cross_compilation_using_findlib_toolchain toolchain ->
473473
let ocamlfind = which_exn "ocamlfind" in
@@ -480,13 +480,8 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
480480
let p = Path.of_filename_relative_to_initial_cwd opam_prefix in
481481
let p = Path.relative p "lib" in
482482
Memo.Build.return [ p ]
483-
| Unknown -> (
484-
match which "ocamlfind" with
485-
| Some ocamlfind ->
486-
let env = Env.remove env ~var:"OCAMLPATH" in
487-
ocamlfind_printconf_path ~env ~ocamlfind ~toolchain:None
488-
| None ->
489-
Memo.Build.return [ Path.relative (Path.parent_exn dir) "lib" ] )
483+
| Unknown ->
484+
Memo.Build.return [ Path.relative (Path.parent_exn dir) "lib" ]
490485
in
491486
let ocaml_config_ok_exn = function
492487
| Ok x -> x
@@ -500,7 +495,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
500495
User_error.raise ~loc:(Loc.in_file file) [ Pp.text msg ]
501496
in
502497
let* default_ocamlpath, (ocaml_config_vars, ocfg) =
503-
Memo.Build.fork_and_join default_findlib_paths (fun () ->
498+
Memo.Build.fork_and_join default_library_search_path (fun () ->
504499
let+ lines =
505500
Memo.Build.of_fiber
506501
(Process.run_capture_lines ~env Strict ocamlc [ "-config" ])
@@ -885,25 +880,10 @@ module DB = struct
885880
end
886881

887882
let install_ocaml_libdir t =
888-
match (t.kind, t.findlib_toolchain, Setup.library_destdir) with
889-
| Default, None, Some d ->
883+
match (t.kind, Setup.library_destdir) with
884+
| Default, Some d ->
890885
Memo.Build.return (Some (Path.of_filename_relative_to_initial_cwd d))
891-
| _ -> (
892-
(* If ocamlfind is present, it has precedence over everything else. *)
893-
match t.which "ocamlfind" with
894-
| Some fn ->
895-
let+ s =
896-
Memo.Build.of_fiber
897-
(Process.run_capture_line ~env:t.env Strict fn
898-
[ "printconf"; "destdir" ])
899-
in
900-
let s = String.trim s in
901-
if String.is_empty s then
902-
(* This case happens if ocamlfind doesn't find its configuration file *)
903-
None
904-
else
905-
Some (Path.of_filename_relative_to_initial_cwd s)
906-
| None -> Memo.Build.return None )
886+
| _ -> Memo.Build.return None
907887

908888
let compiler t (mode : Mode.t) =
909889
match mode with

test/blackbox-tests/test-cases/install-libdir.t/run.t

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -85,56 +85,55 @@ If prefix is passed, the default for libdir is `$prefix/lib`:
8585
Creating directory install/man/man3
8686
Copying _build/install/default/man/man3/another-man-page.3 to install/man/man3/another-man-page.3 (executable: false)
8787

88-
If prefix is not passed, libdir defaults to the output of `ocamlfind printconf
89-
destdir`:
88+
If prefix is not passed, libdir defaults to the opam-prefix/lib directory:
9089

9190
$ (export OCAMLFIND_DESTDIR=/OCAMLFIND_DESTDIR
9291
> dune install --dry-run 2>&1 | dune_cmd sanitize
9392
> dune uninstall --dry-run 2>&1 | dune_cmd sanitize)
94-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/META
95-
Installing /OCAMLFIND_DESTDIR/foo/META
96-
Creating directory /OCAMLFIND_DESTDIR/foo
97-
Copying _build/install/default/lib/foo/META to /OCAMLFIND_DESTDIR/foo/META (executable: false)
98-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/dune-package
99-
Installing /OCAMLFIND_DESTDIR/foo/dune-package
100-
Creating directory /OCAMLFIND_DESTDIR/foo
101-
Copying _build/install/default/lib/foo/dune-package to /OCAMLFIND_DESTDIR/foo/dune-package (executable: false)
102-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo$ext_lib
103-
Installing /OCAMLFIND_DESTDIR/foo/foo$ext_lib
104-
Creating directory /OCAMLFIND_DESTDIR/foo
105-
Copying _build/install/default/lib/foo/foo$ext_lib to /OCAMLFIND_DESTDIR/foo/foo$ext_lib (executable: false)
106-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cma
107-
Installing /OCAMLFIND_DESTDIR/foo/foo.cma
108-
Creating directory /OCAMLFIND_DESTDIR/foo
109-
Copying _build/install/default/lib/foo/foo.cma to /OCAMLFIND_DESTDIR/foo/foo.cma (executable: false)
110-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmi
111-
Installing /OCAMLFIND_DESTDIR/foo/foo.cmi
112-
Creating directory /OCAMLFIND_DESTDIR/foo
113-
Copying _build/install/default/lib/foo/foo.cmi to /OCAMLFIND_DESTDIR/foo/foo.cmi (executable: false)
114-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmt
115-
Installing /OCAMLFIND_DESTDIR/foo/foo.cmt
116-
Creating directory /OCAMLFIND_DESTDIR/foo
117-
Copying _build/install/default/lib/foo/foo.cmt to /OCAMLFIND_DESTDIR/foo/foo.cmt (executable: false)
118-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmx
119-
Installing /OCAMLFIND_DESTDIR/foo/foo.cmx
120-
Creating directory /OCAMLFIND_DESTDIR/foo
121-
Copying _build/install/default/lib/foo/foo.cmx to /OCAMLFIND_DESTDIR/foo/foo.cmx (executable: false)
122-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmxa
123-
Installing /OCAMLFIND_DESTDIR/foo/foo.cmxa
124-
Creating directory /OCAMLFIND_DESTDIR/foo
125-
Copying _build/install/default/lib/foo/foo.cmxa to /OCAMLFIND_DESTDIR/foo/foo.cmxa (executable: false)
126-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.ml
127-
Installing /OCAMLFIND_DESTDIR/foo/foo.ml
128-
Creating directory /OCAMLFIND_DESTDIR/foo
129-
Copying _build/install/default/lib/foo/foo.ml to /OCAMLFIND_DESTDIR/foo/foo.ml (executable: false)
130-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/opam
131-
Installing /OCAMLFIND_DESTDIR/foo/opam
132-
Creating directory /OCAMLFIND_DESTDIR/foo
133-
Copying _build/install/default/lib/foo/opam to /OCAMLFIND_DESTDIR/foo/opam (executable: false)
134-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmxs
135-
Installing /OCAMLFIND_DESTDIR/foo/foo.cmxs
136-
Creating directory /OCAMLFIND_DESTDIR/foo
137-
Copying _build/install/default/lib/foo/foo.cmxs to /OCAMLFIND_DESTDIR/foo/foo.cmxs (executable: true)
93+
Removing (if it exists) /OPAM_PREFIX/lib/foo/META
94+
Installing /OPAM_PREFIX/lib/foo/META
95+
Creating directory /OPAM_PREFIX/lib/foo
96+
Copying _build/install/default/lib/foo/META to /OPAM_PREFIX/lib/foo/META (executable: false)
97+
Removing (if it exists) /OPAM_PREFIX/lib/foo/dune-package
98+
Installing /OPAM_PREFIX/lib/foo/dune-package
99+
Creating directory /OPAM_PREFIX/lib/foo
100+
Copying _build/install/default/lib/foo/dune-package to /OPAM_PREFIX/lib/foo/dune-package (executable: false)
101+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo$ext_lib
102+
Installing /OPAM_PREFIX/lib/foo/foo$ext_lib
103+
Creating directory /OPAM_PREFIX/lib/foo
104+
Copying _build/install/default/lib/foo/foo$ext_lib to /OPAM_PREFIX/lib/foo/foo$ext_lib (executable: false)
105+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cma
106+
Installing /OPAM_PREFIX/lib/foo/foo.cma
107+
Creating directory /OPAM_PREFIX/lib/foo
108+
Copying _build/install/default/lib/foo/foo.cma to /OPAM_PREFIX/lib/foo/foo.cma (executable: false)
109+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmi
110+
Installing /OPAM_PREFIX/lib/foo/foo.cmi
111+
Creating directory /OPAM_PREFIX/lib/foo
112+
Copying _build/install/default/lib/foo/foo.cmi to /OPAM_PREFIX/lib/foo/foo.cmi (executable: false)
113+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmt
114+
Installing /OPAM_PREFIX/lib/foo/foo.cmt
115+
Creating directory /OPAM_PREFIX/lib/foo
116+
Copying _build/install/default/lib/foo/foo.cmt to /OPAM_PREFIX/lib/foo/foo.cmt (executable: false)
117+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmx
118+
Installing /OPAM_PREFIX/lib/foo/foo.cmx
119+
Creating directory /OPAM_PREFIX/lib/foo
120+
Copying _build/install/default/lib/foo/foo.cmx to /OPAM_PREFIX/lib/foo/foo.cmx (executable: false)
121+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmxa
122+
Installing /OPAM_PREFIX/lib/foo/foo.cmxa
123+
Creating directory /OPAM_PREFIX/lib/foo
124+
Copying _build/install/default/lib/foo/foo.cmxa to /OPAM_PREFIX/lib/foo/foo.cmxa (executable: false)
125+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.ml
126+
Installing /OPAM_PREFIX/lib/foo/foo.ml
127+
Creating directory /OPAM_PREFIX/lib/foo
128+
Copying _build/install/default/lib/foo/foo.ml to /OPAM_PREFIX/lib/foo/foo.ml (executable: false)
129+
Removing (if it exists) /OPAM_PREFIX/lib/foo/opam
130+
Installing /OPAM_PREFIX/lib/foo/opam
131+
Creating directory /OPAM_PREFIX/lib/foo
132+
Copying _build/install/default/lib/foo/opam to /OPAM_PREFIX/lib/foo/opam (executable: false)
133+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmxs
134+
Installing /OPAM_PREFIX/lib/foo/foo.cmxs
135+
Creating directory /OPAM_PREFIX/lib/foo
136+
Copying _build/install/default/lib/foo/foo.cmxs to /OPAM_PREFIX/lib/foo/foo.cmxs (executable: true)
138137
Removing (if it exists) /OPAM_PREFIX/bin/exec
139138
Installing /OPAM_PREFIX/bin/exec
140139
Creating directory /OPAM_PREFIX/bin
@@ -151,26 +150,26 @@ destdir`:
151150
Installing /OPAM_PREFIX/man/man3/another-man-page.3
152151
Creating directory /OPAM_PREFIX/man/man3
153152
Copying _build/install/default/man/man3/another-man-page.3 to /OPAM_PREFIX/man/man3/another-man-page.3 (executable: false)
154-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/META
155-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/dune-package
156-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo$ext_lib
157-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cma
158-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmi
159-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmt
160-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmx
161-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmxa
162-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.ml
163-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/opam
164-
Removing (if it exists) /OCAMLFIND_DESTDIR/foo/foo.cmxs
153+
Removing (if it exists) /OPAM_PREFIX/lib/foo/META
154+
Removing (if it exists) /OPAM_PREFIX/lib/foo/dune-package
155+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo$ext_lib
156+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cma
157+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmi
158+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmt
159+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmx
160+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmxa
161+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.ml
162+
Removing (if it exists) /OPAM_PREFIX/lib/foo/opam
163+
Removing (if it exists) /OPAM_PREFIX/lib/foo/foo.cmxs
165164
Removing (if it exists) /OPAM_PREFIX/bin/exec
166165
Removing (if it exists) /OPAM_PREFIX/man/a-man-page-with-no-ext
167166
Removing (if it exists) /OPAM_PREFIX/man/man1/a-man-page.1
168167
Removing (if it exists) /OPAM_PREFIX/man/man3/another-man-page.3
169168
Removing directory (if empty) /OPAM_PREFIX/man/man3
170169
Removing directory (if empty) /OPAM_PREFIX/man/man1
171170
Removing directory (if empty) /OPAM_PREFIX/man
171+
Removing directory (if empty) /OPAM_PREFIX/lib/foo
172172
Removing directory (if empty) /OPAM_PREFIX/bin
173-
Removing directory (if empty) /OCAMLFIND_DESTDIR/foo
174173

175174
If only libdir is passed, binaries are installed under prefix/bin and libraries
176175
in libdir:

0 commit comments

Comments
 (0)