diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 17 | ||||
-rwxr-xr-x | run_unittests.py | 39 | ||||
-rw-r--r-- | test cases/unit/16 prebuilt shared/alexandria.c | 6 | ||||
-rw-r--r-- | test cases/unit/16 prebuilt shared/alexandria.h | 20 | ||||
-rw-r--r-- | test cases/unit/16 prebuilt shared/another_visitor.c | 10 | ||||
-rw-r--r-- | test cases/unit/16 prebuilt shared/meson.build | 14 | ||||
-rw-r--r-- | test cases/unit/16 prebuilt shared/patron.c | 8 |
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(); +} |