aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py17
-rwxr-xr-xrun_unittests.py39
-rw-r--r--test cases/unit/16 prebuilt shared/alexandria.c6
-rw-r--r--test cases/unit/16 prebuilt shared/alexandria.h20
-rw-r--r--test cases/unit/16 prebuilt shared/another_visitor.c10
-rw-r--r--test cases/unit/16 prebuilt shared/meson.build14
-rw-r--r--test cases/unit/16 prebuilt shared/patron.c8
7 files changed, 108 insertions, 6 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 12fb3eb..562e467 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -298,6 +298,22 @@ class Backend:
raise MesonException(m.format(target.name))
return l
+ def rpaths_for_bundled_shared_libraries(self, target):
+ paths = []
+ for dep in target.external_deps:
+ if isinstance(dep, dependencies.ExternalLibrary):
+ la = dep.link_args
+ if len(la) == 1 and la[0].startswith(self.environment.get_source_dir()):
+ # The only link argument is an absolute path to a library file.
+ libpath = la[0]
+ if not(libpath.lower().endswith('.dll') or libpath.lower().endswith('.so')):
+ continue
+ absdir = os.path.split(libpath)[0]
+ rel_to_src = absdir[len(self.environment.get_source_dir())+1:]
+ assert(not os.path.isabs(rel_to_src))
+ paths.append(os.path.join(self.build_to_src, rel_to_src))
+ return paths
+
def determine_rpath_dirs(self, target):
link_deps = target.get_all_link_deps()
result = []
@@ -305,6 +321,7 @@ class Backend:
prospective = self.get_target_dir(ld)
if prospective not in result:
result.append(prospective)
+ result += self.rpaths_for_bundled_shared_libraries(target)
return result
def object_filename_from_source(self, target, source, is_unity):
diff --git a/run_unittests.py b/run_unittests.py
index e821152..abff78a 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1304,27 +1304,29 @@ int main(int argc, char **argv) {
else:
object_suffix = 'o'
static_suffix = 'a'
+ shared_suffix = 'so'
if shutil.which('cl'):
compiler = 'cl'
static_suffix = 'lib'
+ shared_suffix = 'dll'
elif shutil.which('cc'):
compiler = 'cc'
elif shutil.which('gcc'):
compiler = 'gcc'
else:
raise RuntimeError("Could not find C compiler.")
- return (compiler, object_suffix, static_suffix)
+ return (compiler, object_suffix, static_suffix, shared_suffix)
- def pbcompile(self, compiler, source, objectfile):
+ def pbcompile(self, compiler, source, objectfile, extra_args=[]):
if compiler == 'cl':
- cmd = [compiler, '/nologo', '/Fo' + objectfile, '/c', source]
+ cmd = [compiler, '/nologo', '/Fo' + objectfile, '/c', source] + extra_args
else:
- cmd = [compiler, '-c', source, '-o', objectfile]
+ cmd = [compiler, '-c', source, '-o', objectfile] + extra_args
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def test_prebuilt_object(self):
- (compiler, object_suffix, _) = self.detect_prebuild_env()
+ (compiler, object_suffix, _, _) = self.detect_prebuild_env()
tdir = os.path.join(self.unit_test_dir, '14 prebuilt object')
source = os.path.join(tdir, 'source.c')
objectfile = os.path.join(tdir, 'prebuilt.' + object_suffix)
@@ -1337,7 +1339,7 @@ int main(int argc, char **argv) {
os.unlink(objectfile)
def test_prebuilt_static_lib(self):
- (compiler, object_suffix, static_suffix) = self.detect_prebuild_env()
+ (compiler, object_suffix, static_suffix, _) = self.detect_prebuild_env()
tdir = os.path.join(self.unit_test_dir, '15 prebuilt static')
source = os.path.join(tdir, 'libdir/best.c')
objectfile = os.path.join(tdir, 'libdir/best.' + object_suffix)
@@ -1358,6 +1360,31 @@ int main(int argc, char **argv) {
finally:
os.unlink(stlibfile)
+ def test_prebuilt_shared_lib(self):
+ (compiler, object_suffix, _, shared_suffix) = self.detect_prebuild_env()
+ tdir = os.path.join(self.unit_test_dir, '16 prebuilt shared')
+ source = os.path.join(tdir, 'alexandria.c')
+ objectfile = os.path.join(tdir, 'alexandria.' + object_suffix)
+ if compiler == 'cl':
+ extra_args = []
+ shlibfile = os.path.join(tdir, 'alexandria.' + shared_suffix)
+ link_cmd = ['link', '/NOLOGO','/DLL', '/DEBUG', '/IMPLIB:alexandria.lib' '/OUT:' + shlibfile, objectfile]
+ else:
+ extra_args = ['-fPIC']
+ shlibfile = os.path.join(tdir, 'libalexandria.' + shared_suffix)
+ link_cmd = [compiler, '-shared', '-o', shlibfile, objectfile, '-Wl,-soname=libalexandria.so']
+ self.pbcompile(compiler, source, objectfile, extra_args=extra_args)
+ try:
+ subprocess.check_call(link_cmd)
+ finally:
+ os.unlink(objectfile)
+ try:
+ self.init(tdir)
+ self.build()
+ self.run_tests()
+ finally:
+ os.unlink(shlibfile)
+
class FailureTests(BasePlatformTests):
'''
Tests that test failure conditions. Build files here should be dynamically
diff --git a/test cases/unit/16 prebuilt shared/alexandria.c b/test cases/unit/16 prebuilt shared/alexandria.c
new file mode 100644
index 0000000..2d6b848
--- /dev/null
+++ b/test cases/unit/16 prebuilt shared/alexandria.c
@@ -0,0 +1,6 @@
+#include"alexandria.h"
+#include<stdio.h>
+
+void alexandria_visit() {
+ printf("You are surrounded by wisdom and knowledge. You feel enlightened.\n");
+}
diff --git a/test cases/unit/16 prebuilt shared/alexandria.h b/test cases/unit/16 prebuilt shared/alexandria.h
new file mode 100644
index 0000000..6e507c5
--- /dev/null
+++ b/test cases/unit/16 prebuilt shared/alexandria.h
@@ -0,0 +1,20 @@
+#pragma once
+
+/* Both funcs here for simplicity. */
+
+#if defined _WIN32 || defined __CYGWIN__
+#if defined BUILDING_DLL
+ #define DLL_PUBLIC __declspec(dllexport)
+#else
+ #define DLL_PUBLIC __declspec(dllimport)
+#endif
+#else
+ #if defined __GNUC__
+ #define DLL_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #pragma message ("Compiler does not support symbol visibility.")
+ #define DLL_PUBLIC
+ #endif
+#endif
+
+void DLL_PUBLIC alexandria_visit();
diff --git a/test cases/unit/16 prebuilt shared/another_visitor.c b/test cases/unit/16 prebuilt shared/another_visitor.c
new file mode 100644
index 0000000..18e5f15
--- /dev/null
+++ b/test cases/unit/16 prebuilt shared/another_visitor.c
@@ -0,0 +1,10 @@
+#include<alexandria.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("Ahh, another visitor. Stay a while.\n");
+ printf("You enter the library.\n\n");
+ alexandria_visit();
+ printf("\nYou decided not to stay forever.\n");
+ return 0;
+}
diff --git a/test cases/unit/16 prebuilt shared/meson.build b/test cases/unit/16 prebuilt shared/meson.build
new file mode 100644
index 0000000..41c11c6
--- /dev/null
+++ b/test cases/unit/16 prebuilt shared/meson.build
@@ -0,0 +1,14 @@
+project('prebuilt shared library', 'c')
+
+cc = meson.get_compiler('c')
+shlib = cc.find_library('alexandria', dirs : meson.current_source_dir())
+
+exe = executable('patron', 'patron.c', dependencies : shlib)
+test('visitation', exe)
+
+d = declare_dependency(dependencies : shlib)
+
+exe2 = executable('another_visitor', 'another_visitor.c',
+ dependencies : d)
+test('another', exe2)
+
diff --git a/test cases/unit/16 prebuilt shared/patron.c b/test cases/unit/16 prebuilt shared/patron.c
new file mode 100644
index 0000000..82d9678
--- /dev/null
+++ b/test cases/unit/16 prebuilt shared/patron.c
@@ -0,0 +1,8 @@
+#include<alexandria.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ printf("You are standing outside the Great Library of Alexandria.\n");
+ printf("You decide to go inside.\n\n");
+ alexandria_visit();
+}