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 <anmonteiro@gmail.com>
  • Loading branch information
anmonteiro committed Apr 8, 2024
1 parent 1e51ffa commit c1766de
Show file tree
Hide file tree
Showing 16 changed files with 290 additions and 172 deletions.
15 changes: 10 additions & 5 deletions bin/describe/describe_workspace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,14 @@ module Crawl = struct
: (Descr.Item.t * Lib.Set.t) option Memo.t
=
let first_exe = snd (Nonempty_list.hd exes.names) in
let* scope =
Scope.DB.find_by_project (Super_context.context sctx |> Context.name) project
in
let* modules_, obj_dir =
let db = Scope.libs scope in
Dir_contents.get sctx ~dir
>>= Dir_contents.ocaml
>>| Ml_sources.modules_and_obj_dir ~for_:(Exe { first_exe })
>>= Ml_sources.modules_and_obj_dir ~db ~for_:(Exe { first_exe })
in
let* pp_map =
let+ version =
Expand All @@ -405,9 +409,6 @@ module Crawl = struct
immediate_deps_of_module ~options ~obj_dir ~modules:modules_ module_
in
let obj_dir = Obj_dir.of_local obj_dir in
let* scope =
Scope.DB.find_by_project (Super_context.context sctx |> Context.name) project
in
let* modules_ = modules ~obj_dir ~deps_of modules_ in
let+ requires =
let* compile_info = Exe_rules.compile_info ~scope exes in
Expand Down Expand Up @@ -449,9 +450,13 @@ module Crawl = struct
| true ->
(* XXX why do we have a second object directory? *)
let* modules_, obj_dir_ =
let* db =
Scope.DB.find_by_dir (Path.as_in_build_dir_exn src_dir) >>| Scope.libs
in
Dir_contents.get sctx ~dir:(Path.as_in_build_dir_exn src_dir)
>>= Dir_contents.ocaml
>>| Ml_sources.modules_and_obj_dir
>>= Ml_sources.modules_and_obj_dir
~db
~for_:(Library (Lib_info.lib_id info |> Lib_id.to_local_exn))
in
let* pp_map =
Expand Down
9 changes: 4 additions & 5 deletions src/dune_rules/dir_contents.ml
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,11 @@ include Load

let modules_of_local_lib sctx lib =
let info = Lib.Local.info lib in
let* t =
let dir = Lib_info.src_dir info in
get sctx ~dir
in
let dir = Lib_info.src_dir info in
let* t = get sctx ~dir
and* db = Scope.DB.find_by_dir dir >>| Scope.libs in
ocaml t
>>| Ml_sources.modules ~for_:(Library (Lib_info.lib_id info |> Lib_id.to_local_exn))
>>= Ml_sources.modules ~db ~for_:(Library (Lib_info.lib_id info |> Lib_id.to_local_exn))
;;

let modules_of_lib sctx lib =
Expand Down
3 changes: 2 additions & 1 deletion src/dune_rules/exe_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ let executables_rules
(* Use "eobjs" rather than "objs" to avoid a potential conflict with a library
of the same name *)
let* modules, obj_dir =
let db = Scope.libs scope in
let first_exe = first_exe exes in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules_and_obj_dir ~for_:(Exe { first_exe })
>>= Ml_sources.modules_and_obj_dir ~db ~for_:(Exe { first_exe })
in
let* () = Check_rules.add_obj_dir sctx ~obj_dir (Ocaml Byte) in
let ctx = Super_context.context sctx in
Expand Down
45 changes: 23 additions & 22 deletions src/dune_rules/gen_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ let define_all_alias ~dir ~project ~js_targets =

