Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 3/3] python: Allow bindings to be compiled with different version of libguestfs (RHBZ#1262983).
Patch to fix: https://bugzilla.redhat.com/show_bug.cgi?id=1262983 Note this won't help until the first two patches get backported to the stable branches, since <guestfs.h> won't define the necessary GUESTFS_HAVE_* macros. Rich.
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 1/3] header: Define GUESTFS_HAVE_* for every function.
Previously we only defined GUESTFS_HAVE_* macros for functions that were not deprecated, test or debug functions. The reasoning for that is given in this commit message [note that 'LIBGUESTFS_HAVE_' is the old/deprecated macro]: commit 2d8fd7dacd77361bc385be42112289faafb5c60d Author: Richard Jones <rjones@redhat.com> Date: Thu Sep 2 22:45:54 2010 +0100 Define LIBGUESTFS_HAVE_<shortname> for C API functions. The actions each have a corresponding define, eg: #define LIBGUESTFS_HAVE_VGUUID 1 extern char *guestfs_vguuid (guestfs_h *g, const char *vgname); However functions which are for testing, debugging or deprecated do not have the corresponding define. Also a few functions are so basic (eg. guestfs_create) that there is no point defining a symbol for them. This wasn't in fact carried through very consistently, since when we replaced s/LIBGUESTFS_HAVE_/GUESTFS_HAVE_/, we kept the old LIBGUESTFS_HAVE_* macros, but defined them for every function. Oops. This commit defines GUESTFS_HAVE_* for every function in <guestfs.h>, making it easier to write the Python language bindings (see following commits). --- generator/c.ml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/generator/c.ml b/generator/c.ml index a2b9c94..ae8e933 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -645,13 +645,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char * let generate_action_header { name = shortname; style = ret, args, optargs as style; deprecated_by = deprecated_by } - let test - String.length shortname >= 13 && - String.sub shortname 0 13 = "internal_test" in - let debug - String.length shortname >= 5 && String.sub shortname 0 5 = "debug" in - if deprecated_by = None && not test && not debug then - pr "#define GUESTFS_HAVE_%s 1\n" (String.uppercase shortname); + pr "#define GUESTFS_HAVE_%s 1\n" (String.uppercase shortname); if optargs <> [] then ( iteri ( -- 2.5.0
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 2/3] header: Define GUESTFS_HAVE_STRUCT_* for each struct defined in the header.
--- generator/c.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generator/c.ml b/generator/c.ml index ae8e933..055b683 100644 --- a/generator/c.ml +++ b/generator/c.ml @@ -603,6 +603,8 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char * (* Public structures. *) let generate_all_structs = List.iter ( fun { s_name = typ; s_cols = cols } -> + pr "#define GUESTFS_HAVE_STRUCT_%s 1\n" (String.uppercase typ); + pr "\n"; pr "struct guestfs_%s {\n" typ; List.iter ( function -- 2.5.0
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 3/3] python: Allow bindings to be compiled with different version of libguestfs (RHBZ#1262983).
When compiling the libguestfs bindings as a pip module, it's helpful if you can compile the bindings with a different version of libguestfs (eg. installed 1.28, pip module 1.30). That broke the previous assumption that we were always compiling against precisely the same version of libguestfs (which made sense because the python bindings are part of the libguestfs source tree). Python distutils has no way to check a C library to find out if functions are defined. Therefore we have to rely on GUESTFS_HAVE_* macros from <guestfs.h>. --- generator/python.ml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/generator/python.ml b/generator/python.ml index 637f22d..c1128f8 100644 --- a/generator/python.ml +++ b/generator/python.ml @@ -140,6 +140,7 @@ put_table (char * const * const argv) "; let emit_put_list_function typ + pr "#ifdef GUESTFS_HAVE_STRUCT_%s\n" (String.uppercase typ); pr "static PyObject *\n"; pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ; pr "{\n"; @@ -151,12 +152,14 @@ put_table (char * const * const argv) pr " PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ; pr " return list;\n"; pr "};\n"; + pr "#endif\n"; pr "\n" in (* Structures, turned into Python dictionaries. *) List.iter ( fun { s_name = typ; s_cols = cols } -> + pr "#ifdef GUESTFS_HAVE_STRUCT_%s\n" (String.uppercase typ); pr "static PyObject *\n"; pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ; pr "{\n"; @@ -228,6 +231,7 @@ put_table (char * const * const argv) ) cols; pr " return dict;\n"; pr "};\n"; + pr "#endif\n"; pr "\n"; ) external_structs; @@ -246,6 +250,7 @@ put_table (char * const * const argv) fun { name = name; style = (ret, args, optargs as style); blocking = blocking; c_function = c_function; c_optarg_prefix = c_optarg_prefix } -> + pr "#ifdef GUESTFS_HAVE_%s\n" (String.uppercase name); pr "static PyObject *\n"; pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name; pr "{\n"; @@ -381,6 +386,7 @@ put_table (char * const * const argv) fun optarg -> let n = name_of_optargt optarg in let uc_n = String.uppercase n in + pr "#ifdef %s_%s_BITMASK\n" c_optarg_prefix uc_n; pr " if (py_%s != Py_None) {\n" n; pr " optargs_s.bitmask |= %s_%s_BITMASK;\n" c_optarg_prefix uc_n; (match optarg with @@ -403,6 +409,7 @@ put_table (char * const * const argv) pr " if (!optargs_s.%s) goto out;\n" n; ); pr " }\n"; + pr "#endif\n" ) optargs; pr "\n" ); @@ -524,13 +531,16 @@ put_table (char * const * const argv) | OBool _ | OInt _ | OInt64 _ | OString _ -> () | OStringList n -> let uc_n = String.uppercase n in + pr "#ifdef %s_%s_BITMASK\n" c_optarg_prefix uc_n; pr " if (py_%s != Py_None && (optargs_s.bitmask & %s_%s_BITMASK) != 0)\n" n c_optarg_prefix uc_n; - pr " free ((char **) optargs_s.%s);\n" n + pr " free ((char **) optargs_s.%s);\n" n; + pr "#endif\n" ) optargs; pr " return py_r;\n"; pr "}\n"; + pr "#endif\n"; pr "\n" ) external_functions_sorted; @@ -546,8 +556,10 @@ put_table (char * const * const argv) pr " py_guestfs_event_to_string, METH_VARARGS, NULL },\n"; List.iter ( fun { name = name } -> + pr "#ifdef GUESTFS_HAVE_%s\n" (String.uppercase name); pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n" - name name + name name; + pr "#endif\n" ) external_functions_sorted; pr " { NULL, NULL, 0, NULL }\n"; pr "};\n"; -- 2.5.0
Reasonably Related Threads
- [PATCH] python: fix possible free on uninit memory with OStringList optargs
- [PATCH 0/7] Add tar compress, numericowner, excludes flags.
- [PATCH 1/4] php: fix invalid memory access with OptString
- [PATCH 0/6] Allow non-optargs functions to gain optional arguments.
- [PATCH] generator: Share Common_utils code.