daily pastebin goal
33%
SHARE
TWEET

Untitled

a guest Feb 18th, 2019 76 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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,
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top