Guest User

Untitled

a guest
Feb 18th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.92 KB | None | 0 0
  1. diff --git a/ocamldep.ml b/ocamldep.ml
  2. index 3146027..507f09b 100644
  3. --- a/ocamldep.ml
  4. +++ b/ocamldep.ml
  5. @@ -27,6 +27,8 @@ let native_only = ref false
  6. let force_slash = ref false
  7. let error_occurred = ref false
  8. let raw_dependencies = ref false
  9. +let full_dependencies = ref false
  10. +let one_line = ref false
  11.  
  12. (* Fix path to use '/' as directory separator instead of '\'.
  13. Only under Windows. *)
  14. @@ -57,6 +59,7 @@ let add_to_synonym_list synonyms suffix =
  15. error_occurred := true
  16. end
  17.  
  18. +(* Find file 'name' (capitalized) in search path *)
  19. let find_file name =
  20. let uname = String.uncapitalize name in
  21. let rec find_in_array a pos =
  22. @@ -77,24 +80,61 @@ let rec find_file_in_list = function
  23. [] -> raise Not_found
  24. | x :: rem -> try find_file x with Not_found -> find_file_in_list rem
  25.  
  26. -let find_dependency modname (byt_deps, opt_deps) =
  27. +(* Convert dependency on module 'modname' into dependency on compilation artefacts.
  28. + First, we try looking for modname.mli.
  29. + If it is found, we depend on compiled interface.
  30. + If not, we look for .ml and depend on compiled interface + compiled object file(s)
  31. +*)
  32. +type file_kind = ML | MLI;;
  33. +
  34. +let find_dependency target_kind modname (byt_deps, opt_deps) =
  35. try
  36. let candidates = List.map ((^) modname) !mli_synonyms in
  37. let filename = find_file_in_list candidates in
  38. let basename = Filename.chop_extension filename in
  39. - let optname =
  40. - if List.exists (fun ext -> Sys.file_exists (basename ^ ext)) !ml_synonyms
  41. - then basename ^ ".cmx"
  42. - else basename ^ ".cmi" in
  43. - ((basename ^ ".cmi") :: byt_deps, optname :: opt_deps)
  44. + let new_byt_dep = basename ^ ".cmi" (* no cross-module inlining, so just .cmi
  45. + regardless of compilation mode *)
  46. + in
  47. + let ml_exists = List.exists (fun ext -> Sys.file_exists (basename ^ ext)) !ml_synonyms in
  48. + let new_opt_dep =
  49. + if !full_dependencies then
  50. + match target_kind with
  51. + | MLI -> [basename ^ ".cmi"]
  52. + (* in native mode, depend interface + implementation for cross-module inlining *)
  53. + | ML -> if ml_exists
  54. + then [basename ^ ".cmi"; basename ^ ".cmx"; basename ^ ".o"]
  55. + else [basename ^ ".cmi"]
  56. + else
  57. + (* this is a make-specific hack that makes .cmx to be a 'proxy' target that would force
  58. + the dependency on .cmi via transitivity *)
  59. + if ml_exists
  60. + then [ basename ^ ".cmx" ]
  61. + else [ basename ^ ".cmi" ]
  62. + in
  63. + ( new_byt_dep :: byt_deps, new_opt_dep @ opt_deps)
  64. with Not_found ->
  65. try
  66. + (* "just .ml" case *)
  67. let candidates = List.map ((^) modname) !ml_synonyms in
  68. let filename = find_file_in_list candidates in
  69. let basename = Filename.chop_extension filename in
  70. let bytename =
  71. - basename ^ (if !native_only then ".cmx" else ".cmo") in
  72. - (bytename :: byt_deps, (basename ^ ".cmx") :: opt_deps)
  73. + if !full_dependencies then
  74. + match target_kind with
  75. + | MLI -> basename ^ ".cmi"
  76. + | ML -> basename ^ ".cmo"
  77. + else
  78. + (* again, make-specific hack *)
  79. + basename ^ (if !native_only then ".cmx" else ".cmo") in
  80. + let optnames =
  81. + if !full_dependencies
  82. + then match target_kind with
  83. + | MLI -> [basename ^ ".cmi"]
  84. + (* in native mode, depend interface + implementation for cross-module inlining *)
  85. + | ML -> [basename ^ ".cmi"; basename ^ ".cmx"; basename ^ ".o"]
  86. + else [ basename ^ ".cmx" ]
  87. + in
  88. + (bytename :: byt_deps, optnames @ opt_deps)
  89. with Not_found ->
  90. (byt_deps, opt_deps)
  91.  
  92. @@ -128,22 +168,21 @@ let print_filename s =
  93. end
  94. ;;
  95.  
  96. -let print_dependencies target_file deps =
  97. - print_filename target_file; print_string depends_on;
  98. +let print_dependencies target_files deps =
  99. let rec print_items pos = function
  100. [] -> print_string "\n"
  101. | dep :: rem ->
  102. - if pos + 1 + String.length dep <= 77 then begin
  103. - print_string " "; print_filename dep;
  104. + if !one_line || (pos + 1 + String.length dep <= 77) then begin
  105. + if pos <> 0 then print_string " "; print_filename dep;
  106. print_items (pos + String.length dep + 1) rem
  107. end else begin
  108. print_string escaped_eol; print_filename dep;
  109. print_items (String.length dep + 4) rem
  110. end in
  111. - print_items (String.length target_file + 1) deps
  112. + print_items 0 (target_files @ [depends_on] @ deps)
  113.  
  114. let print_raw_dependencies source_file deps =
  115. - print_filename source_file; print_string ":";
  116. + print_filename source_file; print_string depends_on;
  117. Depend.StringSet.iter
  118. (fun dep ->
  119. if (String.length dep > 0)
  120. @@ -223,15 +262,29 @@ let ml_file_dependencies source_file =
  121. print_raw_dependencies source_file !Depend.free_structure_names
  122. end else begin
  123. let basename = Filename.chop_extension source_file in
  124. - let init_deps =
  125. + let byte_targets =
  126. + if !native_only then [] else [ basename ^ ".cmo" ] in
  127. + let native_targets =
  128. + if !full_dependencies
  129. + then [ basename ^ ".cmx"; basename ^ ".o" ]
  130. + else [ basename ^ ".cmx" ] in
  131. + (*
  132. + If we have an .mli, then .ml is used to compile just the module object file:
  133. + foo.cmi + foo.ml -> foo.cmo or foo.cmx+foo.o
  134. +
  135. + Otherwise, foo.ml produces foo.cmi + object file(s)
  136. + *)
  137. + let init_deps = if !full_dependencies then [source_file] else [] in
  138. + let cmi_name = basename ^ ".cmi" in
  139. + let init_deps, extra_targets =
  140. if List.exists (fun ext -> Sys.file_exists (basename ^ ext)) !mli_synonyms
  141. - then let cmi_name = basename ^ ".cmi" in ([cmi_name], [cmi_name])
  142. - else ([], []) in
  143. - let (byt_deps, opt_deps) =
  144. - Depend.StringSet.fold find_dependency
  145. + then (cmi_name :: init_deps, cmi_name :: init_deps), []
  146. + else (init_deps, init_deps), ( if !full_dependencies then [cmi_name] else [] ) in
  147. + let (byt_deps, native_deps) =
  148. + Depend.StringSet.fold (find_dependency ML)
  149. !Depend.free_structure_names init_deps in
  150. - print_dependencies (basename ^ ".cmo") byt_deps;
  151. - print_dependencies (basename ^ ".cmx") opt_deps
  152. + if not !native_only then print_dependencies (byte_targets @ extra_targets) byt_deps;
  153. + print_dependencies (native_targets @ extra_targets) native_deps;
  154. end;
  155. close_in ic; remove_preprocessed input_file
  156. with x ->
  157. @@ -248,16 +301,17 @@ let mli_file_dependencies source_file =
  158. print_raw_dependencies source_file !Depend.free_structure_names
  159. end else begin
  160. let basename = Filename.chop_extension source_file in
  161. + let init_deps = if !full_dependencies then ([source_file],[source_file]) else ([],[]) in
  162. let (byt_deps, opt_deps) =
  163. - Depend.StringSet.fold find_dependency
  164. - !Depend.free_structure_names ([], []) in
  165. - print_dependencies (basename ^ ".cmi") byt_deps
  166. + Depend.StringSet.fold (find_dependency MLI)
  167. + !Depend.free_structure_names init_deps in
  168. + print_dependencies [basename ^ ".cmi"] byt_deps
  169. end;
  170. close_in ic; remove_preprocessed input_file
  171. with x ->
  172. close_in ic; remove_preprocessed input_file; raise x
  173.  
  174. -type file_kind = ML | MLI;;
  175. +(* Dispatch on file type, print dependencies, handle and report errors *)
  176.  
  177. let file_dependencies_as kind source_file =
  178. Location.input_name := source_file;
  179. @@ -327,6 +381,10 @@ let _ =
  180. " Print module dependencies in raw form (not suitable for make)";
  181. "-native", Arg.Set native_only,
  182. " Generate dependencies for a pure native-code project (no .cmo files)";
  183. + "-full", Arg.Set full_dependencies,
  184. + " Generate full set of dependency rules (not accommodating for make shortcomings)";
  185. + "-one-line", Arg.Set one_line,
  186. + " Output one line per file, regardless of the length";
  187. "-pp", Arg.String(fun s -> preprocessor := Some s),
  188. "<cmd> Pipe sources through preprocessor <cmd>";
  189. "-slash", Arg.Set force_slash,
Add Comment
Please, Sign In to add comment