Add an rpath entry to shared libraries that are linked from the source tree.
This commit is contained in:
parent
ac79eebc2f
commit
a655b64989
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
@ -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();
|
||||
}
|
Loading…
Reference in New Issue