Blob Blame History Raw
From 3efce06fd92ef66098f84bd9955ff9b4c16cb6f4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 13 Jul 2016 19:16:07 +0100
Subject: [PATCH] v2v: Move augeas_debug_errors (renamed debug_augeas_errors)
 to common code.

Since the function uses the StringMap module, I also had to
move this to mllib.

The function is renamed and the 'if verbose ()' part is moved into the
function, but apart from that, it's all just code motion.

(cherry picked from commit eb22e2d36e3a28805f36e43b2be549ccbd3457b1)
---
 builder/Makefile.am          |  1 +
 customize/Makefile.am        |  1 +
 dib/Makefile.am              |  1 +
 get-kernel/Makefile.am       |  1 +
 mllib/Makefile.am            |  3 +++
 mllib/common_utils.ml        | 63 +++++++++++++++++++++++++++++++++++++++++++
 mllib/common_utils.mli       | 14 ++++++++++
 mllib/stringMap.ml           | 21 +++++++++++++++
 mllib/stringMap.mli          | 54 +++++++++++++++++++++++++++++++++++++
 po/POTFILES-ml               |  2 +-
 resize/Makefile.am           |  1 +
 sparsify/Makefile.am         |  1 +
 sysprep/Makefile.am          |  1 +
 v2v/Makefile.am              |  6 ++---
 v2v/linux.ml                 | 64 ++------------------------------------------
 v2v/stringMap.ml             | 21 ---------------
 v2v/stringMap.mli            | 54 -------------------------------------
 v2v/test-harness/Makefile.am |  1 +
 18 files changed, 169 insertions(+), 141 deletions(-)
 create mode 100644 mllib/stringMap.ml
 create mode 100644 mllib/stringMap.mli
 delete mode 100644 v2v/stringMap.ml
 delete mode 100644 v2v/stringMap.mli

diff --git a/builder/Makefile.am b/builder/Makefile.am
index 54aa10b..d69e7ec 100644
--- a/builder/Makefile.am
+++ b/builder/Makefile.am
@@ -136,6 +136,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/fsync.cmo \
 	$(top_builddir)/mllib/planner.cmo \
diff --git a/customize/Makefile.am b/customize/Makefile.am
index 661917a..05f144f 100644
--- a/customize/Makefile.am
+++ b/customize/Makefile.am
@@ -95,6 +95,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/regedit.cmo \
 	$(top_builddir)/mllib/URI.cmo \
diff --git a/dib/Makefile.am b/dib/Makefile.am
index d1674a9..ff6a933 100644
--- a/dib/Makefile.am
+++ b/dib/Makefile.am
@@ -59,6 +59,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/mkdtemp.cmo \
 	$(SOURCES_ML:.ml=.cmo)
diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am
index 9d8fc61..e2d78b0 100644
--- a/get-kernel/Makefile.am
+++ b/get-kernel/Makefile.am
@@ -58,6 +58,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/URI.cmo \
 	$(SOURCES_ML:.ml=.cmo)
diff --git a/mllib/Makefile.am b/mllib/Makefile.am
index 0a6dd93..8807d86 100644
--- a/mllib/Makefile.am
+++ b/mllib/Makefile.am
@@ -37,11 +37,13 @@ SOURCES_MLI = \
 	progress.mli \
 	regedit.mli \
 	StatVFS.mli \
+	stringMap.mli \
 	URI.mli
 
 SOURCES_ML = \
 	guestfs_config.ml \
 	libdir.ml \
+	stringMap.ml \
 	common_gettext.ml \
 	dev_t.ml \
 	common_utils.ml \
@@ -150,6 +152,7 @@ common_utils_tests_BOBJECTS = \
 	guestfs_config.cmo \
 	common_gettext.cmo \
 	dev_t.cmo \
+	stringMap.cmo \
 	common_utils.cmo \
 	common_utils_tests.cmo
 common_utils_tests_XOBJECTS = $(common_utils_tests_BOBJECTS:.cmo=.cmx)
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 7bd02f8..2dfe475 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -796,6 +796,69 @@ let truncate_recursive (g : Guestfs.guestfs) dir =
   let files = List.filter g#is_file files in
   List.iter g#truncate files
 
