Add an rpath entry to shared libraries that are linked from the source tree.

pull/2397/head
Jussi Pakkanen 7 years ago
parent ac79eebc2f
commit a655b64989
  1. 17
      mesonbuild/backend/backends.py
  2. 39
      run_unittests.py
  3. 6
      test cases/unit/16 prebuilt shared/alexandria.c
  4. 20
      test cases/unit/16 prebuilt shared/alexandria.h
  5. 10
      test cases/unit/16 prebuilt shared/another_visitor.c
  6. 14
      test cases/unit/16 prebuilt shared/meson.build
  7. 8
      test cases/unit/16 prebuilt shared/patron.c

@ -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…
Cancel
Save