From 69dcbb6ec9e8bab86b66c9d78dc4a0dba4350659 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 11 Nov 2016 04:30:15 +0530 Subject: [PATCH 1/2] gnome.generate_gir: Add gir deps and includes recursively Earlier, we were never adding dependencies on other GirTargets that we need. The dependency would only be added indirectly through other BuildTargets such as SharedLibrary. Now we add all GirTargets specified in the `dependencies :` kwarg to the list of dependencies of the GirTarget that we generate. Also, we weren't adding include directories for the typelib generation command recursively. We were only adding it for the GirTargets listed under the `dependencies :` kwarg to gnome.generate_gir. Now we search all link targets, find GirTargets, extract the include dir, and use it. In summation, dependencies were completely broken. --- mesonbuild/modules/gnome.py | 53 ++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index f3f22bc8a..15ed1786d 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -401,6 +401,41 @@ class GnomeModule: deps = [deps] deps = (girtarget.get_all_link_deps() + girtarget.get_external_deps() + deps) + # Need to recursively add deps on GirTarget sources from our + # dependencies and also find the include directories needed for the + # typelib generation custom target below. + typelib_includes = [] + for dep in deps: + if hasattr(dep, 'held_object'): + dep = dep.held_object + # Add a dependency on each GirTarget listed in dependencies and add + # the directory where it will be generated to the typelib includes + if isinstance(dep, dependencies.InternalDependency): + for source in dep.sources: + if hasattr(source, 'held_object'): + source = source.held_object + if isinstance(source, GirTarget) and source not in depends: + depends.append(source) + subdir = os.path.join(state.environment.get_build_dir(), + source.get_subdir()) + if subdir not in typelib_includes: + typelib_includes.append(subdir) + # Do the same, but for dependencies of dependencies. These are + # stored in the list of generated sources for each link dep (from + # girtarget.get_all_link_deps() above). + # FIXME: Store this in the original form from declare_dependency() + # so it can be used here directly. + elif isinstance(dep, build.SharedLibrary): + for source in dep.generated: + if isinstance(source, GirTarget): + subdir = os.path.join(state.environment.get_build_dir(), + source.get_subdir()) + if subdir not in typelib_includes: + typelib_includes.append(subdir) + elif isinstance(dep, dependencies.PkgConfigDependency): + girdir = dep.get_pkgconfig_variable("girdir") + if girdir and girdir not in typelib_includes: + typelib_includes.append(girdir) # ldflags will be misinterpreted by gir scanner (showing # spurious dependencies) but building GStreamer fails if they # are not used here. @@ -441,22 +476,8 @@ class GnomeModule: typelib_cmd = ['g-ir-compiler', scan_target, '--output', '@OUTPUT@'] typelib_cmd += self._get_include_args(state, gir_inc_dirs, prefix='--includedir=') - for dep in deps: - if hasattr(dep, 'held_object'): - dep = dep.held_object - if isinstance(dep, dependencies.InternalDependency): - for source in dep.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, dependencies.PkgConfigDependency): - girdir = dep.get_pkgconfig_variable("girdir") - if girdir: - typelib_cmd += ["--includedir=%s" % (girdir, )] + for incdir in typelib_includes: + typelib_cmd += ["--includedir=" + incdir] typelib_kwargs = { 'output': typelib_output, From 4b7ddfbce7537b83e0dcb6190ae22d58d09137f4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sun, 13 Nov 2016 02:49:39 +0530 Subject: [PATCH 2/2] Add a test for gir dependencies and includes MesonDep1 doesn't use symbols from MesonDep2, but uses the MesonDep2 structure definition (so it only needs the header). This means only generate_gir needs a dependency on MesonDep2 and shared_library doesn't. This was broken earlier. MesonSample uses symbols from MesonDep1 and MesonDep2, so both the library and the gir get a dependency on MesonDep1, and on MesonDep2 (transitively). The transitive dependency was broken earlier. --- test cases/frameworks/7 gnome/gir/dep1/dep1.c | 56 ++++++++ test cases/frameworks/7 gnome/gir/dep1/dep1.h | 23 ++++ .../frameworks/7 gnome/gir/dep1/dep2/dep2.c | 124 ++++++++++++++++++ .../frameworks/7 gnome/gir/dep1/dep2/dep2.h | 21 +++ .../7 gnome/gir/dep1/dep2/meson.build | 22 ++++ .../frameworks/7 gnome/gir/dep1/meson.build | 29 ++++ .../frameworks/7 gnome/gir/meson-sample.c | 15 +-- .../frameworks/7 gnome/gir/meson-sample.h | 7 +- test cases/frameworks/7 gnome/gir/meson.build | 16 ++- test cases/frameworks/7 gnome/gir/prog.c | 8 +- test cases/frameworks/7 gnome/gir/prog.py | 8 +- .../frameworks/7 gnome/installed_files.txt | 8 +- 12 files changed, 314 insertions(+), 23 deletions(-) create mode 100755 test cases/frameworks/7 gnome/gir/dep1/dep1.c create mode 100755 test cases/frameworks/7 gnome/gir/dep1/dep1.h create mode 100755 test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c create mode 100755 test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h create mode 100755 test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build create mode 100755 test cases/frameworks/7 gnome/gir/dep1/meson.build mode change 100644 => 100755 test cases/frameworks/7 gnome/gir/meson-sample.c mode change 100644 => 100755 test cases/frameworks/7 gnome/gir/meson-sample.h mode change 100644 => 100755 test cases/frameworks/7 gnome/gir/meson.build mode change 100644 => 100755 test cases/frameworks/7 gnome/gir/prog.c diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep1.c b/test cases/frameworks/7 gnome/gir/dep1/dep1.c new file mode 100755 index 000000000..8d4ca4bfe --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep1.c @@ -0,0 +1,56 @@ +#include "dep1.h" + +struct _MesonDep1 +{ + GObject parent_instance; +}; + +G_DEFINE_TYPE (MesonDep1, meson_dep1, G_TYPE_OBJECT) + +/** + * meson_dep1_new: + * + * Allocates a new #MesonDep1. + * + * Returns: (transfer full): a #MesonDep1. + */ +MesonDep1 * +meson_dep1_new (void) +{ + return g_object_new (MESON_TYPE_DEP1, NULL); +} + +static void +meson_dep1_finalize (GObject *object) +{ + G_OBJECT_CLASS (meson_dep1_parent_class)->finalize (object); +} + +static void +meson_dep1_class_init (MesonDep1Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meson_dep1_finalize; +} + +static void +meson_dep1_init (MesonDep1 *self) +{ +} + +/** + * meson_dep1_just_return_it: + * @dep: a #MesonDep2. + * + * Returns the #MesonDep2 that is passed in + * + * Returns: (transfer none): a #MesonDep2 + */ +MesonDep2* +meson_dep1_just_return_it (MesonDep1 *self, MesonDep2 *dep) +{ + g_return_val_if_fail (MESON_IS_DEP1 (self), NULL); + + return dep; +} diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep1.h b/test cases/frameworks/7 gnome/gir/dep1/dep1.h new file mode 100755 index 000000000..92fc44c86 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep1.h @@ -0,0 +1,23 @@ +#ifndef MESON_DEP1_H +#define MESON_DEP1_H + +#if !defined (MESON_TEST) +#error "MESON_TEST not defined." +#endif + +#include +#include "dep2/dep2.h" + +G_BEGIN_DECLS + +#define MESON_TYPE_DEP1 (meson_dep1_get_type()) + +G_DECLARE_FINAL_TYPE (MesonDep1, meson_dep1, MESON, DEP1, GObject) + +MesonDep1 *meson_dep1_new (void); +MesonDep2 *meson_dep1_just_return_it (MesonDep1 *self, + MesonDep2 *dep); + +G_END_DECLS + +#endif /* MESON_DEP1_H */ diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c new file mode 100755 index 000000000..754c6d7f7 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.c @@ -0,0 +1,124 @@ +#include "dep2.h" + +struct _MesonDep2 +{ + GObject parent_instance; + + gchar *msg; +}; + +G_DEFINE_TYPE (MesonDep2, meson_dep2, G_TYPE_OBJECT) + +enum { + PROP_0, + PROP_MSG, + LAST_PROP +}; + +static GParamSpec *gParamSpecs [LAST_PROP]; + +/** + * meson_dep2_new: + * @msg: The message to set. + * + * Allocates a new #MesonDep2. + * + * Returns: (transfer full): a #MesonDep2. + */ +MesonDep2 * +meson_dep2_new (const gchar *msg) +{ + g_return_val_if_fail (msg != NULL, NULL); + + return g_object_new (MESON_TYPE_DEP2, + "message", msg, + NULL); +} + +static void +meson_dep2_finalize (GObject *object) +{ + MesonDep2 *self = (MesonDep2 *)object; + + g_clear_pointer (&self->msg, g_free); + + G_OBJECT_CLASS (meson_dep2_parent_class)->finalize (object); +} + +static void +meson_dep2_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MesonDep2 *self = MESON_DEP2 (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_dep2_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MesonDep2 *self = MESON_DEP2 (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_dep2_class_init (MesonDep2Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meson_dep2_finalize; + object_class->get_property = meson_dep2_get_property; + object_class->set_property = meson_dep2_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_dep2_init (MesonDep2 *self) +{ +} + +/** + * meson_dep2_return_message: + * @self: a #MesonDep2. + * + * Returns the message. + * + * Returns: (transfer none): a const gchar* + */ +const gchar* +meson_dep2_return_message (MesonDep2 *self) +{ + g_return_val_if_fail (MESON_IS_DEP2 (self), NULL); + + return (const gchar*) self->msg; +} diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h new file mode 100755 index 000000000..0afea9029 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/dep2.h @@ -0,0 +1,21 @@ +#ifndef MESON_DEP2_H +#define MESON_DEP2_H + +#if !defined (MESON_TEST) +#error "MESON_TEST not defined." +#endif + +#include + +G_BEGIN_DECLS + +#define MESON_TYPE_DEP2 (meson_dep2_get_type()) + +G_DECLARE_FINAL_TYPE (MesonDep2, meson_dep2, MESON, DEP2, GObject) + +MesonDep2 *meson_dep2_new (const gchar *msg); +const gchar *meson_dep2_return_message (MesonDep2 *self); + +G_END_DECLS + +#endif /* MESON_DEP2_H */ diff --git a/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build b/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build new file mode 100755 index 000000000..4004f22d6 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/dep2/meson.build @@ -0,0 +1,22 @@ +dep2sources = ['dep2.c', 'dep2.h'] + +dep2lib = shared_library( + 'dep2lib', + sources : dep2sources, + dependencies : gobj, + install : true +) + +dep2gir = gnome.generate_gir( + dep2lib, + sources : dep2sources, + nsversion : '1.0', + namespace : 'MesonDep2', + symbol_prefix : 'meson', + identifier_prefix : 'Meson', + includes : ['GObject-2.0'], + install : true +) + +dep2_dep = declare_dependency(link_with : dep2lib, + sources : [dep2gir]) diff --git a/test cases/frameworks/7 gnome/gir/dep1/meson.build b/test cases/frameworks/7 gnome/gir/dep1/meson.build new file mode 100755 index 000000000..75dd73166 --- /dev/null +++ b/test cases/frameworks/7 gnome/gir/dep1/meson.build @@ -0,0 +1,29 @@ +subdir('dep2') + +dep1sources = ['dep1.c', 'dep1.h'] + +# Do not need to link to dep2lib because we don't use any symbols from it +dep1lib = shared_library( + 'dep1lib', + sources : dep1sources, + dependencies : gobj, + install : true +) + +# But the gir does need it because it we use the MesonDep2* structure defined +# in the header +dep1gir = gnome.generate_gir( + dep1lib, + sources : dep1sources, + nsversion : '1.0', + namespace : 'MesonDep1', + symbol_prefix : 'meson', + identifier_prefix : 'Meson', + includes : ['GObject-2.0', 'MesonDep2-1.0'], + dependencies : [dep2_dep], + install : true +) + +dep1_dep = declare_dependency(link_with : dep1lib, + dependencies : [dep2_dep], + sources : [dep1gir]) diff --git a/test cases/frameworks/7 gnome/gir/meson-sample.c b/test cases/frameworks/7 gnome/gir/meson-sample.c old mode 100644 new mode 100755 index dbf3625db..850b850cf --- a/test cases/frameworks/7 gnome/gir/meson-sample.c +++ b/test cases/frameworks/7 gnome/gir/meson-sample.c @@ -19,20 +19,15 @@ 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) +meson_sample_new (void) { - g_return_val_if_fail (msg != NULL, NULL); - - return g_object_new (MESON_TYPE_SAMPLE, - "message", msg, - NULL); + return g_object_new (MESON_TYPE_SAMPLE, NULL); } static void @@ -116,9 +111,11 @@ meson_sample_init (MesonSample *self) * Returns: Nothing. */ void -meson_sample_print_message (MesonSample *self) +meson_sample_print_message (MesonSample *self, MesonDep1 *dep1, MesonDep2 *dep2) { + MesonDep2 *samedep; g_return_if_fail (MESON_IS_SAMPLE (self)); - g_print ("Message: %s\n", self->msg); + samedep = meson_dep1_just_return_it (dep1, dep2); + g_print ("Message: %s\n", meson_dep2_return_message (samedep)); } diff --git a/test cases/frameworks/7 gnome/gir/meson-sample.h b/test cases/frameworks/7 gnome/gir/meson-sample.h old mode 100644 new mode 100755 index cd2bbc6a6..04e79b839 --- a/test cases/frameworks/7 gnome/gir/meson-sample.h +++ b/test cases/frameworks/7 gnome/gir/meson-sample.h @@ -6,6 +6,7 @@ #endif #include +#include "dep1/dep1.h" G_BEGIN_DECLS @@ -13,8 +14,10 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject) -MesonSample *meson_sample_new (const gchar *msg); -void meson_sample_print_message (MesonSample *self); +MesonSample *meson_sample_new (void); +void meson_sample_print_message (MesonSample *self, + MesonDep1 *dep1, + MesonDep2 *dep2); G_END_DECLS diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build old mode 100644 new mode 100755 index 51bbbab54..beddc8183 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -1,9 +1,11 @@ +subdir('dep1') + libsources = ['meson-sample.c', 'meson-sample.h'] girlib = shared_library( 'gir_lib', sources : libsources, - dependencies : gobj, + dependencies : [gobj, dep1_dep], install : true ) @@ -21,15 +23,17 @@ gnome.generate_gir( sources : libsources, nsversion : '1.0', namespace : 'Meson', - symbol_prefix : 'meson_', + symbol_prefix : 'meson', identifier_prefix : 'Meson', - includes : ['GObject-2.0'], - dependencies : [fake_dep], + includes : ['GObject-2.0', 'MesonDep1-1.0'], + # dep1_dep pulls in dep2_dep for us + dependencies : [fake_dep, dep1_dep], install : true ) test('gobject introspection/c', girexe) +gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir()]) test('gobject introspection/py', find_program('prog.py'), - env : ['GI_TYPELIB_PATH=' + girlib.outdir(), - 'LD_LIBRARY_PATH=' + girlib.outdir(), + env : ['GI_TYPELIB_PATH=' + gir_paths, + 'LD_LIBRARY_PATH=' + gir_paths, ]) diff --git a/test cases/frameworks/7 gnome/gir/prog.c b/test cases/frameworks/7 gnome/gir/prog.c old mode 100644 new mode 100755 index c855a6b28..001f6d0b9 --- a/test cases/frameworks/7 gnome/gir/prog.c +++ b/test cases/frameworks/7 gnome/gir/prog.c @@ -21,10 +21,14 @@ main (gint argc, return 1; } - MesonSample * i = meson_sample_new ("Hello, meson/c!"); - meson_sample_print_message (i); + MesonSample * i = meson_sample_new (); + MesonDep1 * dep1 = meson_dep1_new (); + MesonDep2 * dep2 = meson_dep2_new ("Hello, meson/c!"); + meson_sample_print_message (i, dep1, dep2); g_object_unref (i); + g_object_unref (dep1); + g_object_unref (dep2); g_option_context_free (ctx); return 0; diff --git a/test cases/frameworks/7 gnome/gir/prog.py b/test cases/frameworks/7 gnome/gir/prog.py index 717d08a86..7ce2aa724 100755 --- a/test cases/frameworks/7 gnome/gir/prog.py +++ b/test cases/frameworks/7 gnome/gir/prog.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 -from gi.repository import Meson +from gi.repository import Meson, MesonDep1, MesonDep2 if __name__ == "__main__": - s = Meson.Sample.new("Hello, meson/py!") - s.print_message() + s = Meson.Sample.new() + dep1 = MesonDep1.Dep1.new() + dep2 = MesonDep2.Dep2.new("Hello, meson/py!") + s.print_message(dep1, dep2) diff --git a/test cases/frameworks/7 gnome/installed_files.txt b/test cases/frameworks/7 gnome/installed_files.txt index a18e4450d..06f416396 100644 --- a/test cases/frameworks/7 gnome/installed_files.txt +++ b/test cases/frameworks/7 gnome/installed_files.txt @@ -2,7 +2,13 @@ usr/include/enums.h usr/include/enums2.h usr/include/enums3.h usr/include/marshaller.h -usr/lib/girepository-1.0/Meson-1.0.typelib usr/lib/libgir_lib.so +usr/lib/libdep1lib.so +usr/lib/libdep2lib.so +usr/lib/girepository-1.0/Meson-1.0.typelib +usr/lib/girepository-1.0/MesonDep1-1.0.typelib +usr/lib/girepository-1.0/MesonDep2-1.0.typelib usr/share/gir-1.0/Meson-1.0.gir +usr/share/gir-1.0/MesonDep1-1.0.gir +usr/share/gir-1.0/MesonDep2-1.0.gir usr/share/glib-2.0/schemas/com.github.meson.gschema.xml