+let debug_augeas_errors g =
+  if verbose () then (
+    try
+      let errors = g#aug_match "/augeas/files//error" in
+      let errors = Array.to_list errors in
+      let map =
+        List.fold_left (
+          fun map error ->
+            let detail_paths = g#aug_match (error ^ "//*") in
+            let detail_paths = Array.to_list detail_paths in
+            List.fold_left (
+              fun map path ->
+                (* path is "/augeas/files/<filename>/error/<field>".  Put
+                 * <filename>, <field> and the value of this Augeas field
+                 * into a map.
+                 *)
+                let i = String.find path "/error/" in
+                assert (i >= 0);
+                let filename = String.sub path 13 (i-13) in
+                let field =
+                  String.sub path (i+7) (String.length path - (i+7)) in
+
+                let detail = g#aug_get path in
+
+                let fmap : string StringMap.t =
+                  try StringMap.find filename map
+                  with Not_found -> StringMap.empty in
+                let fmap = StringMap.add field detail fmap in
+                StringMap.add filename fmap map
+            ) map detail_paths
+        ) StringMap.empty errors in
+
+      let filenames = StringMap.keys map in
+      let filenames = List.sort compare filenames in
+
+      List.iter (
+        fun filename ->
+          eprintf "augeas failed to parse %s:\n" filename;
+          let fmap = StringMap.find filename map in
+          (try
+            let msg = StringMap.find "message" fmap in
+            eprintf " error \"%s\"" msg
+          with Not_found -> ()
+          );
+          (try
+            let line = StringMap.find "line" fmap
+            and char = StringMap.find "char" fmap in
+            eprintf " at line %s char %s" line char
+          with Not_found -> ()
+          );
+          (try
+            let lens = StringMap.find "lens" fmap in
+            eprintf " in lens %s" lens
+          with Not_found -> ()
+          );
+          eprintf "\n"
+      ) filenames;
+
+      flush stderr
+    with
+      Guestfs.Error msg -> eprintf "%s: augeas: %s (ignored)\n" prog msg
+  )
+
 (* Detect type of a file. *)
 let detect_file_type filename =
   let chan = open_in filename in
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index 4cfe7d0..c66efa7 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -319,6 +319,20 @@ val truncate_recursive : Guestfs.guestfs -> string -> unit
 (** Using the libguestfs API, recurse into the given directory and
     truncate all files found to zero size. *)
 
