Repository: mesonbuild/meson

Issue:
gdbus_codegen should return two different targets (.c, .h)
With glib<2.56.2, gdbus_codegen() returns twice the same custom_target, with two outputs.

A bug occurs when this return value is used for generate_gir(). The source list then contains twice the .c, and zero times the .h…

Maybe gdbus_codegen() should return two custom_targets, with each one output (once the .c, once the .h).

EDIT : Actually, after reading the source of generate_gir, I suppose the bug is there.

```
                    gir_filelist.write(os.path.join(state.environment.get_build_dir(),
                                                    state.backend.get_target_dir(s),
                                                    s.get_outputs()[0]) + '\n')
```
Why only `s.get_outputs()[0]` ?



Discussion:
Yeah, that `s.get_outputs()[0]` is probably wrong. It should loop over all the outputs and write them all.

Resolving patch:
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -920,51 +920,19 @@ def gdbus_codegen(self, state, args, kwargs):
                 raise MesonException('Annotations must be made up of 3 strings for ELEMENT, KEY, and VALUE')
             cmd += ['--annotate'] + annotation
 
+        targets = []
+        install_header = kwargs.get('install_header', False)
+        install_dir = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir'))
+
+        output = namebase + '.c'
         # Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2)
         # Fixed in https://gitlab.gnome.org/GNOME/glib/commit/cd1f82d8fc741a2203582c12cc21b4dacf7e1872 (2.56.2)
         if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.56.2'):
-            targets = []
-            install_header = kwargs.get('install_header', False)
-            install_dir = kwargs.get('install_dir', state.environment.coredata.get_builtin_option('includedir'))
-
-            output = namebase + '.c'
             custom_kwargs = {'input': xml_files,
                              'output': output,
                              'command': cmd + ['--body', '--output', '@OUTPUT@', '@INPUT@'],
                              'build_by_default': build_by_default
                              }
-            targets.append(build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs))
-
-            output = namebase + '.h'
-            custom_kwargs = {'input': xml_files,
-                             'output': output,
-                             'command': cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@'],
-                             'build_by_default': build_by_default,
-                             'install': install_header,
-                             'install_dir': install_dir
-                             }
-            targets.append(build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs))
-
-            if 'docbook' in kwargs:
-                docbook = kwargs['docbook']
-                if not isinstance(docbook, str):
-                    raise MesonException('docbook value must be a string.')
-
-                docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
-
-                # The docbook output is always ${docbook}-${name_of_xml_file}
-                output = namebase + '-docbook'
-                outputs = []
-                for f in xml_files:
-                    outputs.append('{}-{}'.format(docbook, f))
-                custom_kwargs = {'input': xml_files,
-                                 'output': outputs,
-                                 'command': docbook_cmd,
-                                 'build_by_default': build_by_default
-                                 }
-                targets.append(build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs))
-
-            objects = targets
         else:
             if 'docbook' in kwargs:
                 docbook = kwargs['docbook']
@@ -979,24 +947,69 @@ def gdbus_codegen(self, state, args, kwargs):
             else:
                 self._print_gdbus_warning()
                 cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@']
-            outputs = [namebase + '.c', namebase + '.h']
-            install = kwargs.get('install_header', False)
+
+            custom_kwargs = {'input': xml_files,
+                             'output': output,
+                             'command': cmd,
+                             'build_by_default': build_by_default
+                             }
+
+        cfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+        targets.append(cfile_custom_target)
+
+        output = namebase + '.h'
+        if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.56.2'):
             custom_kwargs = {'input': xml_files,
-                             'output': outputs,
+                             'output': output,
+                             'command': cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@'],
+                             'build_by_default': build_by_default,
+                             'install': install_header,
+                             'install_dir': install_dir
+                             }
+        else:
+            custom_kwargs = {'input': xml_files,
+                             'output': output,
                              'command': cmd,
                              'build_by_default': build_by_default,
-                             'install': install,
+                             'install': install_header,
+                             'install_dir': install_dir,
+                             'depends': cfile_custom_target
                              }
-            if install and 'install_dir' in kwargs:
-                custom_kwargs['install_dir'] = [False, kwargs['install_dir']]
-            ct = build.CustomTarget(target_name, state.subdir, state.subproject, custom_kwargs)
-            # Ensure that the same number (and order) of arguments are returned
-            # regardless of the gdbus-codegen (glib) version being used
-            targets = [ct, ct]
-            if 'docbook' in kwargs:
-                targets.append(ct)
-            objects = [ct]
-        return ModuleReturnValue(targets, objects)
+
+        hfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+        targets.append(hfile_custom_target)
+
+        if 'docbook' in kwargs:
+            docbook = kwargs['docbook']
+            if not isinstance(docbook, str):
+                raise MesonException('docbook value must be a string.')
+
+            docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
+
+            # The docbook output is always ${docbook}-${name_of_xml_file}
+            output = namebase + '-docbook'
+            outputs = []
+            for f in xml_files:
+                outputs.append('{}-{}'.format(docbook, f))
+
+            if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.56.2'):
+                custom_kwargs = {'input': xml_files,
+                                 'output': outputs,
+                                 'command': docbook_cmd,
+                                 'build_by_default': build_by_default
+                                 }
+            else:
+                custom_kwargs = {'input': xml_files,
+                                 'output': outputs,
+                                 'command': cmd,
+                                 'build_by_default': build_by_default,
+                                 'depends': cfile_custom_target
+                                 }
+
+            docbook_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+            targets.append(docbook_custom_target)
+
+        return ModuleReturnValue(targets, targets)
 
     @permittedKwargs({'sources', 'c_template', 'h_template', 'install_header', 'install_dir',
                       'comments', 'identifier_prefix', 'symbol_prefix', 'eprod', 'vprod',


Test patch:
diff --git a/test cases/frameworks/7 gnome/gdbus/meson.build b/test cases/frameworks/7 gnome/gdbus/meson.build
--- a/test cases/frameworks/7 gnome/gdbus/meson.build	
+++ b/test cases/frameworks/7 gnome/gdbus/meson.build	
@@ -6,6 +6,8 @@ gdbus_src = gnome.gdbus_codegen('generated-gdbus-no-docbook', 'com.example.Sampl
   ],
 )
 assert(gdbus_src.length() == 2, 'expected 2 targets')
+assert(gdbus_src[0].full_path().endswith('.c'), 'expected 1 c source file')
+assert(gdbus_src[1].full_path().endswith('.h'), 'expected 1 c header file')
 
 gdbus_src = gnome.gdbus_codegen('generated-gdbus',
   sources : 'com.example.Sample.xml',
@@ -19,6 +21,8 @@ gdbus_src = gnome.gdbus_codegen('generated-gdbus',
   install_dir : get_option('includedir')
 )
 assert(gdbus_src.length() == 3, 'expected 3 targets')
+assert(gdbus_src[0].full_path().endswith('.c'), 'expected 1 c source file')
+assert(gdbus_src[1].full_path().endswith('.h'), 'expected 1 c header file')
 
 if not pretend_glib_old and glib.version().version_compare('>=2.51.3')
   includes = []