The ‘Visit’ module is a self-contained library with the only dependencies being:
- the C ‘visit’ implementation - the guestfs OCaml bindings Move it to a separate ‘common/mlvisit’ directory. This change is not entirely refactoring. Two other fixes are made: - remove unsafe use of CLEANUP_FREE from a function which could raise an OCaml exception (cleanup handlers would not be called correctly if the exception is thrown) - don't link directly to common/visit/visit.c, but instead use the library (common/visit/libvisit.la) --- .gitignore | 3 +- Makefile.am | 5 +- common/mlvisit/Makefile.am | 152 +++++++++++++++++++++++++++++++ common/mlvisit/dummy.c | 2 + {mllib => common/mlvisit}/visit-c.c | 6 +- {mllib => common/mlvisit}/visit.ml | 0 {mllib => common/mlvisit}/visit.mli | 0 {mllib => common/mlvisit}/visit_tests.ml | 0 configure.ac | 1 + docs/C_SOURCE_FILES | 3 +- docs/guestfs-hacking.pod | 4 + mllib/Makefile.am | 30 +----- sysprep/Makefile.am | 10 +- 13 files changed, 180 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 69e1ae160..2367cddcb 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,8 @@ Makefile.in /common/errnostring/errnostring-gperf.gperf /common/errnostring/errnostring.h /common/miniexpect/miniexpect.3 +/common/mlvisit/.depend +/common/mlvisit/visit_tests /common/protocol/guestfs_protocol.c /common/protocol/guestfs_protocol.h /common/protocol/guestfs_protocol.x @@ -366,7 +368,6 @@ Makefile.in /mllib/JSON_tests /mllib/libdir.ml /mllib/oUnit-* -/mllib/visit_tests /ocaml/bindtests.bc /ocaml/bindtests.opt /ocaml/bindtests.ml diff --git a/Makefile.am b/Makefile.am index ae77cdda2..499a1d279 100644 --- a/Makefile.am +++ b/Makefile.am @@ -150,10 +150,11 @@ endif # Unconditional because nothing is built yet. SUBDIRS += csharp -# OCaml tools. Note 'mllib' and 'customize' contain shared code used -# by other OCaml tools, so these must come first. +# OCaml tools. Note 'common/ml*', 'mllib' and 'customize' contain +# shared code used by other OCaml tools, so these must come first. if HAVE_OCAML SUBDIRS += \ + common/mlvisit \ mllib \ customize \ builder builder/templates \ diff --git a/common/mlvisit/Makefile.am b/common/mlvisit/Makefile.am new file mode 100644 index 000000000..51cbd2de6 --- /dev/null +++ b/common/mlvisit/Makefile.am @@ -0,0 +1,152 @@ +# libguestfs OCaml tools common code +# Copyright (C) 2011-2017 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 $(top_srcdir)/subdir-rules.mk + +EXTRA_DIST = \ + $(SOURCES_MLI) \ + $(SOURCES_ML) \ + $(SOURCES_C) \ + visit_tests.ml + +SOURCES_MLI = \ + visit.mli + +SOURCES_ML = \ + visit.ml + +SOURCES_C = \ + visit-c.c + +if HAVE_OCAML + +# We pretend that we're building a C library. automake handles the +# compilation of the C sources for us. At the end we take the C +# objects and OCaml objects and link them into the OCaml library. +# This C library is never used. + +noinst_LIBRARIES = libmlvisit.a + +if !HAVE_OCAMLOPT +MLVISIT_CMA = mlvisit.cma +else +MLVISIT_CMA = mlvisit.cmxa +endif + +noinst_DATA = $(MLVISIT_CMA) + +libmlvisit_a_SOURCES = $(SOURCES_C) +libmlvisit_a_CPPFLAGS = \ + -I. \ + -I$(top_builddir) \ + -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ + -I$(shell $(OCAMLC) -where) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/common/visit +libmlvisit_a_CFLAGS = \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBVIRT_CFLAGS) $(LIBXML2_CFLAGS) \ + -fPIC + +BOBJECTS = $(SOURCES_ML:.ml=.cmo) +XOBJECTS = $(BOBJECTS:.cmo=.cmx) + +# -I $(top_builddir)/lib/.libs is a hack which forces corresponding -L +# option to be passed to gcc, so we don't try linking against an +# installed copy of libguestfs. +OCAMLPACKAGES = \ + -package str,unix \ + -I $(top_builddir)/lib/.libs \ + -I $(top_builddir)/gnulib/lib/.libs \ + -I $(top_builddir)/ocaml \ + -I $(top_builddir)/common/utils/.libs \ + -I $(top_builddir)/common/visit/.libs \ + -I $(builddir) +OCAMLPACKAGES_TESTS = $(MLVISIT_CMA) + +OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) + +if !HAVE_OCAMLOPT +OBJECTS = $(BOBJECTS) +else +OBJECTS = $(XOBJECTS) +endif + +libmlvisit_a_DEPENDENCIES = $(OBJECTS) + +$(MLVISIT_CMA): $(OBJECTS) libmlvisit.a + $(OCAMLFIND) mklib $(OCAMLPACKAGES) \ + $(OBJECTS) $(libmlvisit_a_OBJECTS) -cclib -lvisit -o mlvisit + +# Tests. + +visit_tests_SOURCES = dummy.c +visit_tests_BOBJECTS = visit_tests.cmo +visit_tests_XOBJECTS = $(visit_tests_BOBJECTS:.cmo=.cmx) + +# Can't call the following as <test>_OBJECTS because automake gets confused. +if !HAVE_OCAMLOPT +visit_tests_THEOBJECTS = $(visit_tests_BOBJECTS) +visit_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS) +else +visit_tests_THEOBJECTS = $(visit_tests_XOBJECTS) +visit_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS) +endif + +OCAMLLINKFLAGS = mlguestfs.$(MLARCHIVE) $(LINK_CUSTOM_OCAMLC_ONLY) + +visit_tests_DEPENDENCIES = \ + $(visit_tests_THEOBJECTS) \ + $(MLVISIT_CMA) \ + $(top_srcdir)/ocaml-link.sh +visit_tests_LINK = \ + $(top_srcdir)/ocaml-link.sh \ + -cclib '-lvisit -lutils $(LIBXML2_LIBS) -lgnu' -- \ + $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \ + $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \ + $(visit_tests_THEOBJECTS) -o $@ + +TESTS_ENVIRONMENT = $(top_builddir)/run --test + +check_PROGRAMS = +TESTS = + +if ENABLE_APPLIANCE +check_PROGRAMS += visit_tests +TESTS += visit_tests +endif + +check-valgrind: + $(MAKE) VG="@VG@" check + +# Dependencies. +depend: .depend + +.depend: $(wildcard $(abs_srcdir)/*.mli) $(wildcard $(abs_srcdir)/*.ml) + rm -f $@ $@-t + $(OCAMLFIND) ocamldep -I ../../ocaml -I $(abs_srcdir) $^ | \ + $(SED) 's/ *$$//' | \ + $(SED) -e :a -e '/ *\\$$/N; s/ *\\\n */ /; ta' | \ + $(SED) -e 's,$(abs_srcdir)/,$(builddir)/,g' | \ + sort > $@-t + mv $@-t $@ + +-include .depend + +endif + +.PHONY: depend docs diff --git a/common/mlvisit/dummy.c b/common/mlvisit/dummy.c new file mode 100644 index 000000000..ebab6198c --- /dev/null +++ b/common/mlvisit/dummy.c @@ -0,0 +1,2 @@ +/* Dummy source, to be used for OCaml-based tools with no C sources. */ +enum { foo = 1 }; diff --git a/mllib/visit-c.c b/common/mlvisit/visit-c.c similarity index 98% rename from mllib/visit-c.c rename to common/mlvisit/visit-c.c index b1c12166c..4cd1c6cea 100644 --- a/mllib/visit-c.c +++ b/common/mlvisit/visit-c.c @@ -31,7 +31,6 @@ #include <caml/mlvalues.h> #include "guestfs.h" -#include "guestfs-internal.h" #include "visit.h" #pragma GCC diagnostic ignored "-Wmissing-prototypes" @@ -59,7 +58,7 @@ guestfs_int_mllib_visit (value gv, value dirv, value fv) /* The dir string could move around when we call the * visitor_function, so we have to take a full copy of it. */ - CLEANUP_FREE char *dir = strdup (String_val (dirv)); + char *dir = strdup (String_val (dirv)); /* This stack address is used to point to the exception, if one is * raised in the visitor_function. */ @@ -71,6 +70,8 @@ guestfs_int_mllib_visit (value gv, value dirv, value fv) args.fvp = &fv; if (visit (g, dir, visitor_function_wrapper, &args) == -1) { + free (dir); + if (exn != Val_unit) { /* The failure was caused by visitor_function raising an * exception. Re-raise it here. @@ -84,6 +85,7 @@ guestfs_int_mllib_visit (value gv, value dirv, value fv) */ caml_failwith ("visit"); } + free (dir); CAMLreturn (Val_unit); } diff --git a/mllib/visit.ml b/common/mlvisit/visit.ml similarity index 100% rename from mllib/visit.ml rename to common/mlvisit/visit.ml diff --git a/mllib/visit.mli b/common/mlvisit/visit.mli similarity index 100% rename from mllib/visit.mli rename to common/mlvisit/visit.mli diff --git a/mllib/visit_tests.ml b/common/mlvisit/visit_tests.ml similarity index 100% rename from mllib/visit_tests.ml rename to common/mlvisit/visit_tests.ml diff --git a/configure.ac b/configure.ac index cbb5101fc..4fc226123 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,7 @@ AC_CONFIG_FILES([Makefile common/errnostring/Makefile common/edit/Makefile common/miniexpect/Makefile + common/mlvisit/Makefile common/options/Makefile common/parallel/Makefile common/progress/Makefile diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES index dc8c052dd..37f930c29 100644 --- a/docs/C_SOURCE_FILES +++ b/docs/C_SOURCE_FILES @@ -15,6 +15,8 @@ common/edit/file-edit.c common/edit/file-edit.h common/miniexpect/miniexpect.c common/miniexpect/miniexpect.h +common/mlvisit/dummy.c +common/mlvisit/visit-c.c common/options/config.c common/options/decrypt.c common/options/display-options.c @@ -338,7 +340,6 @@ mllib/getopt-c.c mllib/progress-c.c mllib/unix_utils-c.c mllib/uri-c.c -mllib/visit-c.c mllib/xml-c.c ocaml/guestfs-c-actions.c ocaml/guestfs-c-errnos.c diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod index d3621c7e6..ac6d1ccbf 100644 --- a/docs/guestfs-hacking.pod +++ b/docs/guestfs-hacking.pod @@ -100,6 +100,10 @@ A copy of the miniexpect library from L<http://git.annexia.org/?p=miniexpect.git;a=summary>. This is used in virt-p2v. +=item F<common/mlvisit> + +OCaml bindings for the visit functions (see F<common/visit>). + =item F<common/options> Common options parsing for guestfish, guestmount and some virt tools. diff --git a/mllib/Makefile.am b/mllib/Makefile.am index ee2f1a7a8..cb79f50f5 100644 --- a/mllib/Makefile.am +++ b/mllib/Makefile.am @@ -24,7 +24,6 @@ EXTRA_DIST = \ common_utils_tests.ml \ getopt_tests.ml \ JSON_tests.ml \ - visit_tests.ml \ test-getopt.sh SOURCES_MLI = \ @@ -41,8 +40,7 @@ SOURCES_MLI = \ regedit.mli \ registry.mli \ stringMap.mli \ - URI.mli \ - visit.mli + URI.mli SOURCES_ML = \ guestfs_config.ml \ @@ -55,7 +53,6 @@ SOURCES_ML = \ common_utils.ml \ progress.ml \ URI.ml \ - visit.ml \ planner.ml \ registry.ml \ regedit.ml \ @@ -66,7 +63,6 @@ SOURCES_ML = \ xpath_helpers.ml SOURCES_C = \ - ../common/visit/visit.c \ ../common/options/decrypt.c \ ../common/options/keys.c \ ../common/options/uri.c \ @@ -76,7 +72,6 @@ SOURCES_C = \ progress-c.c \ unix_utils-c.c \ uri-c.c \ - visit-c.c \ xml-c.c if HAVE_OCAML @@ -104,7 +99,6 @@ libmllib_a_CPPFLAGS = \ -I$(shell $(OCAMLC) -where) \ -I$(top_srcdir)/common/utils \ -I$(top_srcdir)/lib \ - -I$(top_srcdir)/common/visit \ -I$(top_srcdir)/common/options \ -I$(top_srcdir)/common/progress libmllib_a_CFLAGS = \ @@ -187,10 +181,6 @@ JSON_tests_SOURCES = dummy.c JSON_tests_BOBJECTS = JSON_tests.cmo JSON_tests_XOBJECTS = $(JSON_tests_BOBJECTS:.cmo=.cmx) -visit_tests_SOURCES = dummy.c -visit_tests_BOBJECTS = visit_tests.cmo -visit_tests_XOBJECTS = $(visit_tests_BOBJECTS:.cmo=.cmx) - # Can't call the following as <test>_OBJECTS because automake gets confused. if !HAVE_OCAMLOPT common_utils_tests_THEOBJECTS = $(common_utils_tests_BOBJECTS) @@ -210,9 +200,6 @@ getopt_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS) JSON_tests_THEOBJECTS = $(JSON_tests_XOBJECTS) JSON_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS) - -visit_tests_THEOBJECTS = $(visit_tests_XOBJECTS) -visit_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS) endif OCAMLLINKFLAGS = mlguestfs.$(MLARCHIVE) $(LINK_CUSTOM_OCAMLC_ONLY) @@ -247,16 +234,6 @@ JSON_tests_LINK = \ $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \ $(JSON_tests_THEOBJECTS) -o $@ -visit_tests_DEPENDENCIES = \ - $(visit_tests_THEOBJECTS) \ - $(MLLIB_CMA) \ - $(top_srcdir)/ocaml-link.sh -visit_tests_LINK = \ - $(top_srcdir)/ocaml-link.sh -cclib '-lutils $(LIBXML2_LIBS) -lgnu' -- \ - $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \ - $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \ - $(visit_tests_THEOBJECTS) -o $@ - TESTS_ENVIRONMENT = $(top_builddir)/run --test TESTS = \ @@ -269,11 +246,6 @@ check_PROGRAMS += common_utils_tests JSON_tests TESTS += common_utils_tests JSON_tests endif -if ENABLE_APPLIANCE -check_PROGRAMS += visit_tests -TESTS += visit_tests -endif - check-valgrind: $(MAKE) VG="@VG@" check diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am index 2a1ca25fd..68cb1814a 100644 --- a/sysprep/Makefile.am +++ b/sysprep/Makefile.am @@ -111,6 +111,8 @@ OCAMLPACKAGES = \ -I $(top_builddir)/lib/.libs \ -I $(top_builddir)/gnulib/lib/.libs \ -I $(top_builddir)/ocaml \ + -I $(top_builddir)/common/visit/.libs \ + -I $(top_builddir)/common/mlvisit \ -I $(top_builddir)/mllib \ -I $(top_builddir)/customize if HAVE_OCAML_PKG_GETTEXT @@ -118,6 +120,7 @@ OCAMLPACKAGES += -package gettext-stub endif OCAMLCLIBS = \ + -lvisit \ -lutils \ $(LIBTINFO_LIBS) \ $(LIBCRYPT_LIBS) \ @@ -133,7 +136,12 @@ else OBJECTS = $(XOBJECTS) endif -OCAMLLINKFLAGS = mlguestfs.$(MLARCHIVE) mllib.$(MLARCHIVE) customize.$(MLARCHIVE) $(LINK_CUSTOM_OCAMLC_ONLY) +OCAMLLINKFLAGS = \ + mlguestfs.$(MLARCHIVE) \ + mllib.$(MLARCHIVE) \ + mlvisit.$(MLARCHIVE) \ + customize.$(MLARCHIVE) \ + $(LINK_CUSTOM_OCAMLC_ONLY) virt_sysprep_DEPENDENCIES = \ $(OBJECTS) \ -- 2.13.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs