Wednesday, July 18, 2012

Fixing dyld image not found on Mac OS

If you've every used command line process and wanted to relocate it you may have run into the error:

dylib: Library not found:
Reason: image not found

You can fix this by doing the following:

  1. Figure out what libraries are dynamically linked to the process using:
    • otool -L process_name
    • Note: You may have to do this for each dynamic library as well and change the paths for the libraries in the dynamic libraries you are linking into your process.  As you can tell this can result in a lot of changes but if you want to move stuff to a new location, it's your best option, as compared to building from source all the required libraries and process.
  2. Change the path of those dynamic libraries using:
    • install_name_tool -change old new process_name

While relocating the library paths for the library I was working with I came up with a pattern of steps to fix this:

Run: otool -L .dylid For example:

otool -L libintl.8.dylib
/opt/local/lib/libintl.8.dylib (compatibility version 10.0.0, current version 10.1.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 635.19.0)
 Then notice that we want to change /opt/local/lib/ to /mypath/lib/.  To do that you need to run:
install_name_tool -change /opt/local/lib/libintl.8.dylib /mypath/lib/libintl.8.dylib /path/to/libintl.8.dylib

This works great until you run into this error:

install_name_tool: changing install names can't be redone for: /mypath/lib/libintl.8.dylib (for architecture i386) because larger updated load commands do not fit (the program must be relinked)
To fix this you need to recompile the library with options to enable the relocation of the library paths.  If the library uses configure then chances are you can add these options to the configure to make it build such that the path for the libraries are relocatable:

  1. Add this to your LDFLAGS=-headerpad_max_install_names
  2. And if available use the configure options: --disable-rpath --enable-relocatable Reference[]
  1. So for example here is an example for libiconv:
./configure --prefix=/mypath/ --disable-rpath --enable-relocatable LDFLAGS=-headerpad_max_install_names


short said...

Hi Mark! First of all, great post! Would you be willing to help me understand what I don't understand here? I recently started doing dev with a mac, so I've never seen this kind of error before!

I get the similar error message when I compile a program linked to 'csfml' dynamic libs:
dyld: Library not loaded: @executable_path/../Frameworks/libsfml-system.2.dylib
Referenced from: /usr/local/lib/libcsfml-system.2.dylib
Reason: image not found

So I tried the following:
install_name_tool -change libcsfml-system.2.dylib /usr/local/lib/libcsfml-system.2.dylib main

But that didn't change the output. In your post you said the last parameter should be the 'path', is it obvious what I am doing wrong?

Mark Thistle said...

Sorry, just saw this.

Is your order for the old lib and new lib in the correct order? Did you try using an absolute path for the old lib path?