diff options
-rw-r--r-- | mesonbuild/interpreter.py | 6 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 147 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/installed_files.txt | 7 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libbar/bar.c | 12 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libbar/bar.h | 5 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libbar/meson.build | 33 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libfoo/foo.c | 11 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libfoo/foo.h | 5 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/libfoo/meson.build | 36 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/main.vala | 9 | ||||
-rw-r--r-- | test cases/vala/12 generated vapi/meson.build | 13 |
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) |