Skip to content

Instantly share code, notes, and snippets.

@EasyIP2023
Last active May 16, 2026 21:29
Show Gist options
  • Select an option

  • Save EasyIP2023/0c91d15aa6582e09f0677195378ea5b9 to your computer and use it in GitHub Desktop.

Select an option

Save EasyIP2023/0c91d15aa6582e09f0677195378ea5b9 to your computer and use it in GitHub Desktop.
MacOS update rpath on binary
#!/bin/bash
##########################################################################################################################################
# https://zditect.com/blog/53084068.html
# On the Mac a dynamic library (dylib) has an "install name". The install name is a path
# baked into the dynamic library that says where to find the library at runtime. When you
# link against the dylib this path is saved in your binary so that your binary can find the
# dylib at runtime.
# If the given binary is a dylib
# install_name_tool -id @rpath/<libname> will update the LC_ID_DYLIB (install name) of
# library to @rpath/<libname>.<version>.dylib. The @rpath of each binary is set to
# @loader_path/../lib via instal_name_tool -add_rpath @loader_path/../lib "${BINARY}".
# We then run otool -l to get a list of dylib's associated with binary. Then we cycle
# through that list updating the path to library if prefix doesn't contain
# @rpath, /usr/lib, or /usr/local/lib.
# Example
# $ otool -L working/build_output/lib/libavdevice.58.10.100.dylib
# /../../../../../working/build_output/lib/libavdevice.58.10.100.dylib (compatibility version 58.0.0, current version 58.10.100)
# /../../../../../working/build_output/lib/libavfilter.7.dylib (compatibility version 7.0.0, current version 7.85.100)
# /../../../../../working/build_output/lib/libswscale.5.dylib (compatibility version 5.0.0, current version 5.7.100)
# /../../../../../working/build_output/lib/libavformat.58.dylib (compatibility version 58.0.0, current version 58.45.100)
# /../../../../../working/build_output/lib/libavcodec.58.dylib (compatibility version 58.0.0, current version 58.91.100)
# /../../../../../working/build_output/lib/libswresample.3.dylib (compatibility version 3.0.0, current version 3.7.100)
# /../../../../../working/build_output/lib/libavresample.4.dylib (compatibility version 4.0.0, current version 4.0.0)
# /../../../../../working/build_output/lib/libavutil.56.dylib (compatibility version 56.0.0, current version 56.51.100)
# /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1858.112.0)
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
# libopus.0.8.0.dylib
# libkvazaar.6.dylib
# ......
# ......
# ......
# ......
# ......
#
# Updates to
# $ otool -L working/build_output/lib/libavdevice.58.10.100.dylib
# @rpath/libavdevice.58.10.100.dylib (compatibility version 58.0.0, current version 58.10.100)
# @rpath/libavfilter.7.dylib (compatibility version 7.0.0, current version 7.85.100)
# @rpath/libswscale.5.dylib (compatibility version 5.0.0, current version 5.7.100)
# @rpath/libavformat.58.dylib (compatibility version 58.0.0, current version 58.45.100)
# @rpath/libavcodec.58.dylib (compatibility version 58.0.0, current version 58.91.100)
# @rpath/libswresample.3.dylib (compatibility version 3.0.0, current version 3.7.100)
# @rpath/libavresample.4.dylib (compatibility version 4.0.0, current version 4.0.0)
# @rpath/libavutil.56.dylib (compatibility version 56.0.0, current version 56.51.100)
# /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1858.112.0)
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
# @rpath/libopus.0.8.0.dylib
# @rpath/libkvazaar.6.dylib
# ......
# ......
# ......
# ......
# ......
##########################################################################################################################################
BINARY="$1"
BINARY_NAME="$(echo "${BINARY}" | sed 's/.*lib\/\(.*dylib\)/\1/')"
instal_name_tool -add_rpath @loader_path/../lib "${BINARY}" || {
echo "[x] install_name_tool: failed to add rpath (LC_RPATH) @loader_path/../lib to of ${BINARY}\n"
exit 1
}
[[ "${BINARY:${#BINARY}-5}" == "dylib" ]] && {
install_name_tool -id @rpath/${BINARY_NAME} "${BINARY}" || {
echo "[x] install_name_tool: failed to change LC_ID_DYLIB of ${BINARY_NAME} to @rpath/${BINARY_NAME}\n"
exit 1
}
}
# aptlib = Absolute Path To lib
libs_paths_to_replace=$(otool -l "${BINARY}" | grep "dylib" | awk '{print $2}')
for aptlib in $libs_paths_to_replace; do
[[ "${aptlib:0:6}" == "@rpath" ]] && continue
[[ "${aptlib:0:5}" == "/usr/" ]] && continue
# Search for name of file between words lib/ and dylib
lib="$(echo "${aptlib}" | sed 's/.*lib\/\(.*dylib\)/\1/')"
install_name_tool -change "${aptlib}" @rpath/${lib} "${BINARY}" || {
echo "[x] install_name_tool: failed to change rpath of ${lib} to @rpath/${lib}\n"
exit 1
}
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment