aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter.py6
-rw-r--r--mesonbuild/modules/gnome.py147
-rw-r--r--test cases/vala/12 generated vapi/installed_files.txt7
-rw-r--r--test cases/vala/12 generated vapi/libbar/bar.c12
-rw-r--r--test cases/vala/12 generated vapi/libbar/bar.h5
-rw-r--r--test cases/vala/12 generated vapi/libbar/meson.build33
-rw-r--r--test cases/vala/12 generated vapi/libfoo/foo.c11
-rw-r--r--test cases/vala/12 generated vapi/libfoo/foo.h5
-rw-r--r--test cases/vala/12 generated vapi/libfoo/meson.build36
-rw-r--r--test cases/vala/12 generated vapi/main.vala9
-rw-r--r--test cases/vala/12 generated vapi/meson.build13
11 files changed, 284 insertions, 0 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 44b5748..44551fc 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -990,6 +990,7 @@ class ModuleHolder(InterpreterObject):
state.project_version = self.interpreter.build.dep_manifest[self.interpreter.active_projectname]
state.compilers = self.interpreter.build.compilers
state.targets = self.interpreter.build.targets
+ state.data = self.interpreter.build.data
state.headers = self.interpreter.build.get_headers()
state.man = self.interpreter.build.get_man()
state.global_args = self.interpreter.build.global_args
@@ -1269,6 +1270,11 @@ class Interpreter():
self.build.install_scripts.append(v)
elif isinstance(v, build.Data):
self.build.data.append(v)
+ elif isinstance(v, dependencies.InternalDependency):
+ # FIXME: This is special cased and not ideal:
+ # The first source is our new VapiTarget, the rest are deps
+ self.module_method_callback(v.sources[0])
+ outvalues.append(InternalDependencyHolder(v))
else:
print(v)
raise InterpreterException('Module returned a value of unknown type.')
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index ea9b15a..6b44af1 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -728,6 +728,149 @@ class GnomeModule:
return [body, header]
+ @staticmethod
+ def _vapi_args_to_command(prefix, variable, kwargs, accept_vapi=False):
+ arg_list = kwargs.get(variable)
+ if not arg_list:
+ return []
+ ret = []
+ if not isinstance(arg_list, list):
+ arg_list = [arg_list]
+ for arg in arg_list:
+ if not isinstance(arg, str):
+ types = 'strings' + ' or InternalDependencys' if accept_vapi else ''
+ raise MesonException('All {} must be {}'.format(variable, types))
+ ret.append(prefix + arg)
+ return ret
+
+ def _extract_vapi_packages(self, state, kwargs):
+ '''
+ Packages are special because we need to:
+ - Get a list of packages for the .deps file
+ - Get a list of depends for any VapiTargets
+ - Get package name from VapiTargets
+ - Add include dirs for any VapiTargets
+ '''
+ arg_list = kwargs.get('packages')
+ if not arg_list:
+ return [], [], [], []
+ if not isinstance(arg_list, list):
+ arg_list = [arg_list]
+
+ vapi_depends = []
+ vapi_packages = []
+ vapi_includes = []
+ ret = []
+ remaining_args = []
+ for arg in arg_list:
+ if hasattr(arg, 'held_object'):
+ arg = arg.held_object
+ if isinstance(arg, dependencies.InternalDependency):
+ targets = [t for t in arg.sources if isinstance(t, VapiTarget)]
+ for target in targets:
+ srcdir = os.path.join(state.environment.get_source_dir(),
+ target.get_subdir())
+ outdir = os.path.join(state.environment.get_build_dir(),
+ target.get_subdir())
+ outfile = target.output[0][:-5] # Strip .vapi
+ ret.append('--vapidir=' + outdir)
+ ret.append('--girdir=' + outdir)
+ ret.append('--pkg=' + outfile)
+ vapi_depends.append(target)
+ vapi_packages.append(outfile)
+ vapi_includes.append(srcdir)
+ else:
+ vapi_packages.append(arg)
+ remaining_args.append(arg)
+
+ kwargs['packages'] = remaining_args
+ vapi_args = ret + self._vapi_args_to_command('--pkg=', 'packages', kwargs, accept_vapi=True)
+ return vapi_args, vapi_depends, vapi_packages, vapi_includes
+
+ def _generate_deps(self, state, library, packages, indir):
+ outdir = state.environment.scratch_dir
+ fname = os.path.join(outdir, library + '.deps')
+ with open(fname, 'w') as ofile:
+ for package in packages:
+ ofile.write(package + '\n')
+ return build.Data(False, outdir, [fname], indir)
+
+ def _get_vapi_link_with(self, target):
+ link_with = []
+ for dep in target.get_target_dependencies():
+ if isinstance(dep, build.SharedLibrary):
+ link_with.append(dep)
+ elif isinstance(dep, GirTarget):
+ link_with += self._get_vapi_link_with(dep)
+ return link_with
+
+ def generate_vapi(self, state, args, kwargs):
+ if len(args) != 1:
+ raise MesonException('The library name is required')
+
+ if not isinstance(args[0], str):
+ raise MesonException('The first argument must be the name of the library')
+
+ library = args[0]
+ 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 = ['vapigen', '--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)
+ cmd += self._vapi_args_to_command('--girdir=', 'gir_dirs', kwargs)
+ cmd += pkg_cmd
+ cmd += ['--metadatadir=' + source_dir]
+
+ inputs = kwargs.get('sources')
+ if not inputs:
+ raise MesonException('sources are required to generate the vapi file')
+
+ if not isinstance(inputs, list):
+ inputs = [inputs]
+
+ link_with = []
+ for i in inputs:
+ if isinstance(i, str):
+ cmd.append(os.path.join(source_dir, i))
+ elif hasattr(i, 'held_object') \
+ and isinstance(i.held_object, GirTarget):
+ link_with += self._get_vapi_link_with(i.held_object)
+ subdir = os.path.join(state.environment.get_build_dir(),
+ i.held_object.get_subdir())
+ gir_file = os.path.join(subdir, i.held_object.output[0])
+ cmd.append(gir_file)
+ else:
+ raise MesonException('Input must be a str or GirTarget')
+
+ vapi_output = library + '.vapi'
+ custom_kwargs = {
+ 'command': cmd,
+ 'input': inputs,
+ 'output': vapi_output,
+ 'depends': vapi_depends,
+ }
+ install_dir = kwargs.get('install_dir',
+ os.path.join(state.environment.coredata.get_builtin_option('datadir'),
+ 'vala', 'vapi'))
+ if kwargs.get('install'):
+ custom_kwargs['install'] = kwargs['install']
+ custom_kwargs['install_dir'] = install_dir
+
+ # We shouldn't need this locally but we install it
+ deps_target = self._generate_deps(state, library, vapi_packages, install_dir)
+ state.data.append(deps_target)
+ vapi_target = VapiTarget(vapi_output, state.subdir, custom_kwargs)
+
+ # So to try our best to get this to just work we need:
+ # - link with with the correct library
+ # - include the vapi and dependent vapi files in sources
+ # - add relevant directories to include dirs
+ includes = [build.IncludeDirs(state.subdir, ['.'] + vapi_includes, False)]
+ sources = [vapi_target] + vapi_depends
+ return dependencies.InternalDependency(
+ None, includes, [], [], link_with, sources, []
+ )
def initialize():
return GnomeModule()
@@ -739,3 +882,7 @@ class GirTarget(build.CustomTarget):
class TypelibTarget(build.CustomTarget):
def __init__(self, name, subdir, kwargs):
super().__init__(name, subdir, kwargs)
+
+class VapiTarget(build.CustomTarget):
+ def __init__(self, name, subdir, kwargs):
+ super().__init__(name, subdir, kwargs)
diff --git a/test cases/vala/12 generated vapi/installed_files.txt b/test cases/vala/12 generated vapi/installed_files.txt
new file mode 100644
index 0000000..5993d01
--- /dev/null
+++ b/test cases/vala/12 generated vapi/installed_files.txt
@@ -0,0 +1,7 @@
+usr/bin/vapigen-test
+usr/lib/libfoo.so
+usr/lib/libbar.so
+usr/share/vala/vapi/foo-1.0.vapi
+usr/share/vala/vapi/foo-1.0.deps
+usr/share/vala/vapi/bar-1.0.vapi
+usr/share/vala/vapi/bar-1.0.deps
diff --git a/test cases/vala/12 generated vapi/libbar/bar.c b/test cases/vala/12 generated vapi/libbar/bar.c
new file mode 100644
index 0000000..f0f5cb8
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libbar/bar.c
@@ -0,0 +1,12 @@
+#include "bar.h"
+#include "foo.h"
+
+/**
+ * bar_return_success:
+ *
+ * Returns 0
+ */
+int bar_return_success(void)
+{
+ return foo_return_success();
+}
diff --git a/test cases/vala/12 generated vapi/libbar/bar.h b/test cases/vala/12 generated vapi/libbar/bar.h
new file mode 100644
index 0000000..165b104
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libbar/bar.h
@@ -0,0 +1,5 @@
+#include <glib-object.h>
+
+#pragma once
+
+int bar_return_success(void);
diff --git a/test cases/vala/12 generated vapi/libbar/meson.build b/test cases/vala/12 generated vapi/libbar/meson.build
new file mode 100644
index 0000000..6482504
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libbar/meson.build
@@ -0,0 +1,33 @@
+libbar_sources = [
+ 'bar.c',
+ 'bar.h',
+]
+
+libbar_deps = [
+ dependency('gobject-2.0'),
+ libfoo_dep,
+]
+
+libbar = shared_library('bar', libbar_sources,
+ dependencies: libbar_deps,
+ install: true,
+)
+
+libbar_api_ver = '1.0'
+
+libbar_gir = gnome.generate_gir(libbar,
+ sources: libbar_sources,
+ namespace: 'Bar',
+ nsversion: libbar_api_ver,
+ packages: 'gobject-2.0',
+ symbol_prefix: 'bar',
+ extra_args: [
+ '--c-include=bar.h',
+ ],
+)
+
+libbar_vapi = gnome.generate_vapi('bar-' + libbar_api_ver,
+ sources: libbar_gir[0],
+ packages: libfoo_vapi,
+ install: true,
+)
diff --git a/test cases/vala/12 generated vapi/libfoo/foo.c b/test cases/vala/12 generated vapi/libfoo/foo.c
new file mode 100644
index 0000000..0413ac5
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libfoo/foo.c
@@ -0,0 +1,11 @@
+#include "foo.h"
+
+/**
+ * foo_return_success:
+ *
+ * Returns 0
+ */
+int foo_return_success(void)
+{
+ return 0;
+}
diff --git a/test cases/vala/12 generated vapi/libfoo/foo.h b/test cases/vala/12 generated vapi/libfoo/foo.h
new file mode 100644
index 0000000..f09256d
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libfoo/foo.h
@@ -0,0 +1,5 @@
+#include <glib-object.h>
+
+#pragma once
+
+int foo_return_success(void);
diff --git a/test cases/vala/12 generated vapi/libfoo/meson.build b/test cases/vala/12 generated vapi/libfoo/meson.build
new file mode 100644
index 0000000..482c8fe
--- /dev/null
+++ b/test cases/vala/12 generated vapi/libfoo/meson.build
@@ -0,0 +1,36 @@
+libfoo_sources = [
+ 'foo.c',
+ 'foo.h',
+]
+
+libfoo_deps = [
+ dependency('gobject-2.0')
+]
+
+libfoo = shared_library('foo', libfoo_sources,
+ dependencies: libfoo_deps,
+ install: true,
+)
+
+libfoo_api_ver = '1.0'
+
+libfoo_gir = gnome.generate_gir(libfoo,
+ sources: libfoo_sources,
+ namespace: 'Foo',
+ nsversion: libfoo_api_ver,
+ packages: 'gobject-2.0',
+ symbol_prefix: 'foo',
+ extra_args: [
+ '--c-include=foo.h',
+ ],
+)
+
+libfoo_vapi = gnome.generate_vapi('foo-' + libfoo_api_ver,
+ sources: libfoo_gir[0],
+ install: true,
+)
+
+libfoo_dep = declare_dependency(
+ link_with: libfoo,
+ include_directories: include_directories('.'),
+)
diff --git a/test cases/vala/12 generated vapi/main.vala b/test cases/vala/12 generated vapi/main.vala
new file mode 100644
index 0000000..303ab33
--- /dev/null
+++ b/test cases/vala/12 generated vapi/main.vala
@@ -0,0 +1,9 @@
+using Foo;
+using Bar;
+
+class Main : GLib.Object {
+ public static int main(string[] args) {
+ var ignore = Foo.return_success();
+ return Bar.return_success();
+ }
+}
diff --git a/test cases/vala/12 generated vapi/meson.build b/test cases/vala/12 generated vapi/meson.build
new file mode 100644
index 0000000..82f0c44
--- /dev/null
+++ b/test cases/vala/12 generated vapi/meson.build
@@ -0,0 +1,13 @@
+project('vapi-test', ['c', 'vala'])
+
+gnome = import('gnome')
+subdir('libfoo')
+subdir('libbar')
+
+vapiexe = executable('vapigen-test',
+ 'main.vala',
+ dependencies: [dependency('gobject-2.0'), libbar_vapi],
+ install: true,
+)
+
+test('vapigen-test', vapiexe)