Re: dyld: "Library not loaded:" Error
Re: dyld: "Library not loaded:" Error
- Subject: Re: dyld: "Library not loaded:" Error
- From: Ken Thomases <email@hidden>
- Date: Fri, 14 Aug 2009 03:50:13 -0500
On Aug 14, 2009, at 12:08 AM, n179911 wrote:
When I run my XCode program, I get this
dyld: Library not loaded: libboost_system-xgcc40-mt-1_39.dylib
Referenced from: /Users/n179911/Documents/ServerXCode/build/Debug/
ServerXCode
Reason: image not found
But I am not sure why I am getting this 'Library not loaded' error.
I have added '/Users/n19911/src/boost_1_39_0/stage/lib' to my 'Library
Search Paths' and I have added '-lboost_system=xgc40-mt' in 'Other
Linker Flags'.
With these, I won't even able to link successfully.
As you note, those two settings are for build time, not run time.
Mac OS X differs from some other platforms. It does not primarily
rely on library search paths to find libraries at load time.
When a binary is linked against a dynamic library, an "install name"
for that library is recorded into the binary. That install name is
treated as a path by the dynamic loader. It usually consists of an
absolute path to the location where the library is to be found at load
time.
Using "otool -L", you can see the install names recorded in a binary.
For example, here's "/usr/bin/true":
$ otool -L /usr/bin/true
/usr/bin/true:
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current
version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current
version 111.0.0)
Note the full paths to libgcc_s and libSystem.
Now, the install name of a library is not necessarily the location
from where it was linked. The install name of a library is something
which is baked into the library by the linker (see the -install_name
option of ld). It can also be modified by install_name_tool with the -
id option. Because the install name of a library can be different
from where it's found at link time, this allows one to work in a non-
final development environment and yet have your programs ready for
eventually being installed to their final locations.
You can use "otool -D" to learn the install name of a library:
$ otool -D /usr/lib/libSystem.dylib
/usr/lib/libSystem.dylib:
/usr/lib/libSystem.B.dylib
Again, note that it's an absolute path.
Now, for some reason, boost seems to build itself with an install name
that's just the name and no path. From the error you show above, it
appears that the install name is just "libboost_system-xgcc40-
mt-1_39.dylib". That means that this just-a-base-name install name is
what is getting baked into your ServerXCode executable. You can use
"otool -L" to see that. There's no path telling the dynamic loader
where to find this library.
You can check the dyld(1) man page to learn how the dynamic loader
searches for libraries. There, you will find out that there are
_some_ search paths involved but, by default, they are only a fallback
mechanism and it's a pretty short list.
For purposes of just testing your program, you could set one of those
DYLD_ environment variables, but that's probably the wrong approach to
solving the larger problem.
If it were your intent to install the boost library to a fixed
location (e.g. /usr/local/lib) on your users' computers, then you
could change the boost build system to set that location as the
install name of the boost library. Then, when your application's
executable were linked against the boost library, it would
automatically pick up the full location on the deployment machine
where it would find the library. However, installing libraries to
fixed locations like this is the exception rather than the rule on the
Mac.
More typically, your application would ship with all non-system
libraries and frameworks on which it depends. These libraries and
frameworks would be included in the application bundle, usually in
Contents/Frameworks, as Dan Ribe said. You would use a Copy Files
build phase to copy the libraries and frameworks there at build time.
But application bundles are inherently moveable. That's one of their
great benefits. That means that the absolute path to any component of
the bundle can't be known in advance. So, to what should you set the
install name of the boost library, if its absolute path can't be known
in advance? You should set it to be executable-relative using an
install name like "@executable_path/../Frameworks/libboost_system-
xgcc40-mt-1_39.dylib". At load time, the dynamic loader will resolve
such paths by substituting the directory containing the process
executable for "@executable_path". (You can also make install names
loader-relative using "@loader_path".)
Some options for solving the problem:
You could set the install name of the boost library by modifying the
boost build system to add or change the -install_name passed to the
link command.
You could set the install of the boost library just after it's built
by applying "install_name_tool -id" to it. Then when ServerXCode is
linked against it, it will automatically pick up the install name of
the boost library.
Or, you could modify ServerXCode after it has been linked to change
the install name it has recorded for the boost library, using
"install_name_tool -change".
The second and third options can be automated using a Run Script build
phase in your Xcode project.
In summary: boost is a bit odd in how it sets its install name; you
need to know how you plan to deploy the libraries on which your app
depends (fixed path or within a moveable application bundle); you need
to either arrange for the install name of your libraries to be set
accordingly prior to linking against them or adjust the dependent
library install paths in your executable after it has been linked.
Regards,
Ken
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden