Skip to content

Commit

Permalink
Update depfixer to fix rpaths also on OSX.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpakkane committed Apr 8, 2018
1 parent 269db40 commit aed11af
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
60 changes: 51 additions & 9 deletions mesonbuild/scripts/depfixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


import sys, struct
import shutil, subprocess

SHT_STRTAB = 3
DT_NEEDED = 1
Expand Down Expand Up @@ -337,20 +338,61 @@ def remove_rpath_entry(self, entrynum):
entry.write(self.bf)
return None

def fix_elf(fname, new_rpath, verbose=True):
with Elf(fname, verbose) as e:
if new_rpath is None:
e.print_rpath()
e.print_runpath()
else:
e.fix_rpath(new_rpath)

def get_darwin_rpaths_to_remove(fname):
out = subprocess.check_output(['otool', '-l', fname], universal_newlines=True)
result = []
current_cmd = 'FOOBAR'
for line in out.split('\n'):
if ' ' not in line:
continue
key, value = line.strip().split(' ', 1)
if key == 'cmd':
current_cmd = value
if key == 'path' and current_cmd == 'LC_RPATH':
rp = value.split('(', 1)[0].strip()
result.append(rp)
return result

def fix_darwin(fname, new_rpath):
try:
for rp in get_darwin_rpaths_to_remove(fname):
subprocess.check_call(['install_name_tool', '-delete_rpath', rp, fname])
if new_rpath != '':
subprocess.check_call(['install_name_tool', '-add_rpath', new_rpath, fname])
except Exception as e:
raise
sys.exit(0)

def fix_rpath(fname, new_rpath, verbose=True):
try:
fix_elf(fname, new_rpath, verbose)
return 0
except SystemExit as e:
if isinstance(e.code, int) and e.code == 0:
pass
else:
raise
if shutil.which('install_name_tool'):
fix_darwin(fname, new_rpath)
return 0

def run(args):
if len(args) < 1 or len(args) > 2:
print('This application resets target rpath.')
print('Don\'t run this unless you know what you are doing.')
print('%s: <binary file> <prefix>' % sys.argv[0])
sys.exit(1)
with Elf(args[0]) as e:
if len(args) == 1:
e.print_rpath()
e.print_runpath()
else:
new_rpath = args[1]
e.fix_rpath(new_rpath)
return 0
fname = args[0]
new_rpath = None if len(args) == 1 else args[1]
return fix_rpath(fname, new_rpath)

if __name__ == '__main__':
run(sys.argv[1:])
sys.exit(run(sys.argv[1:]))
3 changes: 1 addition & 2 deletions mesonbuild/scripts/meson_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,7 @@ def install_targets(d):
printed_symlink_error = True
if is_elf_platform() and os.path.isfile(outname):
try:
e = depfixer.Elf(outname, False)
e.fix_rpath(install_rpath)
depfixer.fix_rpath(outname, install_rpath, False)
except SystemExit as e:
if isinstance(e.code, int) and e.code == 0:
pass
Expand Down

1 comment on commit aed11af

@bredelings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the depfixer.fix_rpath( ) run on OS X? Because is_elf_platform( ) should be false, right?

Please sign in to comment.