aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Gnome-module.md49
-rw-r--r--docs/markdown/Release-notes-for-0.42.0.md7
-rw-r--r--mesonbuild/interpreter.py8
-rw-r--r--mesonbuild/interpreterbase.py14
-rw-r--r--mesonbuild/modules/gnome.py111
-rw-r--r--test cases/frameworks/7 gnome/gir/meson.build4
-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
10 files changed, 264 insertions, 10 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/interpreter.py b/mesonbuild/interpreter.py
index 91e4305..5fa0878 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1015,9 +1015,10 @@ class CompilerHolder(InterpreterObject):
return []
ModuleState = namedtuple('ModuleState', [
- 'build_to_src', 'subdir', 'environment', 'project_name', 'project_version',
- 'backend', 'compilers', 'targets', 'data', 'headers', 'man', 'global_args',
- 'project_args', 'build_machine', 'host_machine', 'target_machine'])
+ 'build_to_src', 'subdir', 'current_lineno', 'environment', 'project_name',
+ 'project_version', 'backend', 'compilers', 'targets', 'data', 'headers',
+ 'man', 'global_args', 'project_args', 'build_machine', 'host_machine',
+ 'target_machine'])
class ModuleHolder(InterpreterObject):
def __init__(self, modname, module, interpreter):
@@ -1040,6 +1041,7 @@ class ModuleHolder(InterpreterObject):
build_to_src=os.path.relpath(self.interpreter.environment.get_source_dir(),
self.interpreter.environment.get_build_dir()),
subdir=self.interpreter.subdir,
+ current_lineno=self.interpreter.current_lineno,
environment=self.interpreter.environment,
project_name=self.interpreter.build.project_name,
project_version=self.interpreter.build.dep_manifest[self.interpreter.active_projectname],
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index c075541..d2e2ab3 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -62,13 +62,19 @@ class permittedKwargs:
def __call__(self, f):
@wraps(f)
- def wrapped(s, node, args, kwargs):
+ def wrapped(s, node_or_state, args, kwargs):
+ if hasattr(s, 'subdir'):
+ subdir = s.subdir
+ lineno = s.current_lineno
+ elif hasattr(node_or_state, 'subdir'):
+ subdir = node_or_state.subdir
+ lineno = node_or_state.current_lineno
for k in kwargs:
if k not in self.permitted:
- fname = os.path.join(s.subdir, environment.build_filename)
+ fname = os.path.join(subdir, environment.build_filename)
mlog.warning('''Passed invalid keyword argument "%s" in %s line %d.
-This will become a hard error in the future.''' % (k, fname, s.current_lineno))
- return f(s, node, args, kwargs)
+This will become a hard error in the future.''' % (k, fname, lineno))
+ return f(s, node_or_state, args, kwargs)
return wrapped
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index dc6c25f..43c4881 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 = {
@@ -1138,7 +1239,11 @@ class GnomeModule(ExtensionModule):
build_dir = os.path.join(state.environment.get_build_dir(), state.subdir)
source_dir = os.path.join(state.environment.get_source_dir(), state.subdir)
pkg_cmd, vapi_depends, vapi_packages, vapi_includes = self._extract_vapi_packages(state, kwargs)
- cmd = [find_program('vapigen', 'Vaapi')]
+ target_name = 'generate_vapi({})'.format(library)
+ if 'VAPIGEN' in os.environ:
+ cmd = [find_program(os.environ['VAPIGEN'], target_name)]
+ else:
+ cmd = [find_program('vapigen', target_name)]
cmd += ['--quiet', '--library=' + library, '--directory=' + build_dir]
cmd += self._vapi_args_to_command('--vapidir=', 'vapi_dirs', kwargs)
cmd += self._vapi_args_to_command('--metadatadir=', 'metadata_dirs', kwargs)
diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build
index 0b26754..3598b66 100644
--- a/test cases/frameworks/7 gnome/gir/meson.build
+++ b/test cases/frameworks/7 gnome/gir/meson.build
@@ -30,6 +30,10 @@ gnome.generate_gir(
dependencies : [fake_dep, dep1_dep],
install : true,
build_by_default : true,
+ # Test that unknown kwargs do not crash the parser.
+ # Unknown kwargs will eventually become a hard error.
+ # Once that happens remove this.
+ unknown_kwarg : true,
)
test('gobject introspection/c', girexe)
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)