Last active
May 16, 2026 21:29
-
-
Save EasyIP2023/0c91d15aa6582e09f0677195378ea5b9 to your computer and use it in GitHub Desktop.
MacOS update rpath on binary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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