Rpaths start working.

pull/15/head
Jussi Pakkanen 11 years ago
parent 2e656bce02
commit 3673791b4f
  1. 3
      backends.py
  2. 12
      build.py
  3. 33
      depfixer.py
  4. 18
      environment.py
  5. 5
      test cases/common/46 library chain/main.c
  6. 5
      test cases/common/46 library chain/meson.build
  7. 6
      test cases/common/46 library chain/subdir/lib1.c
  8. 4
      test cases/common/46 library chain/subdir/meson.build
  9. 3
      test cases/common/46 library chain/subdir/subdir2/lib2.c
  10. 1
      test cases/common/46 library chain/subdir/subdir2/meson.build
  11. 3
      test cases/common/46 library chain/subdir/subdir3/lib3.c
  12. 1
      test cases/common/46 library chain/subdir/subdir3/meson.build

@ -225,7 +225,6 @@ class Backend():
if compiler.id == 'msvc': if compiler.id == 'msvc':
if fname.endswith('dll'): if fname.endswith('dll'):
fname = fname[:-3] + 'lib' fname = fname[:-3] + 'lib'
fname = os.path.join('.', fname) # Hack to make ldd find the library.
args.append(fname) args.append(fname)
return args return args
@ -852,6 +851,7 @@ class NinjaBackend(Backend):
elif isinstance(target, build.SharedLibrary): elif isinstance(target, build.SharedLibrary):
commands += linker.get_std_shared_lib_link_flags() commands += linker.get_std_shared_lib_link_flags()
commands += linker.get_pic_flags() commands += linker.get_pic_flags()
commands += linker.get_soname_flags(target.name)
elif isinstance(target, build.StaticLibrary): elif isinstance(target, build.StaticLibrary):
commands += linker.get_std_link_flags() commands += linker.get_std_link_flags()
else: else:
@ -860,6 +860,7 @@ class NinjaBackend(Backend):
commands += dep.get_link_flags() commands += dep.get_link_flags()
dependencies = target.get_dependencies() dependencies = target.get_dependencies()
commands += self.build_target_link_arguments(linker, dependencies) commands += self.build_target_link_arguments(linker, dependencies)
commands.append(linker.build_rpath_arg(self.environment.get_build_dir(), target.get_rpaths()))
if self.environment.coredata.coverage: if self.environment.coredata.coverage:
commands += linker.get_coverage_link_flags() commands += linker.get_coverage_link_flags()
dep_targets = [self.get_dependency_filename(t) for t in dependencies] dep_targets = [self.get_dependency_filename(t) for t in dependencies]

@ -143,6 +143,15 @@ class BuildTarget():
newd.append(i) newd.append(i)
self.kwargs['deps'] = newd self.kwargs['deps'] = newd
def get_rpaths(self):
return self.get_transitive_rpaths()
def get_transitive_rpaths(self):
result = []
for i in self.link_targets:
result += i.get_rpaths()
return result
def process_kwargs(self, kwargs): def process_kwargs(self, kwargs):
self.copy_kwargs(kwargs) self.copy_kwargs(kwargs)
kwargs.get('modules', []) kwargs.get('modules', [])
@ -404,6 +413,9 @@ class SharedLibrary(BuildTarget):
def get_shbase(self): def get_shbase(self):
return self.prefix + self.name + '.' + self.suffix return self.prefix + self.name + '.' + self.suffix
def get_rpaths(self):
return [self.subdir] + self.get_transitive_rpaths()
def get_filename(self): def get_filename(self):
fname = self.get_shbase() fname = self.get_shbase()
if self.version is None: if self.version is None:

@ -187,6 +187,17 @@ class Elf():
self.bf.seek(strtab.val + soname.val) self.bf.seek(strtab.val + soname.val)
print(self.read_str()) print(self.read_str())
def get_rpath_offset(self):
sec = self.find_section(b'.dynstr')
for i in self.dynamic:
if i.d_tag == DT_RPATH:
rpath = i
return sec.sh_offset + rpath.val
def print_rpath(self):
self.bf.seek(self.get_rpath_offset())
print(self.read_str())
def print_deps(self): def print_deps(self):
sec = self.find_section(b'.dynstr') sec = self.find_section(b'.dynstr')
deps = [] deps = []
@ -217,14 +228,26 @@ class Elf():
self.bf.seek(offset) self.bf.seek(offset)
self.bf.write(newname) self.bf.write(newname)
def fix_rpath(self, new_rpath):
rp_off = self.get_rpath_offset()
self.bf.seek(rp_off)
old_rpath = self.read_str()
if len(old_rpath) < len(new_rpath):
print("New rpath must not be longer than the old one.")
self.bf.seek(rp_off)
self.bf.write(new_rpath)
self.bf.write(b'\0'*(len(old_rpath) - len(new_rpath) + 1))
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) != 3: if len(sys.argv) < 2 or len(sys.argv) > 3:
print('This application converts absolute dep paths to relative ones.') print('This application resets target rpath.')
print('Don\'t run this unless you know what you are doing.') print('Don\'t run this unless you know what you are doing.')
print('%s: <binary file> <prefix>' % sys.argv[0]) print('%s: <binary file> <prefix>' % sys.argv[0])
exit(1) exit(1)
e = Elf(sys.argv[1]) e = Elf(sys.argv[1])
prefix = sys.argv[2] if len(sys.argv) == 2:
#e.print_deps() e.print_rpath()
e.fix_deps(prefix.encode()) else:
new_rpath = sys.argv[2]
e.fix_rpath(new_rpath.encode('utf8'))
#e.fix_deps(prefix.encode())

@ -56,6 +56,15 @@ class CCompiler():
def get_always_flags(self): def get_always_flags(self):
return [] return []
def get_soname_flags(self, shlib_name):
return []
def split_shlib_to_parts(self, fname):
return (None, fname)
def build_rpath_arg(self, build_dir, rpath_paths):
return ''
def get_id(self): def get_id(self):
return self.id return self.id
@ -503,6 +512,15 @@ class GnuCCompiler(CCompiler):
def get_pch_suffix(self): def get_pch_suffix(self):
return 'gch' return 'gch'
def split_shlib_to_parts(self, fname):
return (os.path.split(fname)[0], fname)
def build_rpath_arg(self, build_dir, rpath_paths):
return '-Wl,-rpath,' + ':'.join([os.path.join(build_dir, p) for p in rpath_paths])
def get_soname_flags(self, shlib_name):
return ['-Wl,-soname,lib%s.so' % shlib_name]
class GnuObjCCompiler(ObjCCompiler): class GnuObjCCompiler(ObjCCompiler):
std_warn_flags = ['-Wall', '-Winvalid-pch'] std_warn_flags = ['-Wall', '-Winvalid-pch']
std_opt_flags = ['-O2'] std_opt_flags = ['-O2']

@ -0,0 +1,5 @@
int libfun();
int main() {
return libfun();
}

@ -0,0 +1,5 @@
project('libchain', 'c')
subdir('subdir')
e = executable('prog', 'main.c', link_with : lib1)
test('tst', e)

@ -0,0 +1,6 @@
int lib2fun();
int lib3fun();
int libfun() {
return lib2fun() + lib3fun();
}

@ -0,0 +1,4 @@
subdir('subdir2')
subdir('subdir3')
lib1 = shared_library('lib1', 'lib1.c', link_with : [lib2, lib3])

@ -0,0 +1 @@
lib2 = shared_library('lib2', 'lib2.c')

@ -0,0 +1 @@
lib3 = shared_library('lib3', 'lib3.c')
Loading…
Cancel
Save