util: introduce compile time API version checking

GLib header files annotate every API with a version number.

It is possible to define some constants before including
glib.h which will result in useful compile time warnings.

Setting GLIB_VERSION_MIN_REQUIRED will result in a warning
if libvirt uses an API that was deprecated in the declared
version, or before. Such API usage should be rewritten to
use the documented new replacement API.

Setting GLIB_VERSION_MAX_ALLOWED will result in a warning
if libvirt uses an API that was not introduced until a
version of GLib that's newer than our minimum declared
version. This avoids accidentally using functionality
that is not available on some supported platforms.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2020-01-03 17:54:12 +00:00
parent fcea025d0e
commit f08d5dada4
2 changed files with 49 additions and 0 deletions

View File

@ -49,3 +49,13 @@
#else #else
# error You either need at least GCC 4.8 or Clang 3.4 or XCode Clang 5.1 to compile libvirt # error You either need at least GCC 4.8 or Clang 3.4 or XCode Clang 5.1 to compile libvirt
#endif #endif
/* Ask for warnings for anything that was marked deprecated in
* the defined version, or before. It is a candidate for rewrite.
*/
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_48
/* Ask for warnings if code tries to use function that did not
* exist in the defined version. These risk breaking builds
*/
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_48

View File

@ -24,6 +24,45 @@
#include "glibcompat.h" #include "glibcompat.h"
/*
* Note that because of the GLIB_VERSION_MAX_ALLOWED constant in
* config-post.h, allowing use of functions from newer GLib via
* this compat impl needs a little trickery to prevent warnings
* being emitted.
*
* Consider a function from newer glib-X.Y that we want to use
*
* int g_foo(const char *wibble)
*
* We must define a function with the same signature that does
* what we need, but with a "vir_" prefix e.g.
*
* void vir_g_foo(const char *wibble)
* {
* #if GLIB_CHECK_VERSION(X, Y, 0)
* g_foo(wibble)
* #else
* g_something_equivalent_in_older_glib(wibble);
* #endif
* }
*
* The #pragma at the top of this file turns off -Wdeprecated-declarations,
* ensuring this wrapper function impl doesn't trigger the compiler
* warning about using too new glib APIs. Finally in glibcompat.h we can
* add
*
* #define g_foo(a) vir_g_foo(a)
*
* Thus all the code elsewhere in libvirt, which *does* have the
* -Wdeprecated-declarations warning active, can call g_foo(...) as
* normal, without generating warnings. The cost is an extra function
* call when using new glib, but this compat code will go away over
* time as we update the supported platforms target.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#undef g_canonicalize_filename #undef g_canonicalize_filename
#undef g_fsync #undef g_fsync
#undef g_strdup_printf #undef g_strdup_printf