@@ -92,7 +92,29 @@ module L = struct
9292 ;;
9393
9494 let to_iflags dir = to_flags " -I" dir
95- let to_hflags dir = to_flags " -H" dir
95+
96+ type flag =
97+ | Hidden
98+ | Include
99+
100+ let to_flags dirs =
101+ Command.Args. S
102+ (Path.Map. foldi dirs ~init: [] ~f: (fun dir flag acc ->
103+ let flag =
104+ match flag with
105+ | Include -> " -I"
106+ | Hidden -> " -H"
107+ in
108+ Command.Args. Path dir :: A flag :: acc)
109+ |> List. rev)
110+ ;;
111+
112+ let include_only =
113+ Path.Map. foldi ~init: [] ~f: (fun path flag acc ->
114+ match flag with
115+ | Include -> path :: acc
116+ | Hidden -> acc)
117+ ;;
96118
97119 let remove_stdlib dirs (lib_config : Lib_config.t ) =
98120 Path.Set. remove dirs lib_config.stdlib_dir
@@ -103,10 +125,36 @@ module L = struct
103125 ; melange_emit : bool
104126 }
105127
128+ let combine_flags x y =
129+ match x, y with
130+ | Include , _ | _ , Include -> Include
131+ | Hidden , Hidden -> Hidden
132+ ;;
133+
134+ let add_flag flags path x =
135+ Path.Map. update flags path ~f: (fun y ->
136+ Some
137+ (match y with
138+ | None -> x
139+ | Some y -> combine_flags x y))
140+ ;;
141+
106142 let include_paths =
107- let add_public_dir ~visible_cmi obj_dir acc mode =
143+ let add_public_dir ocaml ~visible_cmi obj_dir acc mode =
144+ let use_hidden =
145+ Ocaml.Version. supports_hidden_includes ocaml
146+ &&
147+ match mode.lib_mode with
148+ | Ocaml _ -> true
149+ | Melange -> false
150+ in
108151 match visible_cmi with
109- | false -> acc
152+ | false ->
153+ if use_hidden
154+ then
155+ Obj_dir. all_cmis obj_dir
156+ |> List. fold_left ~init: acc ~f: (fun acc dir -> add_flag acc dir Hidden )
157+ else acc
110158 | true ->
111159 let public_cmi_dirs =
112160 List. map
@@ -116,14 +164,19 @@ module L = struct
116164 | { lib_mode = Melange ; melange_emit = false } ->
117165 [ Obj_dir. public_cmi_melange_dir ]
118166 | { lib_mode = Melange ; melange_emit = true } ->
119- (* Add the dir where ` .cmj` files exist, even for installed
120- private libraries. Melange needs to query ` .cmj` files for
121- ` import` information *)
167+ (* Add the dir where [ .cmj] files exist, even for installed
168+ private libraries. Melange needs to query [ .cmj] files for
169+ [ import] information *)
122170 [ Obj_dir. melange_dir; Obj_dir. public_cmi_melange_dir ])
123171 in
124- List. fold_left public_cmi_dirs ~init: acc ~f: Path.Set. add
172+ let acc =
173+ List. fold_left public_cmi_dirs ~init: acc ~f: (fun acc dir ->
174+ add_flag acc dir Include )
175+ in
176+ if use_hidden then add_flag acc (Obj_dir. byte_dir obj_dir) Hidden else acc
125177 in
126- fun ?project ts mode lib_config ->
178+ fun ?project ts mode (lib_config : Lib_config.t ) ->
179+ let ocaml = lib_config.ocaml_version in
127180 let visible_cmi =
128181 match project with
129182 | None -> fun _ -> true
@@ -139,33 +192,37 @@ module L = struct
139192 | _ -> true )
140193 in
141194 let dirs =
142- List. fold_left ts ~init: Path.Set . empty ~f: (fun acc t ->
195+ List. fold_left ts ~init: Path.Map . empty ~f: (fun acc t ->
143196 let obj_dir = Lib_info. obj_dir (Lib. info t) in
144197 let visible_cmi = visible_cmi t in
145198 match mode.lib_mode with
146- | Melange -> add_public_dir ~visible_cmi obj_dir acc mode
199+ | Melange -> add_public_dir ocaml ~visible_cmi obj_dir acc mode
147200 | Ocaml ocaml_mode ->
148- let acc = add_public_dir ~visible_cmi obj_dir acc mode in
201+ let acc = add_public_dir ocaml ~visible_cmi obj_dir acc mode in
149202 (match ocaml_mode with
150203 | Byte -> acc
151204 | Native ->
152205 let native_dir = Obj_dir. native_dir obj_dir in
153- Path.Set. add acc native_dir))
206+ add_flag acc native_dir Include ))
154207 in
155- remove_stdlib dirs lib_config
208+ Path.Map. remove dirs lib_config.stdlib_dir
156209 ;;
157210
158211 let include_flags ?project ~direct_libs ~hidden_libs mode lib_config =
159212 let include_paths ts =
160213 include_paths ?project ts { lib_mode = mode; melange_emit = false }
161214 in
162- let hidden_includes = to_hflags (include_paths hidden_libs lib_config) in
163- let direct_includes = to_iflags (include_paths direct_libs lib_config) in
215+ let hidden_includes =
216+ include_paths hidden_libs lib_config
217+ |> Path.Map. map ~f: (fun _ -> Hidden )
218+ |> to_flags
219+ in
220+ let direct_includes = to_flags (include_paths direct_libs lib_config) in
164221 Command.Args. S [ direct_includes; hidden_includes ]
165222 ;;
166223
167224 let melange_emission_include_flags ?project ts lib_config =
168- to_iflags
225+ to_flags
169226 (include_paths ?project ts { lib_mode = Melange ; melange_emit = true } lib_config)
170227 ;;
171228
@@ -239,9 +296,12 @@ module L = struct
239296 ;;
240297
241298 let toplevel_include_paths ts lib_config =
242- Path.Set. union
299+ Path.Map. union
300+ ~f: (fun _ x y -> Some (combine_flags x y))
243301 (include_paths ts (Lib_mode. Ocaml Byte ) lib_config)
244- (toplevel_ld_paths ts lib_config)
302+ (toplevel_ld_paths ts lib_config
303+ |> Path.Set. to_list_map ~f: (fun p -> p, Include )
304+ |> Path.Map. of_list_exn)
245305 ;;
246306end
247307
0 commit comments