From 539665a7ddd707d994047d1cde37f6978dd4eeef Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Mon, 24 Oct 2022 15:00:53 -0700 Subject: [PATCH] Use otool to read dylib install name When linking an executable on darwin, cc_wrapper.sh contains functionality to ensure rpath entries and shared library install names are relative and match the intended paths that will be used in downstream actions. This depends on being able to traverse symlinks from the _solibs path (like _solib_darwin_x86_64/_U_S_S_Cgenlib_Uimport___U/libgenlib.so) to the actual file (like bazel-out/darwin-opt-exec-31C2CD59/bin/libgenlib.so). This also assumes that the library has its internal install name equal to that latter path - this seems to be generally true right now, but is maybe a bit brittle. This system breaks down when doing linking on a remote executor, because Bazel does not encode symlinks, and so the file shows up in _solib_darwin_x86_64 as a real file, and the wrapper picks the wrong install name. The resulting executable works when run directly from bazel-bin/bazel-out on a local machine, but will not work via bazel run, or when used in remote actions. This change uses otool to read the install name of the target library, which is guaranteed to match what was embedded into the executable during link time. This result will be immune to the peculiarities of how symlinks are used and what install_name is encoded into the shared library during its creation. Co-authored-by: John Laxson --- tools/cpp/osx_cc_wrapper.sh.tpl | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tools/cpp/osx_cc_wrapper.sh.tpl b/tools/cpp/osx_cc_wrapper.sh.tpl index ab58d1f1df4fd5..9002c3737ad455 100644 --- a/tools/cpp/osx_cc_wrapper.sh.tpl +++ b/tools/cpp/osx_cc_wrapper.sh.tpl @@ -78,22 +78,9 @@ function get_library_path() { done } -# A convenient method to return the actual path even for non symlinks -# and multi-level symlinks. -function get_realpath() { - local previous="$1" - local next=$(readlink "${previous}") - while [ -n "${next}" ]; do - previous="${next}" - next=$(readlink "${previous}") - done - echo "${previous}" -} - # Get the path of a lib inside a tool function get_otool_path() { - # the lib path is the path of the original lib relative to the workspace - get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|' + /usr/bin/otool -D "$1" | awk 'NR==2{print $1}' | sed 's|^.*/bazel-out/|bazel-out/|' } # Do replacements in the output @@ -116,4 +103,3 @@ for rpath in ${RPATHS}; do fi done done -