aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2017-05-14 12:12:57 +0100
committerJussi Pakkanen <jpakkane@gmail.com>2017-08-14 19:40:36 +0300
commit4e476c82f34d46e3fd1358b46220bff74826b3e4 (patch)
treee143c4abe78e0199a184756c7fe57019699fa40b
parentc69a4aee1eb8f78770d59afec6dd12ebea9bfbd1 (diff)
downloadmeson-4e476c82f34d46e3fd1358b46220bff74826b3e4.zip
meson-4e476c82f34d46e3fd1358b46220bff74826b3e4.tar.gz
meson-4e476c82f34d46e3fd1358b46220bff74826b3e4.tar.bz2
gnome: add mkenums_simple()
99% of all mkenums uses in C libraries use the same basic template, so add a mkenums_simple() function that takes care of everything for us based on that template. Features: - optional function declaration decorator such as GLIB_AVAILABLE - optional extra header prefix (e.g. for include needed for decorator) - optional extra body prefix (e.g. for additional includes) - optional function name prefix (e.g. to add leading underscores) Fixes issue #1384
-rw-r--r--docs/markdown/Gnome-module.md49
-rw-r--r--docs/markdown/Release-notes-for-0.42.0.md7
-rw-r--r--mesonbuild/modules/gnome.py105
-rw-r--r--test cases/frameworks/7 gnome/mkenums/main4.c35
-rw-r--r--test cases/frameworks/7 gnome/mkenums/main5.c35
-rw-r--r--test cases/frameworks/7 gnome/mkenums/meson-decls.h2
-rw-r--r--test cases/frameworks/7 gnome/mkenums/meson.build9
7 files changed, 240 insertions, 2 deletions
diff --git a/docs/markdown/Gnome-module.md b/docs/markdown/Gnome-module.md
index 038f1ea..0e24bb0 100644
--- a/docs/markdown/Gnome-module.md
+++ b/docs/markdown/Gnome-module.md
@@ -72,6 +72,12 @@ Returns an array of two elements which are: `[c_source, header_file]`
Generates enum files for GObject using the `glib-mkenums` tool. The first argument is the base name of the output files.
+This method is essentially a wrapper around the `glib-mkenums` tool's command line API. It is the most featureful method for enum creation.
+
+Typically you either provide template files or you specify the various template sections manually as strings.
+
+Most libraries and applications will be using the same standard template with only minor tweaks, in which case the `gnome.mkenums_simple()` convenience method can be used instead.
+
Note that if you `#include` the generated header in any of the sources for a build target, you must add the generated header to the build target's list of sources to codify the dependency. This is true for all generated sources, not just `mkenums`.
* `sources`: the list of sources to make enums with
@@ -93,6 +99,49 @@ Note that if you `#include` the generated header in any of the sources for a bui
Returns an array of two elements which are: `[c_source, header_file]`
+### gnome.mkenums_simple()
+
+Generates enum `.c` and `.h` files for GObject using the `glib-mkenums` tool
+with the standard template used by most GObject-based C libraries. The first
+argument is the base name of the output files.
+
+Note that if you `#include` the generated header in any of the sources for a
+build target, you must add the generated header to the build target's list of
+sources to codify the dependency. This is true for all generated sources, not
+just `mkenums_simple`.
+
+* `sources`: the list of sources to make enums with
+* `install_header`: if true, install the generated header
+* `install_dir`: directory to install the header
+* `identifier_prefix`: prefix to use for the identifiers
+* `symbol_prefix`: prefix to use for the symbols
+* `header_prefix`: additional prefix at the top of the header file, e.g. for extra includes (which may be needed if you specify a decorator for the function declarations)
+* `decorator`: optional decorator for the function declarations, e.g. `GTK_AVAILABLE` or `GST_EXPORT`
+* `function_prefix`: additional prefix for function names, e.g. in case you want to add a leading underscore to functions used only internally
+* `body_prefix`: additional prefix at the top of the body file, e.g. for extra includes
+
+Example:
+
+```meson
+gnome = import('gnome')
+
+my_headers = ['myheader1.h', 'myheader2.h']
+my_sources = ['mysource1.c', 'mysource2.c']
+
+# will generate myenums.c and myenums.h based on enums in myheader1.h and myheader2.h
+enums = gnome.mkenums_simple('myenums', sources : my_headers)
+
+mylib = library('my', my_sources, enums,
+ include_directories: my_incs,
+ dependencies: my_deps,
+ c_args: my_cargs,
+ install: true)
+```
+
+*Added 0.42.0*
+
+Returns an array of two elements which are: `[c_source, header_file]`
+
### gnome.compile_schemas()
When called, this method will compile the gschemas in the current directory. Note that this is not
diff --git a/docs/markdown/Release-notes-for-0.42.0.md b/docs/markdown/Release-notes-for-0.42.0.md
index 1ed74dc..3ba84eb 100644
--- a/docs/markdown/Release-notes-for-0.42.0.md
+++ b/docs/markdown/Release-notes-for-0.42.0.md
@@ -140,3 +140,10 @@ using the `pcap-config` tool. It is used like any other dependency:
```meson
pcap_dep = dependency('pcap', version : '>=1.0')
```
+
+## GNOME module mkenums_simple() addition
+
+Most libraries and applications use the same standard templates for
+glib-mkenums. There is now a new `mkenums_simple()` convenience method
+that passes those default templates to glib-mkenums and allows some tweaks
+such as optional function decorators or leading underscores.
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index dc6c25f..5f9847e 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -13,7 +13,7 @@
# limitations under the License.
'''This module provides helper functions for Gnome/GLib related
-functionality such as gobject-introspection and gresources.'''
+functionality such as gobject-introspection, gresources and gtk-doc'''
from .. import build
import os
@@ -32,7 +32,6 @@ from . import find_program, get_include_args
from . import ExtensionModule
from . import noKwargs, permittedKwargs
-
# gresource compilation is broken due to the way
# the resource compiler and Ninja clash about it
#
@@ -955,6 +954,108 @@ class GnomeModule(ExtensionModule):
else:
return ModuleReturnValue(targets, targets)
+ def mkenums_simple(self, state, args, kwargs):
+ hdr_filename = args[0] + '.h'
+ body_filename = args[0] + '.c'
+
+ # not really needed, just for sanity checking
+ forbidden_kwargs = ['c_template', 'h_template', 'eprod', 'fhead',
+ 'fprod', 'ftail', 'vhead', 'vtail', 'comments']
+ for arg in forbidden_kwargs:
+ if arg in kwargs:
+ raise MesonException('mkenums_simple() does not take a %s keyword argument' % (arg, ))
+
+ # kwargs to pass as-is from mkenums_simple() to mkenums()
+ shared_kwargs = ['sources', 'install_header', 'install_dir',
+ 'identifier_prefix', 'symbol_prefix']
+ mkenums_kwargs = {}
+ for arg in shared_kwargs:
+ if arg in kwargs:
+ mkenums_kwargs[arg] = kwargs[arg]
+
+ # .c file generation
+ c_file_kwargs = copy.deepcopy(mkenums_kwargs)
+ if 'sources' not in kwargs:
+ raise MesonException('Missing keyword argument "sources".')
+ sources = kwargs['sources']
+ if isinstance(sources, str):
+ sources = [sources]
+ elif not isinstance(sources, list):
+ raise MesonException(
+ 'Sources keyword argument must be a string or array.')
+
+ header_prefix = kwargs.get('header_prefix', '')
+ decl_decorator = kwargs.get('decorator', '')
+ func_prefix = kwargs.get('function_prefix', '')
+ body_prefix = kwargs.get('body_prefix', '')
+
+ # Maybe we should write our own template files into the build dir
+ # instead, but that seems like much more work, nice as it would be.
+ fhead = ''
+ if body_prefix != '':
+ fhead += '%s\n' % body_prefix
+ fhead += '#include "%s"\n' % hdr_filename
+ for hdr in sources:
+ fhead += '#include "%s"\n' % hdr
+ fhead += '''
+#define C_ENUM(v) ((gint) v)
+#define C_FLAGS(v) ((guint) v)
+'''
+ c_file_kwargs['fhead'] = fhead
+
+ c_file_kwargs['fprod'] = '''
+/* enumerations from "@basename@" */
+'''
+
+ c_file_kwargs['vhead'] = '''
+GType
+%s@enum_name@_get_type (void)
+{
+ static volatile gsize gtype_id = 0;
+ static const G@Type@Value values[] = {''' % func_prefix
+
+ c_file_kwargs['vprod'] = ' { C_@TYPE@(@VALUENAME@), "@VALUENAME@", "@valuenick@" },'
+
+ c_file_kwargs['vtail'] = ''' { 0, NULL, NULL }
+ };
+ if (g_once_init_enter (&gtype_id)) {
+ GType new_type = g_@type@_register_static ("@EnumName@", values);
+ g_once_init_leave (&gtype_id, new_type);
+ }
+ return (GType) gtype_id;
+}'''
+
+ rv = self.mkenums(state, [body_filename], c_file_kwargs)
+ c_file = rv.return_value
+
+ # .h file generation
+ h_file_kwargs = copy.deepcopy(mkenums_kwargs)
+
+ h_file_kwargs['fhead'] = '''#pragma once
+
+#include <glib-object.h>
+{}
+
+G_BEGIN_DECLS
+'''.format(header_prefix)
+
+ h_file_kwargs['fprod'] = '''
+/* enumerations from "@basename@" */
+'''
+
+ h_file_kwargs['vhead'] = '''
+{}
+GType {}@enum_name@_get_type (void);
+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ ({}@enum_name@_get_type())'''.format(decl_decorator, func_prefix, func_prefix)
+
+ h_file_kwargs['ftail'] = '''
+G_END_DECLS'''
+
+ rv = self.mkenums(state, [hdr_filename], h_file_kwargs)
+ h_file = rv.return_value
+
+ return ModuleReturnValue([c_file, h_file], [c_file, h_file])
+
@staticmethod
def _make_mkenum_custom_target(state, sources, output, cmd, kwargs):
custom_kwargs = {
diff --git a/test cases/frameworks/7 gnome/mkenums/main4.c b/test cases/frameworks/7 gnome/mkenums/main4.c
new file mode 100644
index 0000000..3df4dd8
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/main4.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib-object.h>
+#include "enums4.h"
+#include "meson-sample.h"
+
+int main(int argc, char **argv) {
+ GEnumClass *xenum = g_type_class_ref(MESON_TYPE_THE_XENUM);
+ GFlagsClass *flags_enum = g_type_class_ref(MESON_TYPE_THE_FLAGS_ENUM);
+ if (g_enum_get_value_by_name(xenum, "MESON_THE_XVALUE")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by name failed.\n");
+ return 1;
+ }
+ if (g_enum_get_value_by_nick(xenum, "the-xvalue")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by nick failed.\n");
+ return 2;
+ }
+ if (g_flags_get_value_by_name(flags_enum, "MESON_THE_FIRST_VALUE")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by name failed.\n");
+ return 3;
+ }
+ if (g_flags_get_value_by_nick(flags_enum, "the-first-value")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by nick failed.\n");
+ return 4;
+ }
+
+ /* Make sure that funcs are generated with leading underscore as requested */
+ if (!_meson_the_xenum_get_type())
+ g_error ("Bad!");
+
+ g_type_class_unref(xenum);
+ g_type_class_unref(flags_enum);
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/mkenums/main5.c b/test cases/frameworks/7 gnome/mkenums/main5.c
new file mode 100644
index 0000000..ed1ccfd
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/main5.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib-object.h>
+#include "enums5.h"
+#include "meson-sample.h"
+
+int main(int argc, char **argv) {
+ GEnumClass *xenum = g_type_class_ref(MESON_TYPE_THE_XENUM);
+ GFlagsClass *flags_enum = g_type_class_ref(MESON_TYPE_THE_FLAGS_ENUM);
+ if (g_enum_get_value_by_name(xenum, "MESON_THE_XVALUE")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by name failed.\n");
+ return 1;
+ }
+ if (g_enum_get_value_by_nick(xenum, "the-xvalue")->value != MESON_THE_XVALUE) {
+ fprintf(stderr, "Get MESON_THE_XVALUE by nick failed.\n");
+ return 2;
+ }
+ if (g_flags_get_value_by_name(flags_enum, "MESON_THE_FIRST_VALUE")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by name failed.\n");
+ return 3;
+ }
+ if (g_flags_get_value_by_nick(flags_enum, "the-first-value")->value != MESON_THE_FIRST_VALUE) {
+ fprintf(stderr, "Get MESON_THE_FIRST_VALUE by nick failed.\n");
+ return 4;
+ }
+
+ /* Make sure that funcs do not have any extra prefix */
+ if (!meson_the_xenum_get_type())
+ g_error ("Bad!");
+
+ g_type_class_unref(xenum);
+ g_type_class_unref(flags_enum);
+ fprintf(stderr, "All ok.\n");
+ return 0;
+}
diff --git a/test cases/frameworks/7 gnome/mkenums/meson-decls.h b/test cases/frameworks/7 gnome/mkenums/meson-decls.h
new file mode 100644
index 0000000..ba94eb9
--- /dev/null
+++ b/test cases/frameworks/7 gnome/mkenums/meson-decls.h
@@ -0,0 +1,2 @@
+#pragma once
+#define MESON_EXPORT extern
diff --git a/test cases/frameworks/7 gnome/mkenums/meson.build b/test cases/frameworks/7 gnome/mkenums/meson.build
index e01e9eb..9963455 100644
--- a/test cases/frameworks/7 gnome/mkenums/meson.build
+++ b/test cases/frameworks/7 gnome/mkenums/meson.build
@@ -117,3 +117,12 @@ main = configure_file(
enumexe3 = executable('enumprog3', main, enums_c3, enums_h3,
dependencies : gobj)
test('enum test 3', enumexe3)
+
+enums4 = gnome.mkenums_simple('enums4', sources : 'meson-sample.h',
+ function_prefix : '_')
+enumexe4 = executable('enumprog4', 'main4.c', enums4, dependencies : gobj)
+
+enums5 = gnome.mkenums_simple('enums5', sources : 'meson-sample.h',
+ decorator : 'MESON_EXPORT',
+ header_prefix : '#include "meson-decls.h"')
+enumexe5 = executable('enumprog5', main, enums5, dependencies : gobj)