Home / Alt manpages / llvm-install-name-tool-18(1)

  • llvm-install-name-tool-18(1)
  • User command
  • linux

Repair Mach-O Library Paths Safely with llvm-install-name-tool-18

You can use llvm-install-name-tool-18 to change a Mach-O executable or shared library's dependency paths, install name, or runtime search paths. This is useful when a packaged macOS binary points at the wrong library location, even when the repair is being prepared on a Linux build host. The command edits the binary, so make a copy first and verify the result before handing it to a release process.

These steps use Ubuntu's llvm-18 package, installed here as version 18.1.3. Allow about 10 minutes if you already have the Mach-O file and its intended paths. You need a writable working copy, enough space for a backup, and a tool that can inspect Mach-O load commands. The examples use llvm-otool-18 if it is installed; use Apple's otool on macOS.

Checkpoint: confirm the tool and input format

  1. Check the installed version and make sure the input is a Mach-O file.

    llvm-install-name-tool-18 --version
    file ./app-or-library
    

On this package, the first command reports Ubuntu LLVM version 18.1.3. The second command should identify a Mach-O executable, dynamically linked shared library, or another Mach-O object. An ELF file from an ordinary Linux build is the wrong input and cannot be repaired with this tool.

Checkpoint: record the current load commands

  1. Save the current dependency and rpath information before editing.

    llvm-otool-18 -L ./app-or-library
    llvm-otool-18 -l ./app-or-library | grep -A3 -E 'LC_RPATH|LC_ID_DYLIB'
    

If llvm-otool-18 is not present, run the equivalent inspection command on a macOS machine and copy its output into the change record. The first command lists install names used for dependent shared libraries. The load-command view is useful for confirming an existing rpath or the identification name of a shared library. Do not guess an old value: -change and -rpath match the exact string stored in the binary.

Checkpoint: create a recoverable working copy

  1. Copy the file and keep the original untouched.

    cp --preserve=all ./app-or-library ./app-or-library.before-install-name-tool
    cp --preserve=all ./app-or-library ./app-or-library.work
    

The tool updates its input in place. Work on *.work, then compare it with the saved original. If the result is wrong, undo it by replacing the work file with the backup:

cp --preserve=all ./app-or-library.before-install-name-tool ./app-or-library.work

This is the recovery step. Do not run the replacement command against a path you have not checked, and do not delete the backup until the repaired binary has passed its consumer's tests.

Change one dependency install name

  1. Replace an exact old dependency path with its new path.

    llvm-install-name-tool-18 \
      -change /old/prefix/lib/libWidget.dylib \
              /new/prefix/lib/libWidget.dylib \
      ./app-or-library.work
    

You can provide -change more than once for several dependencies. If the old install name is not present, the option is ignored, so inspect the output again rather than assuming a successful-looking command made a change. The tool's exit code is zero when it accepts the operation and non-zero when it encounters an error; it does not turn a missing -change match into an error.

Manage rpaths without guessing

Use -add_rpath to add a search path, -delete_rpath to remove one, and -rpath to replace one exact rpath with another:

llvm-install-name-tool-18 -add_rpath /new/prefix/lib ./app-or-library.work
llvm-install-name-tool-18 -rpath /old/prefix/lib /new/prefix/lib ./app-or-library.work
llvm-install-name-tool-18 -delete_rpath /unused/prefix/lib ./app-or-library.work

Run only the operation that matches the state you recorded. Adding an rpath that is already listed, deleting one that is absent, or replacing an absent old rpath causes an error. A replacement also fails when the new rpath is already present. The manpage permits these rpath operations to be combined only when they do not share the same rpath value.

Destructive warning: -delete_all_rpaths removes every rpath from the binary. Treat it as a release-impacting change. Use it only when you have confirmed that every dependency is otherwise discoverable, and retain the original backup.

Change a shared library's identification name

For a dynamic shared library, -id changes the name stored under LC_ID_DYLIB:

llvm-install-name-tool-18 \
  -id /new/prefix/lib/libWidget.dylib \
  ./libWidget.dylib.work

This option is ignored when the input is not a dynamic shared library. If you specify -id more than once, only the last value is selected. It does not rewrite the dependency entries in other binaries, so update those separately with -change where required.

Verify the edited file

  1. Inspect the work file and compare it with the original.

    llvm-otool-18 -L ./app-or-library.work
    diff -u ./app-or-library.before-install-name-tool ./app-or-library.work
    file ./app-or-library.work
    

Confirm that the intended path appears, that an unwanted old path is gone when it should be, and that the file remains the expected Mach-O type. Then run the program or package's normal test suite on the work file. A zero exit status from the editing command proves only that the requested edit was accepted; it does not prove that the loader can find every library at runtime.

Version and common traps

The installed LLVM 18.1.3 executable also advertises -prepend_rpath, -o, --output, and @FILE in its live help. They are not described in the installed llvm-install-name-tool-18(1) manpage, so this guide stays with the documented interface. Check llvm-install-name-tool-18 --help on the exact package used by your build before relying on those extensions.

Do not confuse a Linux ELF binary with a Mach-O file, a dependency install name with an rpath, or a successful process exit with a verified runtime load. Quote paths containing spaces, keep edits on a copy, and make the backup part of the release record.

Done means

  • The input was confirmed as Mach-O and the tool version was recorded.
  • The original file remains available as a backup.
  • Every changed install name or rpath was matched against recorded load-command output.
  • The edited file still has the expected Mach-O type and passes the consuming program's tests.
  • The backup is retained until the repaired artefact is accepted.