diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index f451cced2..d6a0fcf8e 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -19,6 +19,7 @@ from .. import build import os, sys import subprocess from ..mesonlib import MesonException +from .. import dependencies from .. import mlog from .. import mesonlib @@ -90,6 +91,33 @@ class GnomeModule: return stdout.split('\n')[:-1] + def get_link_args(self, state, lib, depends): + link_command = ['-l%s' % lib.name] + if isinstance(lib, build.SharedLibrary): + link_command += ['-L%s' % + os.path.join(state.environment.get_build_dir(), + lib.subdir)] + depends.append(lib) + return link_command + + def get_include_args(self, state, include_dirs): + if not include_dirs: + return [] + + dirs_str = [] + for incdirs in include_dirs: + if hasattr(incdirs, "held_object"): + dirs = incdirs.held_object + else: + dirs = incdirs + for incdir in dirs.get_incdirs(): + if os.path.isabs(incdir): + dirs_str += ['-I%s' % os.path.join(incdir)] + else: + dirs_str += ['-I%s' % os.path.join(state.environment.get_source_dir(), + dirs.curdir, incdir)] + return dirs_str + def generate_gir(self, state, args, kwargs): if len(args) != 1: raise MesonException('Gir takes one argument') @@ -120,23 +148,14 @@ class GnomeModule: extra_args = mesonlib.stringlistify(kwargs.pop('extra_args', [])) scan_command += extra_args - - for incdirs in girtarget.include_dirs: - for incdir in incdirs.get_incdirs(): - scan_command += ['-I%s' % os.path.join(state.environment.get_source_dir(), incdir)] + scan_command += self.get_include_args(state, girtarget.include_dirs) if 'link_with' in kwargs: link_with = kwargs.pop('link_with') if not isinstance(link_with, list): link_with = [link_with] for link in link_with: - lib = link.held_object - scan_command += ['-l%s' % lib.name] - if isinstance(lib, build.SharedLibrary): - scan_command += ['-L%s' % - os.path.join(state.environment.get_build_dir(), - lib.subdir)] - depends.append(lib) + scan_command += self.get_link_args(state, link.held_object, depends) if 'includes' in kwargs: includes = kwargs.pop('includes') @@ -175,24 +194,43 @@ class GnomeModule: if not isinstance (deps, list): deps = [deps] for dep in deps: - girdir = dep.held_object.get_variable ("girdir") - if girdir: - scan_command += ["--add-include-path=%s" % girdir] - for lib in dep.held_object.libs: - if os.path.isabs(lib) and dep.held_object.is_libtool: - scan_command += ["-L%s" % os.path.dirname(lib)] - libname = os.path.basename(lib) - if libname.startswith("lib"): - libname = libname[3:] - libname = libname.split(".so")[0] - lib = "-l%s" % libname - scan_command += [lib] + if isinstance(dep.held_object, dependencies.InternalDependency): + scan_command += self.get_include_args(state, dep.held_object.include_directories) + for lib in dep.held_object.libraries: + scan_command += self.get_link_args(state, lib.held_object, depends) + for source in dep.held_object.sources: + if isinstance(source.held_object, GirTarget): + scan_command += ["--add-include-path=%s" % + os.path.join(state.environment.get_build_dir(), + source.held_object.get_subdir())] + elif isinstance(dep.held_object, dependencies.PkgConfigDependency): + for lib in dep.held_object.libs: + if os.path.isabs(lib) and dep.held_object.is_libtool: + scan_command += ["-L%s" % os.path.dirname(lib)] + libname = os.path.basename(lib) + if libname.startswith("lib"): + libname = libname[3:] + libname = libname.split(".so")[0] + lib = "-l%s" % libname + # Hack to avoid passing some compiler options in + if lib.startswith("-W"): + continue + scan_command += [lib] + + girdir = dep.held_object.get_variable ("girdir") + if girdir: + scan_command += ["--add-include-path=%s" % girdir] + else: + mlog.log('dependency %s not handled to build gir files' % dep) + continue inc_dirs = None if kwargs.get('include_directories'): inc_dirs = kwargs.pop('include_directories') + if not isinstance(inc_dirs, list): inc_dirs = [inc_dirs] + for ind in inc_dirs: if isinstance(ind.held_object, build.IncludeDirs): scan_command += ['--add-include-path=%s' % inc for inc in ind.held_object.get_incdirs()] @@ -222,9 +260,16 @@ class GnomeModule: incd.held_object.get_incdirs()] if deps: for dep in deps: - girdir = dep.held_object.get_variable ("girdir") - if girdir: - typelib_cmd += ["--includedir=%s" % girdir] + if isinstance(dep.held_object, dependencies.InternalDependency): + for source in dep.held_object.sources: + if isinstance(source.held_object, GirTarget): + typelib_cmd += ["--includedir=%s" % + os.path.join(state.environment.get_build_dir(), + source.held_object.get_subdir())] + elif isinstance(dep.held_object, dependencies.PkgConfigDependency): + girdir = dep.held_object.get_variable ("girdir") + if girdir: + typelib_cmd += ["--includedir=%s" % girdir] kwargs['output'] = typelib_output kwargs['command'] = typelib_cmd diff --git a/test cases/frameworks/11 gir subproject/gir/meson-subsample.c b/test cases/frameworks/11 gir subproject/gir/meson-subsample.c new file mode 100644 index 000000000..2d58a1039 --- /dev/null +++ b/test cases/frameworks/11 gir subproject/gir/meson-subsample.c @@ -0,0 +1,124 @@ +#include "meson-subsample.h" + +struct _MesonSubSample +{ + MesonSample parent_instance; + + gchar *msg; +}; + +G_DEFINE_TYPE (MesonSubSample, meson_sub_sample, MESON_TYPE_SAMPLE) + +enum { + PROP_0, + PROP_MSG, + LAST_PROP +}; + +static GParamSpec *gParamSpecs [LAST_PROP]; + +/** + * meson_sub_sample_new: + * @msg: The message to set. + * + * Allocates a new #MesonSubSample. + * + * Returns: (transfer full): a #MesonSubSample. + */ +MesonSubSample * +meson_sub_sample_new (const gchar *msg) +{ + g_return_val_if_fail (msg != NULL, NULL); + + return g_object_new (MESON_TYPE_SUB_SAMPLE, + "message", msg, + NULL); +} + +static void +meson_sub_sample_finalize (GObject *object) +{ + MesonSubSample *self = (MesonSubSample *)object; + + g_clear_pointer (&self->msg, g_free); + + G_OBJECT_CLASS (meson_sub_sample_parent_class)->finalize (object); +} + +static void +meson_sub_sample_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MesonSubSample *self = MESON_SUB_SAMPLE (object); + + switch (prop_id) + { + case PROP_MSG: + g_value_set_string (value, self->msg); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_sub_sample_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MesonSubSample *self = MESON_SUB_SAMPLE (object); + + switch (prop_id) + { + case PROP_MSG: + self->msg = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_sub_sample_class_init (MesonSubSampleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meson_sub_sample_finalize; + object_class->get_property = meson_sub_sample_get_property; + object_class->set_property = meson_sub_sample_set_property; + + gParamSpecs [PROP_MSG] = + g_param_spec_string ("message", + "Message", + "The message to print.", + NULL, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs); +} + +static void +meson_sub_sample_init (MesonSubSample *self) +{ +} + +/** + * meson_sub_sample_print_message: + * @self: a #MesonSubSample. + * + * Prints the message. + * + * Returns: Nothing. + */ +void +meson_sub_sample_print_message (MesonSubSample *self) +{ + g_return_if_fail (MESON_IS_SUB_SAMPLE (self)); + + g_print ("Message: %s\n", self->msg); +} diff --git a/test cases/frameworks/11 gir subproject/gir/meson-subsample.h b/test cases/frameworks/11 gir subproject/gir/meson-subsample.h new file mode 100644 index 000000000..666d59ffa --- /dev/null +++ b/test cases/frameworks/11 gir subproject/gir/meson-subsample.h @@ -0,0 +1,21 @@ +#ifndef MESON_SUB_SAMPLE_H +#define MESON_SUB_SAMPLE_H + +#if !defined (MESON_TEST) +#error "MESON_TEST not defined." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define MESON_TYPE_SUB_SAMPLE (meson_sub_sample_get_type()) + +G_DECLARE_FINAL_TYPE (MesonSubSample, meson_sub_sample, MESON, SUB_SAMPLE, MesonSample) + +MesonSubSample *meson_sub_sample_new (const gchar *msg); + +G_END_DECLS + +#endif /* MESON_SUB_SAMPLE_H */ diff --git a/test cases/frameworks/11 gir subproject/gir/meson.build b/test cases/frameworks/11 gir subproject/gir/meson.build new file mode 100644 index 000000000..e92c64163 --- /dev/null +++ b/test cases/frameworks/11 gir subproject/gir/meson.build @@ -0,0 +1,35 @@ +libsources = ['meson-subsample.c', 'meson-subsample.h'] + +girsubproject = shared_library( + 'girsubproject', + sources : libsources, + dependencies : [gobj, meson_gir], + install : true +) + +girexe = executable( + 'girprog', + sources : 'prog.c', + dependencies : [gobj, meson_gir], + link_with : girsubproject +) + +gnome.generate_gir( + girsubproject, + sources : libsources, + dependencies : [gobj, meson_gir], + nsversion : '1.0', + namespace : 'MesonSub', + symbol_prefix : 'meson_sub_', + identifier_prefix : 'MesonSub', + includes : ['GObject-2.0', 'Meson-1.0'], + install : true +) + +message('TEST: ' + girsubproject.outdir()) + +test('gobject introspection/subproject/c', girexe) +test('gobject introspection/subproject/py', find_program('prog.py'), + env : ['GI_TYPELIB_PATH=' + girsubproject.outdir() + ':subprojects/mesongir', + 'LD_LIBRARY_PATH=' + girsubproject.outdir() + ':subprojects/mesongir', + ]) diff --git a/test cases/frameworks/11 gir subproject/gir/prog.c b/test cases/frameworks/11 gir subproject/gir/prog.c new file mode 100644 index 000000000..f25c9d85c --- /dev/null +++ b/test cases/frameworks/11 gir subproject/gir/prog.c @@ -0,0 +1,12 @@ +#include "meson-subsample.h" + +gint +main (gint argc, + gchar *argv[]) +{ + MesonSample * i = (MesonSample*) meson_sub_sample_new ("Hello, sub/meson/c!"); + meson_sample_print_message (i); + g_object_unref (i); + + return 0; +} diff --git a/test cases/frameworks/11 gir subproject/gir/prog.py b/test cases/frameworks/11 gir subproject/gir/prog.py new file mode 100755 index 000000000..ea4da5b5e --- /dev/null +++ b/test cases/frameworks/11 gir subproject/gir/prog.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +from gi.repository import MesonSub + +if __name__ == "__main__": + s = MesonSub.Sample.new("Hello, sub/meson/py!") + s.print_message() diff --git a/test cases/frameworks/11 gir subproject/installed_files.txt b/test cases/frameworks/11 gir subproject/installed_files.txt new file mode 100644 index 000000000..434481ebe --- /dev/null +++ b/test cases/frameworks/11 gir subproject/installed_files.txt @@ -0,0 +1,6 @@ +usr/lib/girepository-1.0/Meson-1.0.typelib +usr/lib/girepository-1.0/MesonSub-1.0.typelib +usr/share/gir-1.0/Meson-1.0.gir +usr/share/gir-1.0/MesonSub-1.0.gir +usr/lib/libgirsubproject.so +usr/lib/libgirlib.so diff --git a/test cases/frameworks/11 gir subproject/meson.build b/test cases/frameworks/11 gir subproject/meson.build new file mode 100644 index 000000000..f3bde4042 --- /dev/null +++ b/test cases/frameworks/11 gir subproject/meson.build @@ -0,0 +1,10 @@ +project('gobject-introspection-with-subproject', 'c') + +gnome = import('gnome') +gobj = dependency('gobject-2.0') + +add_global_arguments('-DMESON_TEST', language : 'c') +meson_gir = dependency('meson-gir', fallback : ['mesongir', 'meson_gir']) + +subdir('gir') + diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c new file mode 100644 index 000000000..2e78b076f --- /dev/null +++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.c @@ -0,0 +1,127 @@ +#include "meson-sample.h" + +typedef struct _MesonSamplePrivate +{ + gchar *msg; +} MesonSamplePrivate; + + +G_DEFINE_TYPE_WITH_PRIVATE (MesonSample, meson_sample, G_TYPE_OBJECT) + +enum { + PROP_0, + PROP_MSG, + LAST_PROP +}; + +static GParamSpec *gParamSpecs [LAST_PROP]; + +/** + * meson_sample_new: + * @msg: The message to set. + * + * Allocates a new #MesonSample. + * + * Returns: (transfer full): a #MesonSample. + */ +MesonSample * +meson_sample_new (const gchar *msg) +{ + g_return_val_if_fail (msg != NULL, NULL); + + return g_object_new (MESON_TYPE_SAMPLE, + "message", msg, + NULL); +} + +static void +meson_sample_finalize (GObject *object) +{ + MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object); + + g_clear_pointer (&priv->msg, g_free); + + G_OBJECT_CLASS (meson_sample_parent_class)->finalize (object); +} + +static void +meson_sample_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object); + + switch (prop_id) + { + case PROP_MSG: + g_value_set_string (value, priv->msg); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_sample_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MesonSamplePrivate *priv = meson_sample_get_instance_private ((MesonSample *) object); + + switch (prop_id) + { + case PROP_MSG: + priv->msg = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +meson_sample_class_init (MesonSampleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meson_sample_finalize; + object_class->get_property = meson_sample_get_property; + object_class->set_property = meson_sample_set_property; + + gParamSpecs [PROP_MSG] = + g_param_spec_string ("message", + "Message", + "The message to print.", + NULL, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs); +} + +static void +meson_sample_init (MesonSample *self) +{ +} + +/** + * meson_sample_print_message: + * @self: a #MesonSample. + * + * Prints the message. + * + * Returns: Nothing. + */ +void +meson_sample_print_message (MesonSample *self) +{ + MesonSamplePrivate *priv; + + g_return_if_fail (MESON_IS_SAMPLE (self)); + + priv = meson_sample_get_instance_private (self); + + g_print ("Message: %s\n", priv->msg); +} diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h new file mode 100644 index 000000000..e4c07a8cf --- /dev/null +++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson-sample.h @@ -0,0 +1,26 @@ +#ifndef MESON_SAMPLE_H +#define MESON_SAMPLE_H + +#if !defined (MESON_TEST) +#error "MESON_TEST not defined." +#endif + +#include + +G_BEGIN_DECLS + +#define MESON_TYPE_SAMPLE (meson_sample_get_type()) + +G_DECLARE_DERIVABLE_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject) + +struct _MesonSampleClass { + GObjectClass parent_class; +}; + + +MesonSample *meson_sample_new (const gchar *msg); +void meson_sample_print_message (MesonSample *self); + +G_END_DECLS + +#endif /* MESON_SAMPLE_H */ diff --git a/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build new file mode 100644 index 000000000..027b4ee80 --- /dev/null +++ b/test cases/frameworks/11 gir subproject/subprojects/mesongir/meson.build @@ -0,0 +1,31 @@ +project('gobject-introspection-subproject', 'c') + +gnome = import('gnome') +gobj = dependency('gobject-2.0') + +libsources = ['meson-sample.c', 'meson-sample.h'] + +girlib = shared_library( + 'girlib', + sources : libsources, + dependencies : gobj, + install : true +) + +girtarget = gnome.generate_gir( + girlib, + sources : libsources, + nsversion : '1.0', + namespace : 'Meson', + symbol_prefix : 'meson_', + identifier_prefix : 'Meson', + includes : ['GObject-2.0'], + install : true +) + +meson_gir = declare_dependency(link_with : girlib, + include_directories : [include_directories('.')], + dependencies : [gobj], + # Everything that uses libgst needs this built to compile + sources : girtarget, +) diff --git a/test cases/frameworks/7 gnome/gir/prog.c b/test cases/frameworks/7 gnome/gir/prog.c index 1116285dd..c855a6b28 100644 --- a/test cases/frameworks/7 gnome/gir/prog.c +++ b/test cases/frameworks/7 gnome/gir/prog.c @@ -6,18 +6,26 @@ gint main (gint argc, gchar *argv[]) { - g_autoptr(GError) error = NULL; + GError * error = NULL; - g_autoptr(GOptionContext) ctx = g_option_context_new (NULL); + GOptionContext * ctx = g_option_context_new (NULL); g_option_context_add_group (ctx, g_irepository_get_option_group ()); if (!g_option_context_parse (ctx, &argc, &argv, &error)) { g_print ("sample: %s\n", error->message); + g_option_context_free (ctx); + if (error) { + g_error_free (error); + } + return 1; } - g_autoptr(MesonSample) i = meson_sample_new ("Hello, meson/c!"); + MesonSample * i = meson_sample_new ("Hello, meson/c!"); meson_sample_print_message (i); + g_object_unref (i); + g_option_context_free (ctx); + return 0; }