Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(melange): add .cmj include dirs for installed private libs #10416

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/changes/10416.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- melange: add include paths for private library `.cmj` files during JS
emission. (#10416, @anmonteiro)

46 changes: 34 additions & 12 deletions src/dune_rules/lib_flags.ml
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,30 @@ module L = struct
| lib :: _ -> Path.Set.remove dirs (Lib.lib_config lib).stdlib_dir
;;

type mode =
{ lib_mode : Lib_mode.t
; melange_emit : bool
}

let include_paths =
let add_public_dir ~visible_cmi obj_dir acc mode =
match visible_cmi with
| false -> acc
| true ->
let public_cmi_dir =
(match mode with
| `Byte -> Obj_dir.public_cmi_ocaml_dir
| `Melange -> Obj_dir.public_cmi_melange_dir)
obj_dir
let public_cmi_dirs =
List.map
~f:(fun f -> f obj_dir)
(match mode with
| { lib_mode = Ocaml _; _ } -> [ Obj_dir.public_cmi_ocaml_dir ]
| { lib_mode = Melange; melange_emit = false } ->
[ Obj_dir.public_cmi_melange_dir ]
| { lib_mode = Melange; melange_emit = true } ->
(* Add the dir where `.cmj` files exist, even for installed
private libraries. Melange needs to query `.cmj` files for
`import` information *)
[ Obj_dir.melange_dir; Obj_dir.public_cmi_melange_dir ])
in
Path.Set.add acc public_cmi_dir
List.fold_left public_cmi_dirs ~init:acc ~f:Path.Set.add
in
fun ?project ts mode ->
let visible_cmi =
Expand All @@ -130,11 +142,11 @@ module L = struct
List.fold_left ts ~init:Path.Set.empty ~f:(fun acc t ->
let obj_dir = Lib_info.obj_dir (Lib.info t) in
let visible_cmi = visible_cmi t in
match mode with
| Lib_mode.Melange -> add_public_dir ~visible_cmi obj_dir acc `Melange
| Ocaml mode ->
let acc = add_public_dir ~visible_cmi obj_dir acc `Byte in
(match mode with
match mode.lib_mode with
| Melange -> add_public_dir ~visible_cmi obj_dir acc mode
| Ocaml ocaml_mode ->
let acc = add_public_dir ~visible_cmi obj_dir acc mode in
(match ocaml_mode with
| Byte -> acc
| Native ->
let native_dir = Obj_dir.native_dir obj_dir in
Expand All @@ -143,7 +155,17 @@ module L = struct
remove_stdlib dirs ts
;;

let include_flags ?project ts mode = to_iflags (include_paths ?project ts mode)
let include_flags ?project ts mode =
to_iflags (include_paths ?project ts { lib_mode = mode; melange_emit = false })
;;

let melange_emission_include_flags ?project ts =
to_iflags (include_paths ?project ts { lib_mode = Melange; melange_emit = true })
;;

let include_paths ?project ts mode =
include_paths ?project ts { lib_mode = mode; melange_emit = false }
;;

let c_include_paths ts =
let dirs =
Expand Down
1 change: 1 addition & 0 deletions src/dune_rules/lib_flags.mli
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module L : sig
val to_iflags : Path.Set.t -> _ Command.Args.t
val include_paths : ?project:Dune_project.t -> t -> Lib_mode.t -> Path.Set.t
val include_flags : ?project:Dune_project.t -> t -> Lib_mode.t -> _ Command.Args.t
val melange_emission_include_flags : ?project:Dune_project.t -> t -> _ Command.Args.t
val c_include_flags : t -> Super_context.t -> _ Command.Args.t
val toplevel_ld_paths : t -> Path.Set.t
val toplevel_include_paths : t -> Path.Set.t
Expand Down
4 changes: 3 additions & 1 deletion src/dune_rules/melange/melange_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ let cmj_includes ~(requires_link : Lib.t list Resolve.t) ~scope =
let+ requires_link = requires_link in
let deps = List.map requires_link ~f:deps_of_lib |> Dep.Set.of_list in
Command.Args.S
[ Lib_flags.L.include_flags ~project requires_link Melange; Hidden_deps deps ]
[ Lib_flags.L.melange_emission_include_flags ~project requires_link
; Hidden_deps deps
]
;;

let compile_info ~scope (mel : Melange_stanzas.Emit.t) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,9 @@ Melange (installed) library depends on private library
> let () = Js.log Foo.x
> EOF

An issue similar to #7104 still present because the `.cmj` is not visible.
Build the app that depends on `foo`, which in turn depends on a private lib

$ OCAMLPATH=$PWD/prefix/lib/:$OCAMLPATH dune build @melange --root app --display=short
$ OCAMLPATH=$PWD/prefix/lib/:$OCAMLPATH dune build @melange --root app
Entering directory 'app'
melc output/node_modules/foo.__private__.priv/priv.js
melc .output.mobjs/melange/melange__Entry.{cmi,cmj,cmt}
melc output/entry.js
melc output/node_modules/foo/foo.js (exit 2)
File "_none_", line 1:
Error: Priv not found, it means either the module does not exist or it is a namespace
Leaving directory 'app'
[1]

Loading