···267267 (Sébastien Hinderer, review by David Allsopp, Nicolás Ojeda Bär,
268268 Xavier Leroy, Vincent Laviron and Antonin Décimo)
269269270270+* #11198: Install the Dynlink, Str and Unix libraries to individual
271271+ subdirectories of LIBDIR. The compiler, debugger and toplevel automatically
272272+ add `-I +lib` if required, but display an alert.
273273+ (David Allsopp, review by Florian Angeletti, Nicolás Ojeda Bär,
274274+ Valentin Gatien-Baron and Sébastien Hinderer)
275275+270276- #11200: Install ocamlprof's Profiling runtime module to a +profiling,
271277 removing it from the default namespace.
272278 (David Allsopp, review by Sébastien Hinderer)
···262262 let new_directory = argument_list_eol argument lexbuf in
263263 if new_directory = [] then begin
264264 if yes_or_no "Reinitialize directory list" then begin
265265- Load_path.init !default_load_path;
265265+ Load_path.init ~auto_include:Compmisc.auto_include !default_load_path;
266266 Envaux.reset_cache ();
267267 Hashtbl.clear Debugger_config.load_path_for;
268268 flush_buffer_list ()
···128128 end;
129129 Symbols.clear_symbols ();
130130 Symbols.read_symbols 0 !program_name;
131131- Load_path.init (Load_path.get_paths () @ !Symbols.program_source_dirs);
131131+ let dirs = Load_path.get_paths () @ !Symbols.program_source_dirs in
132132+ Load_path.init ~auto_include:Compmisc.auto_include dirs;
132133 Envaux.reset_cache ();
133134 if !debug_loading then
134135 prerr_endline "Opening a socket...";
+8-1
driver/compmisc.ml
···1313(* *)
1414(**************************************************************************)
15151616+let auto_include find_in_dir fn =
1717+ if !Clflags.no_std_include then
1818+ raise Not_found
1919+ else
2020+ let alert = Location.auto_include_alert in
2121+ Load_path.auto_include_otherlibs alert find_in_dir fn
2222+1623(* Initialize the search path.
1724 [dir] (default: the current directory)
1825 is always searched first unless -nocwd is specified,
···3744 (if !Clflags.no_cwd then [] else [dir])
3845 @ List.rev_append exp_dirs (Clflags.std_include_dir ())
3946 in
4040- Load_path.init(dirs);
4747+ Load_path.init ~auto_include dirs;
4148 Env.reset_cache ()
42494350(* Return the initial environment in which compilation proceeds. *)
+6
driver/compmisc.mli
···2121val read_clflags_from_env : unit -> unit
22222323val with_ppf_dump : file_prefix:string -> (Format.formatter -> 'a) -> 'a
2424+2525+val auto_include :
2626+ (Load_path.Dir.t -> string -> string option) -> string -> string
2727+(** [auto_include find_in_dir fn] is a callback function to be passed to
2828+ {!Load_path.init} and automatically adds [-I +lib] to the load path after
2929+ displaying an alert. *)
+13-5
otherlibs/Makefile.otherlibs.common
···8585lib$(CLIBNAME).$(A): $(COBJS)
8686 $(MKLIB_CMD) -oc $(CLIBNAME) $(COBJS) $(LDOPTS)
87878888+INSTALL_LIBDIR_LIBNAME = $(INSTALL_LIBDIR)/$(LIBNAME)
8989+8890install::
8991 if test -f dll$(CLIBNAME)$(EXT_DLL); then \
9092 $(INSTALL_PROG) \
···9395ifneq "$(STUBSLIB)" ""
9496 $(INSTALL_DATA) $(STUBSLIB) "$(INSTALL_LIBDIR)/"
9597endif
9696-9898+# If installing over a previous OCaml version, ensure the library is removed
9999+# from the previous installation.
100100+ rm -f $(addprefix "$(INSTALL_LIBDIR)"/, \
101101+ $(LIBNAME).cma $(CMIFILES) \
102102+ $(CMIFILES:.cmi=.mli) $(CMIFILES:.cmi=.cmti) \
103103+ $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).cmxs $(LIBNAME).$(A))
104104+ $(MKDIR) "$(INSTALL_LIBDIR_LIBNAME)"
97105 $(INSTALL_DATA) \
98106 $(LIBNAME).cma $(CMIFILES) \
9999- "$(INSTALL_LIBDIR)/"
107107+ "$(INSTALL_LIBDIR_LIBNAME)/"
100108ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
101109 $(INSTALL_DATA) \
102110 $(CMIFILES:.cmi=.mli) \
103111 $(CMIFILES:.cmi=.cmti) \
104104- "$(INSTALL_LIBDIR)/"
112112+ "$(INSTALL_LIBDIR_LIBNAME)/"
105113endif
106114 if test -n "$(HEADERS)"; then \
107115 $(INSTALL_DATA) $(HEADERS) "$(INSTALL_INCDIR)/"; \
···110118installopt:
111119 $(INSTALL_DATA) \
112120 $(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).$(A) \
113113- "$(INSTALL_LIBDIR)/"
121121+ "$(INSTALL_LIBDIR_LIBNAME)/"
114122 if test -f $(LIBNAME).cmxs; then \
115115- $(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR)"; \
123123+ $(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR_LIBNAME)"; \
116124 fi
117125118126partialclean:
···903903 | "include_dirs" ->
904904 Clflags.include_dirs := get_list get_string payload
905905 | "load_path" ->
906906- Load_path.init (get_list get_string payload)
906906+ (* Duplicates Compmisc.auto_include, since we can't reference Compmisc
907907+ from this module. *)
908908+ let auto_include find_in_dir fn =
909909+ if !Clflags.no_std_include then
910910+ raise Not_found
911911+ else
912912+ let alert = Location.auto_include_alert in
913913+ Load_path.auto_include_otherlibs alert find_in_dir fn
914914+ in
915915+ Load_path.init ~auto_include (get_list get_string payload)
907916 | "open_modules" ->
908917 Clflags.open_modules := get_list get_string payload
909918 | "for_package" ->
+14-3
parsing/location.ml
···1818type t = Warnings.loc =
1919 { loc_start: position; loc_end: position; loc_ghost: bool }
20202121-let in_file name =
2222- let loc = { dummy_pos with pos_fname = name } in
2323- { loc_start = loc; loc_end = loc; loc_ghost = true }
2121+let in_file = Warnings.ghost_loc_in_file
24222523let none = in_file "_none_"
2624let is_none l = (l = none)
···896894897895let deprecated ?def ?use loc message =
898896 alert ?def ?use ~kind:"deprecated" loc message
897897+898898+let auto_include_alert lib =
899899+ let message = Printf.sprintf "\
900900+ OCaml's lib directory layout changed in 5.0. The %s subdirectory has been \
901901+ automatically added to the search path, but you should add -I +%s to the \
902902+ command-line to silence this alert (e.g. by adding %s to the list of \
903903+ libraries in your dune file, or adding use_%s to your _tags file for \
904904+ ocamlbuild, or using -package %s for ocamlfind)." lib lib lib lib lib in
905905+ let alert =
906906+ {Warnings.kind="ocaml_deprecated_auto_include"; use=none; def=none;
907907+ message = Format.asprintf "@[@\n%a@]" Format.pp_print_text message}
908908+ in
909909+ prerr_alert none alert
899910900911(******************************************************************************)
901912(* Reporting errors on exceptions *)
+3
parsing/location.mli
···243243val alert: ?def:t -> ?use:t -> kind:string -> t -> string -> unit
244244(** Prints an arbitrary alert. *)
245245246246+val auto_include_alert: string -> unit
247247+(** Prints an alert that -I +lib has been automatically added ot the load
248248+ path *)
246249247250(** {1 Reporting errors} *)
248251
···3131 let path t = t.path
3232 let files t = t.files
33333434+ let find t fn =
3535+ if List.mem fn t.files then
3636+ Some (Filename.concat t.path fn)
3737+ else
3838+ None
3939+4040+ let find_uncap t fn =
4141+ let fn = String.uncapitalize_ascii fn in
4242+ let search base =
4343+ if String.uncapitalize_ascii base = fn then
4444+ Some (Filename.concat t.path base)
4545+ else
4646+ None
4747+ in
4848+ List.find_map search t.files
4949+3450 (* For backward compatibility reason, simulate the behavior of
3551 [Misc.find_in_path]: silently ignore directories that don't exist
3652 + treat [""] as the current directory. *)
···4561end
46624763let dirs = s_ref []
6464+let default_auto_include_callback _ _ = raise Not_found
6565+let auto_include_callback = ref default_auto_include_callback
48664967let reset () =
5068 assert (not Config.merlin || Local_store.is_bound ());
5169 STbl.clear !files;
5270 STbl.clear !files_uncap;
5353- dirs := []
7171+ dirs := [];
7272+ auto_include_callback := default_auto_include_callback
54735574let get () = List.rev !dirs
5675let get_paths () = List.rev_map Dir.path !dirs
···6685 STbl.replace !files_uncap (String.uncapitalize_ascii base) fn
6786 ) dir.Dir.files
68876969-let init l =
8888+let init ~auto_include l =
7089 reset ();
7190 dirs := List.rev_map Dir.create l;
7272- List.iter prepend_add !dirs
9191+ List.iter prepend_add !dirs;
9292+ auto_include_callback := auto_include
73937494let remove_dir dir =
7595 assert (not Config.merlin || Local_store.is_bound ());
···109129110130let is_basename fn = Filename.basename fn = fn
111131132132+let auto_include_libs libs alert find_in_dir fn =
133133+ let scan (lib, lazy dir) =
134134+ let file = find_in_dir dir fn in
135135+ let alert_and_add_dir _ =
136136+ alert lib;
137137+ append_dir dir
138138+ in
139139+ Option.iter alert_and_add_dir file;
140140+ file
141141+ in
142142+ match List.find_map scan libs with
143143+ | Some base -> base
144144+ | None -> raise Not_found
145145+146146+let auto_include_otherlibs =
147147+ (* Ensure directories are only ever scanned once *)
148148+ let expand = Misc.expand_directory Config.standard_library in
149149+ let otherlibs =
150150+ let read_lib lib = lazy (Dir.create (expand ("+" ^ lib))) in
151151+ List.map (fun lib -> (lib, read_lib lib)) ["dynlink"; "str"; "unix"] in
152152+ auto_include_libs otherlibs
153153+112154let find fn =
113155 assert (not Config.merlin || Local_store.is_bound ());
114114- if is_basename fn && not !Sys.interactive then
115115- STbl.find !files fn
116116- else
117117- Misc.find_in_path (get_paths ()) fn
156156+ try
157157+ if is_basename fn && not !Sys.interactive then
158158+ STbl.find !files fn
159159+ else
160160+ Misc.find_in_path (get_paths ()) fn
161161+ with Not_found ->
162162+ !auto_include_callback Dir.find fn
118163119164let find_uncap fn =
120165 assert (not Config.merlin || Local_store.is_bound ());
121121- if is_basename fn && not !Sys.interactive then
122122- STbl.find !files_uncap (String.uncapitalize_ascii fn)
123123- else
124124- Misc.find_in_path_uncap (get_paths ()) fn
166166+ try
167167+ if is_basename fn && not !Sys.interactive then
168168+ STbl.find !files_uncap (String.uncapitalize_ascii fn)
169169+ else
170170+ Misc.find_in_path_uncap (get_paths ()) fn
171171+ with Not_found ->
172172+ let fn_uncap = String.uncapitalize_ascii fn in
173173+ !auto_include_callback Dir.find_uncap fn_uncap
+29-14
utils/load_path.mli
···3131val reset : unit -> unit
3232(** Remove all directories *)
33333434-val init : string list -> unit
3434+module Dir : sig
3535+ type t
3636+ (** Represent one directory in the load path. *)
3737+3838+ val create : string -> t
3939+4040+ val path : t -> string
4141+4242+ val files : t -> string list
4343+ (** All the files in that directory. This doesn't include files in
4444+ sub-directories of this directory. *)
4545+4646+ val find : t -> string -> string option
4747+ (** [find dir fn] returns the full path to [fn] in [dir]. *)
4848+4949+ val find_uncap : t -> string -> string option
5050+ (** As {!find}, but search also for uncapitalized name, i.e. if name is
5151+ Foo.ml, either /path/Foo.ml or /path/foo.ml may be returned. *)
5252+end
5353+5454+val init :
5555+ auto_include:((Dir.t -> string -> string option) -> string -> string) ->
5656+ string list -> unit
3557(** [init l] is the same as [reset (); List.iter add_dir (List.rev l)] *)
5858+5959+val auto_include_otherlibs :
6060+ (string -> unit) -> (Dir.t -> string -> string option) -> string -> string
6161+(** [auto_include_otherlibs alert] is a callback function to be passed to
6262+ {!Load_path.init} and automatically adds [-I +lib] to the load path after
6363+ calling [alert lib]. *)
36643765val get_paths : unit -> string list
3866(** Return the list of directories passed to [add_dir] so far. *)
···4674val find_uncap : string -> string
4775(** Same as [find], but search also for uncapitalized name, i.e. if
4876 name is Foo.ml, allow /path/Foo.ml and /path/foo.ml to match. *)
4949-5050-module Dir : sig
5151- type t
5252- (** Represent one directory in the load path. *)
5353-5454- val create : string -> t
5555-5656- val path : t -> string
5757-5858- val files : t -> string list
5959- (** All the files in that directory. This doesn't include files in
6060- sub-directories of this directory. *)
6161-end
62776378val[@deprecated] add : Dir.t -> unit
6479(** Old name for {!append_dir} *)
+5-2
utils/warnings.ml
···686686 | Letter of char * modifier option
687687 | Num of int * int * modifier
688688689689+let ghost_loc_in_file name =
690690+ let pos = { Lexing.dummy_pos with pos_fname = name } in
691691+ { loc_start = pos; loc_end = pos; loc_ghost = true }
692692+689693let letter_alert tokens =
690694 let print_warning_char ppf c =
691695 let lowercase = Char.lowercase_ascii c = c in
···724728 match consecutive_letters with
725729 | [] -> None
726730 | example :: _ ->
727727- let pos = { Lexing.dummy_pos with pos_fname = "_none_" } in
728728- let nowhere = { loc_start=pos; loc_end=pos; loc_ghost=true } in
731731+ let nowhere = ghost_loc_in_file "_none_" in
729732 let spelling_hint ppf =
730733 let max_seq_len =
731734 List.fold_left (fun l x -> Int.max l (List.length x))
+3
utils/warnings.mli
···2626 loc_ghost: bool;
2727}
28282929+val ghost_loc_in_file : string -> loc
3030+(** Return an empty ghost range located in a given file *)
3131+2932type field_usage_warning =
3033 | Unused
3134 | Not_read