let gen_rules_for_stanzas sctx dir_contents cctxs expander dune_file ~dir:ctx_dir =
let src_dir = Dune_file.dir dune_file in
let* stanzas = Dune_file.stanzas dune_file in
let* stanzas = Dune_file.stanzas dune_file
and* scope = Scope.DB.find_by_dir ctx_dir in
let* { For_stanza.merlin = merlins; cctx = cctxs; js = js_targets; source_dirs } =
let* scope = Scope.DB.find_by_dir ctx_dir in
For_stanza.of_stanzas
stanzas
~cctxs
Expand All @@ -240,26 +240,27 @@ let gen_rules_for_stanzas sctx dir_contents cctxs expander dune_file ~dir:ctx_di
| false -> Memo.return ()
| true ->
let* ml_sources = Dir_contents.ocaml dir_contents in
(match
let base_path =
match Ml_sources.include_subdirs ml_sources with
| Include Unqualified | No -> []
| Include Qualified ->
Path.Local.descendant
(Path.Build.local ctx_dir)
~of_:(Path.Build.local (Dir_contents.dir dir_contents))
|> Option.value_exn
|> Path.Local.explode
|> List.map ~f:Module_name.of_string
in
Menhir_rules.module_names m
|> List.find_map ~f:(fun name ->
let open Option.O in
let path = base_path @ [ name ] in
let* origin = Ml_sources.find_origin ml_sources path in
List.find_map cctxs ~f:(fun (loc, cctx) ->
Option.some_if (Loc.equal loc (Ml_sources.Origin.loc origin)) cctx))
with
let base_path =
match Ml_sources.include_subdirs ml_sources with
| Include Unqualified | No -> []
| Include Qualified ->
Path.Local.descendant
(Path.Build.local ctx_dir)
~of_:(Path.Build.local (Dir_contents.dir dir_contents))
|> Option.value_exn
|> Path.Local.explode
|> List.map ~f:Module_name.of_string
in
Menhir_rules.module_names m
|> Memo.List.find_map ~f:(fun name ->
let path = base_path @ [ name ] in
Ml_sources.find_origin ml_sources (Scope.libs scope) path
>>| function
| None -> None
| Some origin ->
List.find_map cctxs ~f:(fun (loc, cctx) ->
Option.some_if (Loc.equal loc (Ml_sources.Origin.loc origin)) cctx))
>>= (function
| Some cctx -> Menhir_rules.gen_rules cctx m ~dir:ctx_dir
| None ->
(* This happens often when passing a [-p ...] option that hides a
Expand Down
24 changes: 15 additions & 9 deletions src/dune_rules/install_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,15 @@ end = struct
>>| List.singleton
;;

let lib_files ~dir_contents ~dir ~lib_config lib =
let lib_files ~scope ~dir_contents ~dir ~lib_config lib =
let+ modules =
let+ ml_sources = Dir_contents.ocaml dir_contents in
Some
(Ml_sources.modules
ml_sources
~for_:(Library (Lib_info.lib_id lib |> Lib_id.to_local_exn)))
let* ml_sources = Dir_contents.ocaml dir_contents in
let db = Scope.libs scope in
Ml_sources.modules
ml_sources
~db
~for_:(Library (Lib_info.lib_id lib |> Lib_id.to_local_exn))
>>| Option.some
and+ foreign_archives =
match Lib_info.virtual_ lib with
| None -> Memo.return (Mode.Map.Multi.to_flat_list @@ Lib_info.foreign_archives lib)
Expand Down Expand Up @@ -184,8 +186,10 @@ end = struct
let lib_name = Library.best_name lib in
let* installable_modules =
let+ modules =
let db = Scope.libs scope in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules
>>= Ml_sources.modules
~db
~for_:(Library (Lib_info.lib_id info |> Lib_id.to_local_exn))
and+ impl = Virtual_rules.impl sctx ~lib ~scope in
Vimpl.impl_modules impl modules |> Modules.split_by_lib
Expand Down Expand Up @@ -310,7 +314,7 @@ end = struct
if Module.kind m = Virtual then [] else common m |> set_dir m)
in
modules_vlib @ modules_impl
and+ lib_files = lib_files ~dir ~dir_contents ~lib_config info
and+ lib_files = lib_files ~scope ~dir ~dir_contents ~lib_config info
and+ execs = lib_ppxs ctx ~scope ~lib
and+ dll_files =
dll_files ~modes:ocaml ~dynlink:lib.dynlink ~ctx info
Expand Down Expand Up @@ -665,8 +669,10 @@ end = struct
|> Foreign.Sources.object_files ~dir ~ext_obj
|> List.map ~f:Path.build
and* modules =
let* db = Scope.DB.find_by_dir dir >>| Scope.libs in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules
>>= Ml_sources.modules
~db
~for_:(Library (Lib_info.lib_id info |> Lib_id.to_local_exn))
and* melange_runtime_deps = file_deps (Lib_info.melange_runtime_deps info)
and* public_headers = file_deps (Lib_info.public_headers info) in
Expand Down
7 changes: 3 additions & 4 deletions src/dune_rules/lib_id.ml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module Local = struct
include Comparable.Make (T)

let make ~loc ~src_dir name = { name; loc; src_dir }
let name t = t.name
let loc t = t.loc
end

Expand Down Expand Up @@ -69,11 +70,9 @@ let to_local_exn = function
;;

let name = function
| Local { name; _ } -> name
| External (_, name) -> name
| Local { name; _ } | External (_, name) -> name
;;

let loc = function
| Local { loc; _ } -> loc
| External (loc, _) -> loc
| Local { loc; _ } | External (loc, _) -> loc
;;
1 change: 1 addition & 0 deletions src/dune_rules/lib_id.mli
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Local : sig

val equal : t -> t -> bool
val make : loc:Loc.t -> src_dir:Path.Source.t -> Lib_name.t -> t
val name : t -> Lib_name.t
val loc : t -> Loc.t
val to_dyn : t -> Dyn.t
end
Expand Down
4 changes: 3 additions & 1 deletion src/dune_rules/lib_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -654,8 +654,10 @@ let rules (lib : Library.t) ~sctx ~dir_contents ~dir ~expander ~scope =
let local_lib = Lib.Local.of_lib_exn local_lib in
let f () =
let* source_modules =
let db = Scope.libs scope in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules
>>= Ml_sources.modules
~db
~for_:
(Library (Lib_info.lib_id (Lib.Local.info local_lib) |> Lib_id.to_local_exn))
in
Expand Down
6 changes: 4 additions & 2 deletions src/dune_rules/melange/melange_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,9 @@ let setup_emit_cmj_rules
let ctx = Super_context.context sctx in
let f () =
let* modules, obj_dir =
let db = Scope.libs scope in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules_and_obj_dir ~for_:(Melange { target = mel.target })
>>= Ml_sources.modules_and_obj_dir ~db ~for_:(Melange { target = mel.target })
in
let* () = Check_rules.add_obj_dir sctx ~obj_dir Melange in
let* modules, pp =
Expand Down Expand Up @@ -422,8 +423,9 @@ let setup_runtime_assets_rules sctx ~dir ~target_dir ~mode ~output ~for_ mel =
let modules_for_js_and_obj_dir ~sctx ~dir_contents ~scope (mel : Melange_stanzas.Emit.t) =
let open Memo.O in
let* modules, obj_dir =
let db = Scope.libs scope in
Dir_contents.ocaml dir_contents
>>| Ml_sources.modules_and_obj_dir ~for_:(Melange { target = mel.target })
>>= Ml_sources.modules_and_obj_dir ~db ~for_:(Melange { target = mel.target })
in
let+ modules = modules_in_obj_dir ~sctx ~scope ~preprocess:mel.preprocess modules in
let modules_for_js =
Expand Down
Loading

0 comments on commit c1766de

Please sign in to comment.