Open nojb opened 11 hours ago
It's rather straightforward to instrument ocamlc/ocamlopt to dump which of the libraries specified on the command-line (when linking an executable) have actually been linked. Or, without patching the compiler, one can replicate the logic with a simple script like:
let required = Hashtbl.create 17
let add_required (name, _crc) = Hashtbl.replace required name ()
let used_libs = ref []
let scan_file obj_name =
let file_name =
try Load_path.find obj_name
with Not_found -> failwith (Printf.sprintf "File not found: %s" obj_name)
in
if Filename.check_suffix file_name ".cmx" then begin
let (info, _) = Compilenv.read_unit_info file_name in
List.iter add_required info.ui_imports_cmx
end else if Filename.check_suffix file_name ".cmxa" then begin
let infos =
try Compilenv.read_library_info file_name
with Compilenv.Error(Not_a_unit_info _) ->
failwith (Printf.sprintf "Not an object file: %s" file_name)
in
let trace = lazy (used_libs := file_name :: !used_libs) in
List.iter
(fun (info, _) ->
if info.Cmx_format.ui_force_link || Hashtbl.mem required info.ui_name
then begin
Lazy.force trace;
List.iter add_required info.ui_imports_cmx
end
)
(List.rev infos.lib_units)
end else
failwith (Printf.sprintf "Not an object file: %s" file_name)
let () =
let files = ref [] in
Arg.parse
[ "-I", Arg.String Load_path.add_dir, "" ]
(fun file -> files := file :: !files) "Usage: ...";
List.iter scan_file !files; (* reverse order *)
List.iter print_endline !used_libs
Note that even if a library is not considered to be needed by the linker, it could still be needed to consider it as dune library dependency to allowing type-checking the code.
Listing unnecessary libraries in the
(libraries ...)
field of executables and libraries is not harmless at the moment due to the way dependencies are computed in Dune: this can cause potentially a lot of unnecessary recompilation, as any change in the "unused" dependency will cause the recompilation of the whole executable/library.Having some way of knowing if one has included unnecessary libraries in
(libraries ...)
would thus be quite useful.