Do not try to remove duplicate RPATH entries on macOS
import sys, struct
import shutil, subprocess
+from ..mesonlib import OrderedSet
+
SHT_STRTAB = 3
DT_NEEDED = 1
DT_RPATH = 15
@@ -374,7 +376,26 @@ def fix_darwin(fname, new_rpath, final_path, install_name_mappings):
try:
args = []
if rpaths:
- for rp in rpaths:
+ # TODO: fix this properly, not totally clear how
+ #
+ # removing rpaths from binaries on macOS has tons of
+ # weird edge cases. For instance, if the user provided
+ # a '-Wl,-rpath' argument in LDFLAGS that happens to
+ # coincide with an rpath generated from a dependency,
+ # this would cause installation failures, as meson would
+ # generate install_name_tool calls with two identical
+ # '-delete_rpath' arguments, which install_name_tool
+ # fails on. Because meson itself ensures that it never
+ # adds duplicate rpaths, duplicate rpaths necessarily
+ # come from user variables. The idea of using OrderedSet
+ # is to remove *at most one* duplicate RPATH entry. This
+ # is not optimal, as it only respects the user's choice
+ # partially: if they provided a non-duplicate '-Wl,-rpath'
+ # argument, it gets removed, if they provided a duplicate
+ # one, it remains in the final binary. A potentially optimal
+ # solution would split all user '-Wl,-rpath' arguments from
+ # LDFLAGS, and later add them back with '-add_rpath'.
+ for rp in OrderedSet(rpaths):
args += ['-delete_rpath', rp]
subprocess.check_call(['install_name_tool', fname] + args,
stdout=subprocess.DEVNULL,
@@ -392,7 +413,7 @@ def fix_darwin(fname, new_rpath, final_path, install_name_mappings):
subprocess.check_call(['install_name_tool', fname] + args,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
- except Exception as e:
+ except Exception:
raise
sys.exit(0)
