aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/modules/gnome.py61
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.c6
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/fake-gthread.h6
-rw-r--r--test cases/frameworks/22 gir link order/fake-gthread/meson.build12
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/get-prgname.c8
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/get-prgname.h6
-rw-r--r--test cases/frameworks/22 gir link order/get-prgname/meson.build13
-rw-r--r--test cases/frameworks/22 gir link order/meson-sample.c48
-rw-r--r--test cases/frameworks/22 gir link order/meson-sample.h17
-rw-r--r--test cases/frameworks/22 gir link order/meson.build41
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,
+)