diff options
10 files changed, 194 insertions, 24 deletions
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 3f6f449..c45d29d 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -316,7 +316,8 @@ class GnomeModule(ExtensionModule): def _get_dependencies_flags(self, deps, state, depends, include_rpath=False, use_gir_args=False): cflags = OrderedSet() - ldflags = OrderedSet() + internal_ldflags = OrderedSet() + external_ldflags = OrderedSet() gi_includes = OrderedSet() deps = mesonlib.listify(deps, unholder=True) @@ -326,17 +327,19 @@ class GnomeModule(ExtensionModule): for lib in dep.libraries: if hasattr(lib, 'held_object'): lib = lib.held_object - ldflags.update(self._get_link_args(state, lib, depends, include_rpath)) + internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath)) libdepflags = self._get_dependencies_flags(lib.get_external_deps(), state, depends, include_rpath, use_gir_args) cflags.update(libdepflags[0]) - ldflags.update(libdepflags[1]) - gi_includes.update(libdepflags[2]) + internal_ldflags.update(libdepflags[1]) + external_ldflags.update(libdepflags[2]) + gi_includes.update(libdepflags[3]) extdepflags = self._get_dependencies_flags(dep.ext_deps, state, depends, include_rpath, use_gir_args) cflags.update(extdepflags[0]) - ldflags.update(extdepflags[1]) - gi_includes.update(extdepflags[2]) + internal_ldflags.update(extdepflags[1]) + external_ldflags.update(extdepflags[2]) + gi_includes.update(extdepflags[3]) for source in dep.sources: if hasattr(source, 'held_object'): source = source.held_object @@ -351,9 +354,9 @@ class GnomeModule(ExtensionModule): # For PkgConfigDependency only: getattr(dep, 'is_libtool', False)): lib_dir = os.path.dirname(lib) - ldflags.update(["-L%s" % lib_dir]) + external_ldflags.update(["-L%s" % lib_dir]) if include_rpath: - ldflags.update(['-Wl,-rpath {}'.format(lib_dir)]) + external_ldflags.update(['-Wl,-rpath {}'.format(lib_dir)]) libname = os.path.basename(lib) if libname.startswith("lib"): libname = libname[3:] @@ -362,7 +365,7 @@ class GnomeModule(ExtensionModule): # Hack to avoid passing some compiler options in if lib.startswith("-W"): continue - ldflags.update([lib]) + external_ldflags.update([lib]) if isinstance(dep, PkgConfigDependency): girdir = dep.get_pkgconfig_variable("girdir", {'default': ''}) @@ -376,14 +379,17 @@ class GnomeModule(ExtensionModule): continue if gir_has_extra_lib_arg(self.interpreter) and use_gir_args: - fixed_ldflags = OrderedSet() - for ldflag in ldflags: - if ldflag.startswith("-l"): - fixed_ldflags.add(ldflag.replace('-l', '--extra-library=', 1)) - else: - fixed_ldflags.add(ldflag) - ldflags = fixed_ldflags - return cflags, ldflags, gi_includes + def fix_ldflags(ldflags): + fixed_ldflags = OrderedSet() + for ldflag in ldflags: + if ldflag.startswith("-l"): + fixed_ldflags.add(ldflag.replace('-l', '--extra-library=', 1)) + else: + fixed_ldflags.add(ldflag) + return fixed_ldflags + internal_ldflags = fix_ldflags(internal_ldflags) + external_ldflags = fix_ldflags(external_ldflags) + return cflags, internal_ldflags, external_ldflags, gi_includes @FeatureNewKwargs('build target', '0.40.0', ['build_by_default']) @permittedKwargs({'sources', 'nsversion', 'namespace', 'symbol_prefix', 'identifier_prefix', @@ -487,7 +493,8 @@ class GnomeModule(ExtensionModule): 'Gir includes must be str, GirTarget, or list of them') cflags = [] - ldflags = [] + internal_ldflags = [] + external_ldflags = [] for lang, compiler in girtarget.compilers.items(): # XXX: Can you use g-i with any other language? if lang in ('c', 'cpp', 'objc', 'objcpp', 'd'): @@ -504,7 +511,7 @@ class GnomeModule(ExtensionModule): sanitize = state.environment.coredata.base_options['b_sanitize'].value cflags += compilers.sanitizer_compile_args(sanitize) if 'address' in sanitize.split(','): - ldflags += ['-lasan'] + external_ldflags += ['-lasan'] # FIXME: Linking directly to libasan is not recommended but g-ir-scanner # does not understand -f LDFLAGS. https://bugzilla.gnome.org/show_bug.cgi?id=783892 # ldflags += compilers.sanitizer_link_args(sanitize) @@ -565,10 +572,11 @@ class GnomeModule(ExtensionModule): # ldflags will be misinterpreted by gir scanner (showing # spurious dependencies) but building GStreamer fails if they # are not used here. - dep_cflags, dep_ldflags, gi_includes = self._get_dependencies_flags(deps, state, depends, - use_gir_args=True) + dep_cflags, dep_internal_ldflags, dep_external_ldflags, gi_includes = \ + self._get_dependencies_flags(deps, state, depends, use_gir_args=True) cflags += list(dep_cflags) - ldflags += list(dep_ldflags) + internal_ldflags += list(dep_internal_ldflags) + external_ldflags += list(dep_external_ldflags) scan_command += ['--cflags-begin'] scan_command += cflags scan_command += state.environment.coredata.get_external_args(lang) @@ -578,7 +586,7 @@ class GnomeModule(ExtensionModule): # ones. if isinstance(girtarget, build.SharedLibrary): scan_command += ["-L@PRIVATE_OUTDIR_ABS_%s@" % girtarget.get_id()] - scan_command += list(ldflags) + scan_command += list(internal_ldflags) for i in gi_includes: scan_command += ['--add-include-path=%s' % i] @@ -606,6 +614,7 @@ class GnomeModule(ExtensionModule): for link_arg in state.environment.coredata.get_external_link_args(lang): if link_arg.startswith('-L'): scan_command.append(link_arg) + scan_command += list(external_ldflags) scankwargs = {'output': girfile, 'command': scan_command, @@ -832,7 +841,8 @@ This will become a hard error in the future.''') def _get_build_args(self, kwargs, state, depends): args = [] deps = extract_as_list(kwargs, 'dependencies', unholder=True) - cflags, ldflags, gi_includes = self._get_dependencies_flags(deps, state, depends, include_rpath=True) + cflags, internal_ldflags, external_ldflags, gi_includes = \ + self._get_dependencies_flags(deps, state, depends, include_rpath=True) inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories') for incd in inc_dirs: if not isinstance(incd.held_object, (str, build.IncludeDirs)): @@ -840,7 +850,10 @@ This will become a hard error in the future.''') 'Gir include dirs should be include_directories().') cflags.update(get_include_args(inc_dirs)) cflags.update(state.environment.coredata.get_external_args('c')) + ldflags = OrderedSet() + ldflags.update(internal_ldflags) ldflags.update(state.environment.coredata.get_external_link_args('c')) + ldflags.update(external_ldflags) if cflags: args += ['--cflags=%s' % ' '.join(cflags)] if ldflags: diff --git a/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c new file mode 100644 index 0000000..fae9c38 --- /dev/null +++ b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c @@ -0,0 +1,6 @@ +#include "fake-gthread.h" + +int fake_gthread_fake_function (void) +{ + return 7; +} diff --git a/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h new file mode 100644 index 0000000..52b5472 --- /dev/null +++ b/test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h @@ -0,0 +1,6 @@ +#ifndef FAKE_GTHREAD_H +#define FAKE_GTHREAD_H + +int fake_gthread_fake_function (void); + +#endif /* FAKE_GTHREAD_H */ diff --git a/test cases/frameworks/22 gir link order/fake-gthread/meson.build b/test cases/frameworks/22 gir link order/fake-gthread/meson.build new file mode 100644 index 0000000..693e8e0 --- /dev/null +++ b/test cases/frameworks/22 gir link order/fake-gthread/meson.build @@ -0,0 +1,12 @@ +fake_gthread_sources = ['fake-gthread.c', 'fake-gthread.h'] +fake_gthread_lib = shared_library( + 'gthread-2.0', + sources : fake_gthread_sources, + install : false, +) + +fake_gthread_includes = include_directories('.') +fake_gthread = declare_dependency( + include_directories : fake_gthread_includes, + link_with : fake_gthread_lib, +) diff --git a/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c new file mode 100644 index 0000000..356b45e --- /dev/null +++ b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.c @@ -0,0 +1,8 @@ +#include "get-prgname.h" + +#include <glib.h> + +const char *get_prgname_get_name (void) +{ + return g_get_prgname (); +} diff --git a/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h new file mode 100644 index 0000000..cb5118e --- /dev/null +++ b/test cases/frameworks/22 gir link order/get-prgname/get-prgname.h @@ -0,0 +1,6 @@ +#ifndef GET_PRGNAME_H +#define GET_PRGNAME_H + +const char *get_prgname_get_name (void); + +#endif /* GET_PRGNAME_H */ diff --git a/test cases/frameworks/22 gir link order/get-prgname/meson.build b/test cases/frameworks/22 gir link order/get-prgname/meson.build new file mode 100644 index 0000000..6a7489d --- /dev/null +++ b/test cases/frameworks/22 gir link order/get-prgname/meson.build @@ -0,0 +1,13 @@ +get_prgname_sources = ['get-prgname.c', 'get-prgname.h'] +get_prgname_lib = shared_library( + 'get-prgname', + sources : get_prgname_sources, + dependencies : [glib], + install : false, +) + +get_prgname_includes = include_directories('.') +get_prgname = declare_dependency( + include_directories : get_prgname_includes, + link_with : get_prgname_lib, +) diff --git a/test cases/frameworks/22 gir link order/meson-sample.c b/test cases/frameworks/22 gir link order/meson-sample.c new file mode 100644 index 0000000..7c6442a --- /dev/null +++ b/test cases/frameworks/22 gir link order/meson-sample.c @@ -0,0 +1,48 @@ +#include "meson-sample.h" + +#include "get-prgname.h" +#include "fake-gthread.h" + +struct _MesonSample { + GObject parent_instance; +}; + +G_DEFINE_TYPE (MesonSample, meson_sample, G_TYPE_OBJECT) + +/** + * meson_sample_new: + * + * Allocates a new #MesonSample. + * + * Returns: (transfer full): a #MesonSample. + */ +MesonSample * +meson_sample_new (void) +{ + return g_object_new (MESON_TYPE_SAMPLE, NULL); +} + +static void +meson_sample_class_init (MesonSampleClass *klass) +{ +} + +static void +meson_sample_init (MesonSample *self) +{ +} + +/** + * meson_sample_print_message: + * @self: a #MesonSample. + * + * Prints a message. + */ +void +meson_sample_print_message (MesonSample *self) +{ + g_return_if_fail (MESON_IS_SAMPLE (self)); + + g_print ("Message: %s\n", get_prgname_get_name ()); + g_print ("Message: %d\n", fake_gthread_fake_function ()); +} diff --git a/test cases/frameworks/22 gir link order/meson-sample.h b/test cases/frameworks/22 gir link order/meson-sample.h new file mode 100644 index 0000000..2c28401 --- /dev/null +++ b/test cases/frameworks/22 gir link order/meson-sample.h @@ -0,0 +1,17 @@ +#ifndef MESON_SAMPLE_H +#define MESON_SAMPLE_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define MESON_TYPE_SAMPLE (meson_sample_get_type()) + +G_DECLARE_FINAL_TYPE (MesonSample, meson_sample, MESON, SAMPLE, GObject) + +MesonSample *meson_sample_new (void); +void meson_sample_print_message (MesonSample *self); + +G_END_DECLS + +#endif /* MESON_SAMPLE_H */ diff --git a/test cases/frameworks/22 gir link order/meson.build b/test cases/frameworks/22 gir link order/meson.build new file mode 100644 index 0000000..224eaf6 --- /dev/null +++ b/test cases/frameworks/22 gir link order/meson.build @@ -0,0 +1,41 @@ +project('gir link order', 'c') + +if not dependency('glib-2.0', required : false).found() + error('MESON_SKIP_TEST glib not found.') +endif + +gnome = import('gnome') +glib = dependency('glib-2.0') +gobject = dependency('gobject-2.0') + +# get-prgname is a shared library which uses a function from glib-2.0. It is +# used to introduce external -L flags which may cause -L order problems. +subdir('get-prgname') + +# fake-gthread is a shared library which has the same name as gthread-2.0 from +# GLib. This is used to simulate the case where an older or unrelated version +# of a library is already installed on the system. Our meson sample library +# defined below uses a function from fake-gthread. If meson messes up -L order, +# the linker will find libgthread-2.0.so installed on the system and fail to +# find the symbol our meson sample library uses. +subdir('fake-gthread') + +meson_sample_sources = ['meson-sample.c', 'meson-sample.h'] +meson_sample_lib = shared_library( + 'sample', + sources : meson_sample_sources, + dependencies : [gobject, get_prgname, fake_gthread], + install : false, +) + +gnome.generate_gir( + meson_sample_lib, + sources : meson_sample_sources, + nsversion : '1.0', + namespace : 'Meson', + symbol_prefix : 'meson', + identifier_prefix : 'Meson', + includes : ['GObject-2.0'], + install : false, + build_by_default: true, +) |