diff options
author | Tim-Philipp Müller <tim@centricular.com> | 2017-05-14 12:12:57 +0100 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-08-14 19:40:36 +0300 |
commit | 4e476c82f34d46e3fd1358b46220bff74826b3e4 (patch) | |
tree | e143c4abe78e0199a184756c7fe57019699fa40b | |
parent | c69a4aee1eb8f78770d59afec6dd12ebea9bfbd1 (diff) | |
download | meson-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.md | 49 | ||||
-rw-r--r-- | docs/markdown/Release-notes-for-0.42.0.md | 7 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 105 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/mkenums/main4.c | 35 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/mkenums/main5.c | 35 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/mkenums/meson-decls.h | 2 | ||||
-rw-r--r-- | test cases/frameworks/7 gnome/mkenums/meson.build | 9 |
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 (>ype_id)) { + GType new_type = g_@type@_register_static ("@EnumName@", values); + g_once_init_leave (>ype_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) |