diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml
index 9d62c3757..9687681fd 100644
--- a/docs/reference/gio/gdbus-codegen.xml
+++ b/docs/reference/gio/gdbus-codegen.xml
@@ -51,6 +51,7 @@
VERSION
+ VERSIONFILEFILE
@@ -460,6 +461,27 @@ gdbus-codegen --c-namespace MyApp \
+
+ VERSION
+
+
+ Specifies the maximum version of GLib which the code generated by
+ gdbus-codegen can depend on. This may be used to
+ ensure that code generated by gdbus-codegen is
+ compilable with specific older versions of GLib that your software has
+ to support.
+
+
+ The version number must be of the form
+ MAJOR.MINOR.MICRO,
+ where all parts are integers. MINOR and
+ MICRO are optional. The version number must
+ be greater than or equal to that passed to .
+ It defaults to the version of GLib which provides this gdbus-codegen.
+
+
+
+
diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py
index 60e1ae042..c938640e7 100644
--- a/gio/gdbus-2.0/codegen/codegen_main.py
+++ b/gio/gdbus-2.0/codegen/codegen_main.py
@@ -169,6 +169,8 @@ def codegen_main():
help='Add annotation (may be used several times)')
arg_parser.add_argument('--glib-min-required', metavar='VERSION',
help='Minimum version of GLib to be supported by the outputted code (default: 2.30)')
+ arg_parser.add_argument('--glib-max-allowed', metavar='VERSION',
+ help='Maximum version of GLib to be used by the outputted code (default: current GLib version)')
group = arg_parser.add_mutually_exclusive_group()
group.add_argument('--generate-c-code', metavar='OUTFILES',
@@ -256,6 +258,28 @@ def codegen_main():
else:
glib_min_required = (2, 30)
+ # And the maximum GLib version.
+ if args.glib_max_allowed:
+ try:
+ parts = args.glib_max_allowed.split('.', 3)
+ glib_max_allowed = (int(parts[0]),
+ int(parts[1] if len(parts) > 1 else 0))
+ # Ignore micro component, but still validate it:
+ _ = int(parts[2] if len(parts) > 2 else 0)
+ except (ValueError, IndexError):
+ print_error('Unrecognized --glib-max-allowed string ‘{}’'.format(
+ args.glib_max_allowed))
+ else:
+ glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION)
+
+ # Round --glib-max-allowed up to the next stable release.
+ glib_max_allowed = \
+ (glib_max_allowed[0], glib_max_allowed[1] + (glib_max_allowed[1] % 2))
+
+ if glib_max_allowed < glib_min_required:
+ print_error('Invalid versions: --glib-min-required ({}) must be '
+ 'less than or equal to --glib-max-allowed ({})'.format(glib_min_required, glib_max_allowed))
+
glib_min_required_is_2_64 = (glib_min_required[0] > 2 or
(glib_min_required[0] == 2 and
glib_min_required[1] >= 64))
diff --git a/gio/gdbus-2.0/codegen/config.py.in b/gio/gdbus-2.0/codegen/config.py.in
index a91178a95..4e6df5a09 100644
--- a/gio/gdbus-2.0/codegen/config.py.in
+++ b/gio/gdbus-2.0/codegen/config.py.in
@@ -20,3 +20,5 @@
# Author: David Zeuthen
VERSION = "@VERSION@"
+MAJOR_VERSION = @MAJOR_VERSION@
+MINOR_VERSION = @MINOR_VERSION@
diff --git a/gio/gdbus-2.0/codegen/meson.build b/gio/gdbus-2.0/codegen/meson.build
index 121e9e6bb..ff5edb977 100644
--- a/gio/gdbus-2.0/codegen/meson.build
+++ b/gio/gdbus-2.0/codegen/meson.build
@@ -10,6 +10,8 @@ gdbus_codegen_files = [
gdbus_codegen_conf = configuration_data()
gdbus_codegen_conf.set('VERSION', glib_version)
+gdbus_codegen_conf.set('MAJOR_VERSION', major_version)
+gdbus_codegen_conf.set('MINOR_VERSION', minor_version)
gdbus_codegen_conf.set('PYTHON', python_name)
gdbus_codegen_conf.set('DATADIR', glib_datadir)
diff --git a/gio/tests/codegen.py b/gio/tests/codegen.py
index bbb51117d..51de0ede4 100644
--- a/gio/tests/codegen.py
+++ b/gio/tests/codegen.py
@@ -384,7 +384,8 @@ G_END_DECLS
result = self.runCodegenWithInterface('',
'--output', '/dev/stdout',
'--header',
- '--glib-min-required', '3')
+ '--glib-min-required', '3',
+ '--glib-max-allowed', '3.2')
self.assertEqual('', result.err)
self.assertNotEqual('', result.out.strip())
@@ -397,6 +398,55 @@ G_END_DECLS
self.assertEqual('', result.err)
self.assertNotEqual('', result.out.strip())
+ def test_glib_max_allowed_too_low(self):
+ """Test running with a --glib-max-allowed which is too low (and hence
+ probably a typo)."""
+ with self.assertRaises(subprocess.CalledProcessError):
+ self.runCodegenWithInterface('',
+ '--output', '/dev/stdout',
+ '--body',
+ '--glib-max-allowed', '2.6')
+
+ def test_glib_max_allowed_major_only(self):
+ """Test running with a --glib-max-allowed which contains only a major version."""
+ result = self.runCodegenWithInterface('',
+ '--output', '/dev/stdout',
+ '--header',
+ '--glib-max-allowed', '3')
+ self.assertEqual('', result.err)
+ self.assertNotEqual('', result.out.strip())
+
+ def test_glib_max_allowed_with_micro(self):
+ """Test running with a --glib-max-allowed which contains a micro version."""
+ result = self.runCodegenWithInterface('',
+ '--output', '/dev/stdout',
+ '--header',
+ '--glib-max-allowed', '2.46.2')
+ self.assertEqual('', result.err)
+ self.assertNotEqual('', result.out.strip())
+
+ def test_glib_max_allowed_unstable(self):
+ """Test running with a --glib-max-allowed which is unstable. It should
+ be rounded up to the next stable version number, and hence should not
+ end up less than --glib-min-required."""
+ result = self.runCodegenWithInterface('',
+ '--output', '/dev/stdout',
+ '--header',
+ '--glib-max-allowed', '2.63',
+ '--glib-min-required', '2.64')
+ self.assertEqual('', result.err)
+ self.assertNotEqual('', result.out.strip())
+
+ def test_glib_max_allowed_less_than_min_required(self):
+ """Test running with a --glib-max-allowed which is less than
+ --glib-min-required."""
+ with self.assertRaises(subprocess.CalledProcessError):
+ self.runCodegenWithInterface('',
+ '--output', '/dev/stdout',
+ '--body',
+ '--glib-max-allowed', '2.62',
+ '--glib-min-required', '2.64')
+
def test_unix_fd_types_and_annotations(self):
"""Test an interface with `h` arguments, no annotation, and GLib < 2.64.