summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2012-02-20 16:20:15 +0000
committerMatthias Clasen <mclasen@redhat.com>2012-02-26 23:58:41 -0500
commit34aeeb7d64a0433f7994dd2b3f60bc018f0a84c1 (patch)
treec01b548de1751785bfe50d8ee035b013b5e60490
parentd70634526d43a9d9281301c2097c788ca575e318 (diff)
downloadglib-34aeeb7d64a0433f7994dd2b3f60bc018f0a84c1.tar.gz
Add flexible API version boundaries
There are cases when it should be possible to define at compile time what range of functions and types should be used, in order to get, or restrict, the compiler warnings for deprecated or newly added types or functions. For instance, if GLib introduces a deprecation warning on a type in version 2.32, application code can decide to specify the minimum and maximum boundary of the used API to be 2.30; when compiling against a new version of GLib, this would produce the following results: - all deprecations introduced prior to 2.32 would emit compiler warnings when used by the application code; - all deprecations introduced in 2.32 would not emit compiler warnings when used by the application code; - all new symbols introduced in 2.32 would emit a compiler warning. Using this scheme it should be possible to have fairly complex situations, like the following one: assuming that an application is compiled with: GLIB_VERSION_MIN_REQUIRED = GLIB_VERSION_2_30 GLIB_VERSION_MAX_ALLOWED = GLIB_VERSION_2_32 and a GLib header containing: void function_A (void) GLIB_DEPRECATED_IN_2_26; void function_B (void) GLIB_DEPRECATED_IN_2_28; void function_C (void) GLIB_DEPRECATED_IN_2_30; void function_D (void) GLIB_AVAILABLE_IN_2_32; void function_E (void) GLIB_AVAILABLE_IN_2_34; any application code using the above functions will get the following compiler warnings: function_A: deprecated symbol warning function_B: deprecated symbol warning function_C: no warning function_D: no warning function_E: undefined symbol warning This means that it should be possible to gradually port code towards non-deprecated API gradually, on a per-release basis. https://bugzilla.gnome.org/show_bug.cgi?id=670542
-rw-r--r--configure.ac4
-rw-r--r--docs/reference/glib/compiling.sgml9
-rw-r--r--docs/reference/glib/glib-sections.txt9
-rw-r--r--glib/Makefile.am1
-rw-r--r--glib/docs.c32
-rw-r--r--glib/glib.h1
-rw-r--r--glib/gmacros.h9
-rw-r--r--glib/gtypes.h1
-rw-r--r--glib/gversion.c12
-rw-r--r--glib/gversionmacros.h206
10 files changed, 284 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 72e396f5a..ec5f73cdf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,10 @@ m4_define(glib_configure_ac)
# if backwards compatibility has been broken,
# set glib_binary_age _and_ glib_interface_age to 0.
#
+# remember to add a GLIB_VERSION_2_xx macro every time the minor version is
+# bumped, as well as the GLIB_DEPRECATED_IN and GLIB_AVAILABLE_IN macros
+# for that version - see gversion.h for further information.
+#
# in easier to understand terms:
#
# <mclasen> on the stable branch, interface age == micro
diff --git a/docs/reference/glib/compiling.sgml b/docs/reference/glib/compiling.sgml
index cc72edabe..fb43b09d5 100644
--- a/docs/reference/glib/compiling.sgml
+++ b/docs/reference/glib/compiling.sgml
@@ -78,6 +78,15 @@ problematic, they can be turned off by defining the preprocessor
symbol GLIB_DISABLE_DEPRECATION_WARNINGS by using the commandline
option <literal>-DGLIB_DISABLE_DEPRECATION_WARNINGS</literal>
</para>
+
+<para>
+GLib deprecation annotations are versioned; by defining the
+macros %GLIB_VERSION_MIN_REQUIRED and %GLIB_VERSION_MAX_ALLOWED,
+you can specify the range of GLib versions whose API you want
+to use. APIs that were deprecated before or introduced after
+this range will trigger compiler warnings.
+</para>
+
<para>
The older deprecation mechanism of hiding deprecated interfaces
entirely from the compiler by using the preprocessor symbol
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 1f829f09f..5f2821610 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -112,6 +112,14 @@ GLIB_MAJOR_VERSION
GLIB_MINOR_VERSION
GLIB_MICRO_VERSION
GLIB_CHECK_VERSION
+
+<SUBSECTION>
+GLIB_VERSION_2_26
+GLIB_VERSION_2_28
+GLIB_VERSION_2_30
+GLIB_VERSION_2_32
+GLIB_VERSION_MIN_REQUIRED
+GLIB_VERSION_MAX_ALLOWED
</SECTION>
<SECTION>
@@ -355,6 +363,7 @@ G_GNUC_MAY_ALIAS
<SUBSECTION>
G_DEPRECATED
G_DEPRECATED_FOR
+G_UNAVAILABLE
<SUBSECTION>
G_LIKELY
diff --git a/glib/Makefile.am b/glib/Makefile.am
index db0e96861..1d7fb6e0f 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -317,6 +317,7 @@ glibsubinclude_HEADERS = \
gvarianttype.h \
gvariant.h \
gversion.h \
+ gversionmacros.h \
gwin32.h \
gprintf.h
diff --git a/glib/docs.c b/glib/docs.c
index f680ae071..a7a6cdec1 100644
--- a/glib/docs.c
+++ b/glib/docs.c
@@ -2020,6 +2020,38 @@
*/
/**
+ * G_DEPRECATED:
+ *
+ * This macro is similar to %G_GNUC_DEPRECATED, and can be used to mark
+ * functions declarations as deprecated. Unlike %G_GNUC_DEPRECATED, it is
+ * meant to be portable across different compilers and must be placed
+ * before the function declaration.
+ *
+ * Since: 2.32
+ */
+
+/**
+ * G_DEPRECATED_FOR:
+ *
+ * This macro is similar to %G_GNUC_DEPRECATED_FOR, and can be used to mark
+ * functions declarations as deprecated. Unlike %G_GNUC_DEPRECATED_FOR, it is
+ * meant to be portable across different compilers and must be placed
+ * before the function declaration.
+ *
+ * Since: 2.32
+ */
+
+/**
+ * G_UNAVAILABLE:
+ *
+ * This macro can be used to mark a function declaration as unavailable.
+ * It must be placed before the function declaration. Use of a function
+ * that has been annotated with this macros will produce a compiler warning.
+ *
+ * Since: 2.32
+ */
+
+/**
* G_GNUC_NORETURN:
*
* Expands to the GNU C <literal>noreturn</literal> function attribute
diff --git a/glib/glib.h b/glib/glib.h
index 06056a373..77abf2329 100644
--- a/glib/glib.h
+++ b/glib/glib.h
@@ -95,6 +95,7 @@
#include <glib/gvarianttype.h>
#include <glib/gvariant.h>
#include <glib/gversion.h>
+#include <glib/gversionmacros.h>
#ifdef G_PLATFORM_WIN32
#include <glib/gwin32.h>
#endif
diff --git a/glib/gmacros.h b/glib/gmacros.h
index be64e3214..0fbe71a90 100644
--- a/glib/gmacros.h
+++ b/glib/gmacros.h
@@ -316,6 +316,13 @@
#define G_DEPRECATED_FOR(f) G_DEPRECATED
#endif
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define G_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available for " #maj "." #min)))
+#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
+#define G_UNAVAILABLE(maj,min) __declspec(deprecated("is not available for " #maj "." #min))
+#else
+#define G_UNAVAILABLE(maj,min)
+#endif
/* These macros are used to mark deprecated functions in GLib headers,
* and thus have to be exposed in installed headers. But please
@@ -326,9 +333,11 @@
#ifdef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DEPRECATED
#define GLIB_DEPRECATED_FOR(f)
+#define GLIB_UNAVAILABLE(maj,min)
#else
#define GLIB_DEPRECATED G_DEPRECATED
#define GLIB_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f)
+#define GLIB_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min)
#endif
#endif /* __G_MACROS_H__ */
diff --git a/glib/gtypes.h b/glib/gtypes.h
index db07201e8..ca9e50d26 100644
--- a/glib/gtypes.h
+++ b/glib/gtypes.h
@@ -33,6 +33,7 @@
#include <glibconfig.h>
#include <glib/gmacros.h>
+#include <glib/gversionmacros.h>
#include <time.h>
G_BEGIN_DECLS
diff --git a/glib/gversion.c b/glib/gversion.c
index d80e262e8..70650b3ca 100644
--- a/glib/gversion.c
+++ b/glib/gversion.c
@@ -36,6 +36,18 @@
* GLib provides version information, primarily useful in configure
* checks for builds that have a configure script. Applications will
* not typically use the features described here.
+ *
+ * The GLib headers annotate deprecated APIs in a way that produces
+ * compiler warnings if these deprecated APIs are used. The warnings
+ * can be turned off by defining the macro %GLIB_DISABLE_DEPRECATION_WARNINGS
+ * before including the glib.h header.
+ *
+ * GLib also provides support for building applications against
+ * defined subsets of deprecated or new GLib APIs. Define the macro
+ * %GLIB_VERSION_MIN_REQUIRED to specify up to what version of GLib
+ * you want to receive warnings about deprecated APIs. Define the
+ * macro %GLIB_VERSION_MAX_ALLOWED to specify the newest version of
+ * GLib whose API you want to use.
*/
/**
diff --git a/glib/gversionmacros.h b/glib/gversionmacros.h
new file mode 100644
index 000000000..2d42497f9
--- /dev/null
+++ b/glib/gversionmacros.h
@@ -0,0 +1,206 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_VERSION_MACROS_H__
+#define __G_VERSION_MACROS_H__
+
+/* Version boundaries checks */
+
+#define G_ENCODE_VERSION(major,minor) ((major) << 16 | (minor) << 8)
+
+/* XXX: Every new stable minor release bump should add a macro here */
+
+/**
+ * GLIB_VERSION_2_26:
+ *
+ * A macro that evaluates to the 2.26 version of GLib, in a format
+ * that can be used by the C pre-processor.
+ *
+ * Since: 2.32
+ */
+#define GLIB_VERSION_2_26 (G_ENCODE_VERSION (2, 26))
+
+/**
+ * GLIB_VERSION_2_28:
+ *
+ * A macro that evaluates to the 2.28 version of GLib, in a format
+ * that can be used by the C pre-processor.
+ *
+ * Since: 2.32
+ */
+#define GLIB_VERSION_2_28 (G_ENCODE_VERSION (2, 28))
+
+/**
+ * GLIB_VERSION_2_30:
+ *
+ * A macro that evaluates to the 2.30 version of GLib, in a format
+ * that can be used by the C pre-processor.
+ *
+ * Since: 2.32
+ */
+#define GLIB_VERSION_2_30 (G_ENCODE_VERSION (2, 30))
+
+/**
+ * GLIB_VERSION_2_32:
+ *
+ * A macro that evaluates to the 2.32 version of GLib, in a format
+ * that can be used by the C pre-processor.
+ *
+ * Since: 2.32
+ */
+#define GLIB_VERSION_2_32 (G_ENCODE_VERSION (2, 32))
+
+/* evaluates to the current stable version; for development cycles,
+ * this means the next stable target
+ */
+#if (GLIB_MINOR_VERSION % 2)
+#define GLIB_VERSION_CUR_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION + 1))
+#else
+#define GLIB_VERSION_CUR_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION))
+#endif
+
+/* evaluates to the previous stable version */
+#if (GLIB_MINOR_VERSION % 2)
+#define GLIB_VERSION_PREV_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION - 1))
+#else
+#define GLIB_VERSION_PREV_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION - 2))
+#endif
+
+/**
+ * GLIB_VERSION_MIN_REQUIRED:
+ *
+ * A macro that should be defined by the user prior to including
+ * the glib.h header.
+ * The definition should be one of the predefined GLib version
+ * macros: %GLIB_VERSION_2_26, %GLIB_VERSION_2_28,...
+ *
+ * This macro defines the lower bound for the GLib API to use.
+ *
+ * If a function has been deprecated in a newer version of GLib,
+ * it is possible to use this symbol to avoid the compiler warnings
+ * without disabling warning for every deprecated function.
+ *
+ * Since: 2.32
+ */
+#ifndef GLIB_VERSION_MIN_REQUIRED
+# define GLIB_VERSION_MIN_REQUIRED (GLIB_VERSION_PREV_STABLE)
+#endif
+
+/**
+ * GLIB_VERSION_MAX_ALLOWED:
+ *
+ * A macro that should be defined by the user prior to including
+ * the glib.h header.
+ * The definition should be one of the predefined GLib version
+ * macros: %GLIB_VERSION_2_26, %GLIB_VERSION_2_28,...
+ *
+ * This macro defines the upper bound for the GLib API to use.
+ *
+ * If a function has been introduced in a newer version of GLib,
+ * it is possible to use this symbol to get compiler warnings when
+ * trying to use that function.
+ *
+ * Since: 2.32
+ */
+#ifndef GLIB_VERSION_MAX_ALLOWED
+# if GLIB_VERSION_MIN_REQUIRED > GLIB_VERSION_PREV_STABLE
+# define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_MIN_REQUIRED
+# else
+# define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_CUR_STABLE
+# endif
+#endif
+
+/* sanity checks */
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_MIN_REQUIRED
+#error "GLIB_VERSION_MAX_ALLOWED must be >= GLIB_VERSION_MIN_REQUIRED"
+#endif
+#if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_26
+#error "GLIB_VERSION_MIN_REQUIRED must be >= GLIB_VERSION_2_26"
+#endif
+
+/* XXX: Every new stable minor release should add a set of macros here */
+
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_26
+# define GLIB_DEPRECATED_IN_2_26 GLIB_DEPRECATED
+# define GLIB_DEPRECATED_IN_2_26_FOR(f) GLIB_DEPRECATED_FOR(f)
+#else
+# define GLIB_DEPRECATED_IN_2_26
+# define GLIB_DEPRECATED_IN_2_26_FOR(f)
+#endif
+
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_26
+# define GLIB_AVAILABLE_IN_2_26 GLIB_UNAVAILABLE(2, 26)
+#else
+# define GLIB_AVAILABLE_IN_2_26
+#endif
+
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_28
+# define GLIB_DEPRECATED_IN_2_28 GLIB_DEPRECATED
+# define GLIB_DEPRECATED_IN_2_28_FOR(f) GLIB_DEPRECATED_FOR(f)
+#else
+# define GLIB_DEPRECATED_IN_2_28
+# define GLIB_DEPRECATED_IN_2_28_FOR(f)
+#endif
+
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_28
+# define GLIB_AVAILABLE_IN_2_28 GLIB_UNAVAILABLE(2, 28)
+#else
+# define GLIB_AVAILABLE_IN_2_28
+#endif
+
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_30
+# define GLIB_DEPRECATED_IN_2_30 GLIB_DEPRECATED
+# define GLIB_DEPRECATED_IN_2_30_FOR(f) GLIB_DEPRECATED_FOR(f)
+#else
+# define GLIB_DEPRECATED_IN_2_30
+# define GLIB_DEPRECATED_IN_2_30_FOR(f)
+#endif
+
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_30
+# define GLIB_AVAILABLE_IN_2_30 GLIB_UNAVAILABLE(2, 30)
+#else
+# define GLIB_AVAILABLE_IN_2_30
+#endif
+
+#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_32
+# define GLIB_DEPRECATED_IN_2_32 GLIB_DEPRECATED
+# define GLIB_DEPRECATED_IN_2_32_FOR(f) GLIB_DEPRECATED_FOR(f)
+#else
+# define GLIB_DEPRECATED_IN_2_32
+# define GLIB_DEPRECATED_IN_2_32_FOR(f)
+#endif
+
+#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_32
+# define GLIB_AVAILABLE_IN_2_32 GLIB_UNAVAILABLE(2, 32)
+#else
+# define GLIB_AVAILABLE_IN_2_32
+#endif
+
+#endif /* __G_VERSION_MACROS_H__ */