Skip to content

Commit

Permalink
fix(ml-sources): check that a library is available before tracking it
Browse files Browse the repository at this point in the history
Since ocaml#10307, dune started allowing libraries to share the same name.
Thus, checking `enabled_if` isn't enough for libraries; dune now needs
to check whether the library is available before tracking it in
ml_sources

Signed-off-by: Antonio Nuno Monteiro <[email protected]>
  • Loading branch information
anmonteiro committed Apr 3, 2024
1 parent 856eeea commit b9892d7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 18 deletions.
44 changes: 26 additions & 18 deletions src/dune_rules/ml_sources.ml
Original file line number Diff line number Diff line change
Expand Up @@ -465,25 +465,33 @@ let modules_of_stanzas =
| true ->
(match Stanza.repr stanza with
| Library.T lib ->
(* jeremiedimino: this [Resolve.get] means that if the user writes an
invalid [implements] field, we will get an error immediately even if
the library is not built. We should change this to carry the
[Or_exn.t] a bit longer. *)
let+ sources, modules =
let lookup_vlib = lookup_vlib ~loc:lib.buildable.loc in
make_lib_modules
~expander
~dir
~libs
~lookup_vlib
~modules
~lib
~include_subdirs
~version:lib.dune_version
>>= Resolve.read_memo
let* available =
let* db = libs in
let src_dir = Path.drop_optional_build_context_src_exn (Path.build dir) in
Lib.DB.available_by_lib_id db (Local (Library.to_lib_id ~src_dir lib))
in
let obj_dir = Library.obj_dir lib ~dir in
`Library { Modules.stanza = lib; sources; modules; dir; obj_dir }
if not available
then Memo.return `Skip
else
(* jeremiedimino: this [Resolve.get] means that if the user writes an
invalid [implements] field, we will get an error immediately even if
the library is not built. We should change this to carry the
[Or_exn.t] a bit longer. *)
let+ sources, modules =
let lookup_vlib = lookup_vlib ~loc:lib.buildable.loc in
make_lib_modules
~expander
~dir
~libs
~lookup_vlib
~modules
~lib
~include_subdirs
~version:lib.dune_version
>>= Resolve.read_memo
in
let obj_dir = Library.obj_dir lib ~dir in
`Library { Modules.stanza = lib; sources; modules; dir; obj_dir }
| Executables.T exes -> make_executables ~dir ~expander ~modules ~project exes
| Tests.T { exes; _ } -> make_executables ~dir ~expander ~modules ~project exes
| Melange_stanzas.Emit.T mel ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Private libraries using the same library name, in the same context, defined in
the same folder. One of them is unavailable because it's `(optional)` and a
dependency is missing.

$ cat > dune-project << EOF
> (lang dune 3.13)
> EOF

$ cat > dune << EOF
> (library
> (name foo)
> (libraries xxx)
> (optional))
> (library
> (name foo))
> EOF
$ cat > foo.ml << EOF
> let x = "hello"
> EOF

Without any consumers of the libraries

$ dune build

With some consumer of the library

$ cat > dune << EOF
> (library
> (name foo)
> (modules foo)
> (libraries xxx)
> (optional))
> (library
> (modules foo)
> (name foo))
> (executable
> (name main)
> (modules main)
> (libraries foo))
> EOF

$ cat > main.ml <<EOF
> let () = print_endline Foo.x
> EOF

$ dune build

0 comments on commit b9892d7

Please sign in to comment.