+val debug_augeas_errors : Guestfs.guestfs -> unit
+(** In verbose mode, any Augeas errors which happened most recently
+    on the handle and printed on standard error.  You should usually
+    call this just after either [g#aug_init] or [g#aug_load].
+
+    Note this doesn't call {!error} if there were any errors on the
+    handle.  It is just for debugging.  It is expected that a
+    subsequent Augeas command will fail, eg. when trying to match
+    an Augeas path which is expected to exist but does not exist
+    because of a parsing error.  In that case turning on debugging
+    will reveal the parse error.
+
+    If not in verbose mode, this does nothing. *)
+
 val detect_file_type : string -> [`GZip | `Tar | `XZ | `Zip | `Unknown]
 (** Detect type of a file (for a very limited range of file types). *)
 
diff --git a/mllib/stringMap.ml b/mllib/stringMap.ml
new file mode 100644
index 0000000..ea47a6e
--- /dev/null
+++ b/mllib/stringMap.ml
@@ -0,0 +1,21 @@
+(* virt-v2v
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+include Map.Make (String)
+
+let keys map = fold (fun k _ ks -> k :: ks) map []
diff --git a/mllib/stringMap.mli b/mllib/stringMap.mli
new file mode 100644
index 0000000..b668538
--- /dev/null
+++ b/mllib/stringMap.mli
@@ -0,0 +1,54 @@
+(* virt-v2v
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+type key = String.t
+type 'a t = 'a Map.Make(String).t
+
+val empty : 'a t
+val is_empty : 'a t -> bool
+val mem : key -> 'a t -> bool
+val add : key -> 'a -> 'a t -> 'a t
+(*
+val singleton : key -> 'a -> 'a t
+*)
+val remove : key -> 'a t -> 'a t
+(*
+val merge : (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t
+*)
+val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
+val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
+val iter : (key -> 'a -> unit) -> 'a t -> unit
+val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+(*
+val for_all : (key -> 'a -> bool) -> 'a t -> bool
+val exists : (key -> 'a -> bool) -> 'a t -> bool
+val filter : (key -> 'a -> bool) -> 'a t -> 'a t
+val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
+val cardinal : 'a t -> int
+val bindings : 'a t -> (key * 'a) list
+val min_binding : 'a t -> key * 'a
+val max_binding : 'a t -> key * 'a
+val choose : 'a t -> key * 'a
+val split : key -> 'a t -> 'a t * 'a option * 'a t
+*)
+val find : key -> 'a t -> 'a
+val map : ('a -> 'b) -> 'a t -> 'b t
+(*
+val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
+*)
+val keys : 'a t -> key list
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index 5937ff5..4ea49a5 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -52,6 +52,7 @@ mllib/mkdtemp.ml
 mllib/planner.ml
 mllib/progress.ml
 mllib/regedit.ml
+mllib/stringMap.ml
 resize/resize.ml
 sparsify/cmdline.ml
 sparsify/copying.ml
@@ -123,7 +124,6 @@ v2v/output_null.ml
 v2v/output_qemu.ml
 v2v/output_rhev.ml
 v2v/output_vdsm.ml
-v2v/stringMap.ml
 v2v/target_bus_assignment.ml
 v2v/test-harness/v2v_test_harness.ml
 v2v/types.ml
diff --git a/resize/Makefile.am b/resize/Makefile.am
index e9f48da..c3c025d 100644
--- a/resize/Makefile.am
+++ b/resize/Makefile.am
@@ -60,6 +60,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(SOURCES_ML:.ml=.cmo)
 XOBJECTS = $(BOBJECTS:.cmo=.cmx)
diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am
index 9dd9179..22a684b 100644
--- a/sparsify/Makefile.am
+++ b/sparsify/Makefile.am
@@ -59,6 +59,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/progress.cmo \
 	$(top_builddir)/mllib/StatVFS.cmo \
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index e439a88..46cc324 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -108,6 +108,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/URI.cmo \
 	$(top_builddir)/mllib/mkdtemp.cmo \
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index e0d013a..09a63a0 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -70,7 +70,6 @@ SOURCES_MLI = \
 	output_rhev.mli \
 	output_vdsm.mli \
 	OVF.mli \
-	stringMap.mli \
 	target_bus_assignment.mli \
 	types.mli \
 	utils.mli \
@@ -80,7 +79,6 @@ SOURCES_MLI = \
 	xml.mli
 
 SOURCES_ML = \
-	stringMap.ml \
 	types.ml \
 	xml.ml \
 	utils.ml \
@@ -142,6 +140,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/regedit.cmo \
 	$(top_builddir)/mllib/mkdtemp.cmo \
@@ -212,6 +211,7 @@ COPY_TO_LOCAL_BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/JSON.cmo \
 	$(top_builddir)/mllib/StatVFS.cmo \
@@ -373,9 +373,9 @@ v2v_unit_tests_BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/mllib/regedit.cmo \
-	stringMap.cmo \
 	types.cmo \
 	xml.cmo \
 	utils.cmo \
diff --git a/v2v/linux.ml b/v2v/linux.ml
index 8c1fde2..46cb3ba 100644
--- a/v2v/linux.ml
+++ b/v2v/linux.ml
@@ -31,71 +31,11 @@ module G = Guestfs
  *)
 let rec augeas_init g =
   g#aug_init "/" 1;
-  if verbose () then augeas_debug_errors g
+  debug_augeas_errors g
 
 and augeas_reload g =
   g#aug_load ();
-  if verbose () then augeas_debug_errors g
-
-and augeas_debug_errors g =
-  try
-    let errors = g#aug_match "/augeas/files//error" in
-    let errors = Array.to_list errors in
-    let map =
-      List.fold_left (
-        fun map error ->
-          let detail_paths = g#aug_match (error ^ "//*") in
-          let detail_paths = Array.to_list detail_paths in
-          List.fold_left (
-            fun map path ->
-              (* path is "/augeas/files/<filename>/error/<field>".  Put
-               * <filename>, <field> and the value of this Augeas field
-               * into a map.
-               *)
-              let i = String.find path "/error/" in
-              assert (i >= 0);
-              let filename = String.sub path 13 (i-13) in
-              let field = String.sub path (i+7) (String.length path - (i+7)) in
-
-              let detail = g#aug_get path in
-
-              let fmap : string StringMap.t =
-                try StringMap.find filename map
-                with Not_found -> StringMap.empty in
-              let fmap = StringMap.add field detail fmap in
-              StringMap.add filename fmap map
-          ) map detail_paths
-      ) StringMap.empty errors in
-
-    let filenames = StringMap.keys map in
-    let filenames = List.sort compare filenames in
-
-    List.iter (
-      fun filename ->
-        eprintf "augeas failed to parse %s:\n" filename;
-        let fmap = StringMap.find filename map in
-        (try
-           let msg = StringMap.find "message" fmap in
-           eprintf " error \"%s\"" msg
-         with Not_found -> ()
-        );
-        (try
-           let line = StringMap.find "line" fmap
-           and char = StringMap.find "char" fmap in
-           eprintf " at line %s char %s" line char
-         with Not_found -> ()
-        );
-        (try
-           let lens = StringMap.find "lens" fmap in
-           eprintf " in lens %s" lens
-         with Not_found -> ()
-        );
-        eprintf "\n"
-    ) filenames;
-
-    flush stderr
-  with
-    Guestfs.Error msg -> eprintf "%s: augeas: %s (ignored)\n" prog msg
+  debug_augeas_errors g
 
 let remove g inspect packages =
   if packages <> [] then (
diff --git a/v2v/stringMap.ml b/v2v/stringMap.ml
deleted file mode 100644
index ea47a6e..0000000
--- a/v2v/stringMap.ml
+++ /dev/null
@@ -1,21 +0,0 @@
-(* virt-v2v
- * Copyright (C) 2009-2016 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *)
-
-include Map.Make (String)
-
-let keys map = fold (fun k _ ks -> k :: ks) map []
diff --git a/v2v/stringMap.mli b/v2v/stringMap.mli
deleted file mode 100644
index b668538..0000000
--- a/v2v/stringMap.mli
+++ /dev/null
@@ -1,54 +0,0 @@
-(* virt-v2v
- * Copyright (C) 2009-2016 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *)
-
-type key = String.t
-type 'a t = 'a Map.Make(String).t
-
-val empty : 'a t
-val is_empty : 'a t -> bool
-val mem : key -> 'a t -> bool
-val add : key -> 'a -> 'a t -> 'a t
-(*
-val singleton : key -> 'a -> 'a t
-*)
-val remove : key -> 'a t -> 'a t
-(*
-val merge : (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t
-*)
-val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
-val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
-val iter : (key -> 'a -> unit) -> 'a t -> unit
-val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
-(*
-val for_all : (key -> 'a -> bool) -> 'a t -> bool
-val exists : (key -> 'a -> bool) -> 'a t -> bool
-val filter : (key -> 'a -> bool) -> 'a t -> 'a t
-val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
-val cardinal : 'a t -> int
-val bindings : 'a t -> (key * 'a) list
-val min_binding : 'a t -> key * 'a
-val max_binding : 'a t -> key * 'a
-val choose : 'a t -> key * 'a
-val split : key -> 'a t -> 'a t * 'a option * 'a t
-*)
-val find : key -> 'a t -> 'a
-val map : ('a -> 'b) -> 'a t -> 'b t
-(*
-val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
-*)
-val keys : 'a t -> key list
diff --git a/v2v/test-harness/Makefile.am b/v2v/test-harness/Makefile.am
index cba5b41..5b376f0 100644
--- a/v2v/test-harness/Makefile.am
+++ b/v2v/test-harness/Makefile.am
@@ -61,6 +61,7 @@ BOBJECTS = \
 	$(top_builddir)/mllib/guestfs_config.cmo \
 	$(top_builddir)/mllib/common_gettext.cmo \
 	$(top_builddir)/mllib/dev_t.cmo \
+	$(top_builddir)/mllib/stringMap.cmo \
 	$(top_builddir)/mllib/common_utils.cmo \
 	$(top_builddir)/v2v/xml.cmo \
 	$(SOURCES_ML:.ml=.cmo) \
-- 
2.7.4