depfixer: Rewrite install_name for dylibs on install

The install name is used by consumers of the library to find the
library at runtime. If it's @rpath/libfoo.dylib, all consumers must
manually add the library path to RPATH, which is not what people
expect.

Almost everyone sets the library install name as the full path to the
library, and this is done at install time with install_name_tool.
pull/3750/head
Nirbheek Chauhan 7 years ago committed by Nirbheek Chauhan
parent e3757e3d3c
commit 69f817b0e3
  1. 22
      mesonbuild/scripts/depfixer.py
  2. 4
      mesonbuild/scripts/meson_install.py

@ -364,7 +364,7 @@ def get_darwin_rpaths_to_remove(fname):
result.append(rp) result.append(rp)
return result return result
def fix_darwin(fname, new_rpath): def fix_darwin(fname, new_rpath, final_path):
try: try:
rpaths = get_darwin_rpaths_to_remove(fname) rpaths = get_darwin_rpaths_to_remove(fname)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
@ -372,30 +372,38 @@ def fix_darwin(fname, new_rpath):
# non-executable target. Just return. # non-executable target. Just return.
return return
try: try:
args = []
if rpaths: if rpaths:
args = []
for rp in rpaths: for rp in rpaths:
args += ['-delete_rpath', rp] args += ['-delete_rpath', rp]
subprocess.check_call(['install_name_tool', fname] + args, subprocess.check_call(['install_name_tool', fname] + args,
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL) stderr=subprocess.DEVNULL)
args = []
if new_rpath: if new_rpath:
subprocess.check_call(['install_name_tool', '-add_rpath', new_rpath, fname], args += ['-add_rpath', new_rpath]
# Rewrite -install_name @rpath/libfoo.dylib to /path/to/libfoo.dylib
if fname.endswith('dylib'):
args += ['-id', final_path]
if args:
subprocess.check_call(['install_name_tool', fname] + args,
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL) stderr=subprocess.DEVNULL)
except Exception as e: except Exception as e:
raise raise
sys.exit(0) sys.exit(0)
def fix_rpath(fname, new_rpath, verbose=True): def fix_rpath(fname, new_rpath, final_path, verbose=True):
# Static libraries never have rpaths
if fname.endswith('.a'):
return
try: try:
fix_elf(fname, new_rpath, verbose) fix_elf(fname, new_rpath, verbose)
return 0 return
except SystemExit as e: except SystemExit as e:
if isinstance(e.code, int) and e.code == 0: if isinstance(e.code, int) and e.code == 0:
pass pass
else: else:
raise raise
if shutil.which('install_name_tool'): if shutil.which('install_name_tool'):
fix_darwin(fname, new_rpath) fix_darwin(fname, new_rpath, final_path, install_name_mappings)
return 0

@ -363,6 +363,7 @@ def install_targets(d):
fname = check_for_stampfile(t[0]) fname = check_for_stampfile(t[0])
outdir = get_destdir_path(d, t[1]) outdir = get_destdir_path(d, t[1])
outname = os.path.join(outdir, os.path.basename(fname)) outname = os.path.join(outdir, os.path.basename(fname))
final_path = os.path.join(d.prefix, outname)
aliases = t[2] aliases = t[2]
should_strip = t[3] should_strip = t[3]
install_rpath = t[4] install_rpath = t[4]
@ -414,7 +415,8 @@ def install_targets(d):
printed_symlink_error = True printed_symlink_error = True
if os.path.isfile(outname): if os.path.isfile(outname):
try: try:
depfixer.fix_rpath(outname, install_rpath, False) depfixer.fix_rpath(outname, install_rpath, final_path,
verbose=False)
except SystemExit as e: except SystemExit as e:
if isinstance(e.code, int) and e.code == 0: if isinstance(e.code, int) and e.code == 0:
pass pass

Loading…
Cancel
Save