dyld: Library not loaded: on OS X - c++

I'm building with g++ from the command line in OS X, and not using XCode. When I built my executable I had to include the linker flag to the library where the dynamic library was stored, but when I went to run the executable the dynamic library was not found, and I got the error dyld: Library not loaded: (foo).
There were a few questions on here already about dynamic libraries related to specific software packages and how to get dynamic libraries built into XCode projects, but nothing generic explaining how Mac OS X looks for dynamic libraries in general and how to get a new .dylib into the search path for the executable.
Could someone fill in that gap. How does Mac OS X look for dynamic libraries when one is built with an executable and how would I put a link to my dynamic library in the right place so the executable will run?
I'm on OSX 10.9 - Mavericks.

A good place to start would be the Apple documentation on Dynamic Library Programming Topics
and especially Run-Path Dependent Libraries.
"When the dynamic loader (dyld) loads the executable, it looks for run-path dependent libraries in the run-path search paths in the order in which they were specified at link time."
The first think is to check the libraries dependencies for you binary using otool:
otool -L /path/to/binary
Then, you have different solutions depending on how you want to distribute your library.
You can specify the absolute path of the library in the binary. It should be done with a tool, CMake for instance. Otherwise, you can use
install_name_tool to change the path to a library by hand.
Most of the time, you want to deploy your binary and put the dylibs in a separated folder. Those libraries are loaded relatively to where the binary is.
For example:
#loader_path/../Frameworks/Sparkle.framework/Versions/A/Sparkle
For more info about paths, I suggest you read this blog.

Related

How to let Cmake Install to link my executables to my target shared libraries [duplicate]

I have a question related to how to install a built executable program with cmake when it relies on some external libraries. Suppose my executable is abc, and it relies on two external libraries: lib1.so and lib2.so. The structure of the codes are as follows:
-.........
|----bin (lib1.so lib2.so)
|----include(lib1.h lib2.h)
|----src(main.cpp)
When the executable program is installed using the following cmake commands:
INSTALL(TARGETS ${Exe_Name}
RUNTIME DESTINATION Path to bin
LIBRARY DESTINATION Path to bin)
I expect that the executable program will be in the same directory with lib1.so and lib2.so. However, when I execute the built program in the installation folder, I met the following error:
error while loading shared libraries: lib1 can not open shared object file No such file or directory
If I use ldd to check the executable, I found lib1.so and lib2.so not found. After searching for possible solutions, I found if I call the executable in this way, then it worked:
LD_LIBRARY_PATH=./ ./my_program_run
Then my question is how I can let my executable program knows the locations of the shared libraries with cmake when it is installed? Thanks.
This is best solved this with the RPATH of the final executable. RPATH is a hardcoded search path for the executable itself, and allows the use of the string $ORIGIN, which expands to the location of the executable at runtime. See this reference: http://man7.org/linux/man-pages/man8/ld.so.8.html
CMake strips the rpath of a binary at installation time, to avoid the binary picking up libraries littered around your development tree. But it also provides a simple way to modify the installation rpath for exactly this reason. Here's the short answer:
IF(UNIX)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:\$ORIGIN/../bin:\$ORIGIN")
ENDIF()
This particular example appends to the existing rpath, and adds . and ../bin to the search path, all relative to the location of the binary.
Some developers claim that adjusting the RPATH of the binary is not a good idea. In the ideal world, all the libraries would live in the system library directories. But if you take this to the extreme, you end up with Windows (at least the older ones), where c:\windows\system32 is full of junk that came from who knows where, and may or may not conflict with other software, etc. Using rpath and installing everything in one place seems like a great solution.
If the application is to be cleanly installed to a standard linux distribution, then you should either install the supporting shared libraries into a standard location (/usr/lib), or you should add the libraries location to the ld.so config, by create an /etc/ld.so.conf.d/myprogram.conf file containing the name of the directory the libraries are in.
If the installation is temporary or more ad-hoc, then a script to set the LD_LIBRARY_PATH is suitable.
The libraries are searched in the predefined locations which includes standard library paths configured with ld.so.conf and LD_LIBRARY_PATH. You can also try to compile your app with -rpath, but it is not recommended by some developers. I suggest you to create a wrapper script which will set LD_LIBRARY_PATH and run the real application like that:
"theapp" script:
#!/bin/sh
dir="`dirname \"$0\"`"
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}"$dir"
exec "$dir/theapp.real" # your real application
The application, script and libraries should be in the same location (under bin/).

Xcode linking against static and dynamic library

I have some problems with linking my macOS app against C libraries.
I have several question related to this issue.
It is better to link app against dynamic or static libraries taking into account that this will be very custom libraries rather not shared with other apps?
I have linked my macOS Xcode app against ~14 static libraries .a and it works fine. I have reconfigured CMakeLists.txt making this libraries and now Xcode project doesn't work. The main change was changing the directory I have
"$(SRCROOT)/../../c/<project_name>/outputs/lib/apple/static"
But now I have both static (.a) and dynamic (.dylib) libraries in the same path
"$(SRCROOT)/../../c/server/outputs/lib/apple"
I don't know whether this should matter, but linking against static libraries causes that after running my Xcode project it complains that it cannot load lib.dylib So maybe it finds this dynamic library under Library Search Paths and tires to load them but don't find them linked?
So I tired to link Xcode macOS app against .dylib libraries and instead of static .a libraries added them in Link Binary with Libraries. The problem is that the error not finding library now also occurs.
Maybe I should change something here ? But what If I will distribute my app to some other computers that will not have libraries in this specific location. How can I include dynamic libraries in Xcode bundle in order to be always findable.
I know I added maybe to many question. But would like to know how to the best solve this issue? Better to link statically or dynamically and then how to correctly achieve this avoiding this error.
UPDATE
It seems that when linking against .dylib it only works when I add path to this library directory to Runpath Search Paths.
It also seems that when I link against static library .a it works when .dylib isn't in the same directory (I moved .a library into /static subdirectory) and then for this moved library error isn't showing any more. But isn't there way to link statically when there is .a and .dylib libraries inside the same directory?
I know this is an old question but it's one of the top results when searching google for "Xcode static linking."
I recently encountered this issue when integrating with Intel IPP, which puts static and dynamic libs in the same directory.
If I used the standard Xcode linking method of adding the library via the "Build Phases | Link Binary with Libraries," Xcode translated that UI into a command line that looked like this:
clang++ ... -L/my/path -lstatic1 -lstatic2 ...
But that causes the linker to prefer the DLL instead of the static library in the same directory.
I worked around this by removing the entries from the "Build Phases | Link Binary with Libraries" window, and adding full relative paths to the libraries in the "Build Settings | Other linker flags" entry:
../../path/to/lib/libstatic1.a ../../path/to/lib/libstatic2.a
This caused Xcode to translate the UI into a command line that looked like this:
clang++ ... ../../path/to/lib/libstatic1.a ../../path/to/lib/libstatic1.a ...
Which linked the libraries statically.
Finally, I have linked this Xcode macOS project with multiple dynamic C libraries (.dylib).
REMARK
In order to link with static libraries (.a) They cannot be placed side by side with dynamic libraries! path/project_name/outputs/lib/apple/*.dylib and then place static libs under path: path/project_name/outputs/lib/apple/static/.a As XCode tries to link dynamic libraries if they found them on Libraries Search Path in Build Settings.
DYNAMIC C LIBRARIES LINKIN IN XCODE
Add dynamic libraries to Build Phases tab and Link Binaries with Libraries section as on the image
Embed all this dynamic libraries in output macOS Application Wrapper
You get something like this:
Then in Build setting add Libraries Search Paths
And finally add Runtime Search Paths in Build Settings

How do I build and use a dynamic library on Mac OS X?

I have a very simple question that I've been trying to figure out for the last 6 hours or so. I want to simply build a dynamic library on Mac OS X, and then build an application using that library. I've created the .dylib and compiled the test application with it, but when I run the application I get:
Joes-Mac-Pro:Desktop Joe$ ./test
dyld: Library not loaded: ./lib/simple_library.dylib
Referenced from: /Users/Joe/Desktop/./test
Reason: image not found
Trace/BPT trap: 5
I've tried making a lib folder in the executable directory and putting the dylib inside, same error. I've tried putting the dylib in the executable path itself, same error. I've tried using install_name_tool to change the path to the dylib in the executable, nothing changes, same error. I've tried building the test application with -headerpad_max_install_names and then using install_name_tool to change the path. Still nothing changes. Same error.
Is what I'm trying to do not possible with the Mac operating system? I'm new to this platform, and am used to things like this working without a hitch on Windows and GNU/Linux. Also, I'm trying to do all this with the command line. I would very much prefer to avoid XCode.
Edit: Oops, I derped. Turns out I made a typo in my install_name_tool arguments. It's working fine now.
install_name_tool is the right tool.
Try otool your_binary to see which dylib are missing.
Also be sure your binary and the linked library are build for the same architectures.
You'll need to ensure that DYLD_LIBRARY_PATH includes the directory where your library resides.
DYLD_LIBRARY_PATH
This is a colon separated list of directories that contain libraries. The dynamic linker searches these directo-
ries before it searches the default locations for libraries. It allows you to test new versions of existing
libraries.
For each library that a program uses, the dynamic linker looks for it in each directory in DYLD_LIBRARY_PATH in
turn. If it still can't find the library, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and DYLD_FALL-
BACK_LIBRARY_PATH in turn.
Use the -L option to otool(1). to discover the frameworks and shared libraries that the executable is linked
against.
The various details of dynamic linking are documented in the dyld man page.

How can I get Xcode to link and debug an app with Boost Filesystem?

TL;DR
Objective-C app linked with static library that dynamic links Boost Filesystem. App can be run from output directory using Terminal, but trying to run from Xcode debugger or Finder gives error dyld: Library not loaded: libboost_filesystem.dylib <snip> Reason: image not found.
Problem
In my Xcode project I have a structure that looks like this:
MainProject (Objective-C)
- static_lib_that_uses_filesystem (C++)
To get everything to link, I added libboost_system and libboost_filesystem dylibs to the "Link Binary with Libraries" build phase in MainProject.
When I try to run the app from either Xcode or Finder I get:
sharedlibrary apply-load-rules all
warning: Unable to read symbols for libboost_filesystem.dylib (file not found).
warning: Unable to read symbols from "libboost_filesystem.dylib" (not yet mapped into memory).
warning: Unable to read symbols for libboost_system.dylib (file not found).
warning: Unable to read symbols from "libboost_system.dylib" (not yet mapped into memory).
[Switching to process 43957 thread 0x0]
dyld: Library not loaded: libboost_filesystem.dylib
Referenced from: /Users/ssteele/Library/Developer/Xcode/DerivedData/MainProject-dqrhyuarllykslftblocjdzxlran/Build/Products/Debug/MainProject.app/Contents/MacOS/MainProject
Reason: image not found
I added a build stage to copy the dylibs to the Frameworks directory in the bundle, this doesn't help. I changed this to copy them to the Executables directory which also didn't help.
Having them in the Executables directory does allow me to run the app from Terminal.
How can I get the app to find the dylibs when run from Finder/Xcode?
Background Info
I'm using Xcode 4.2 on Lion and currently targeting Lion only. I built my shared libraries for filesystem like this:
./b2 threading=multi macosx-version=10.7 --with-filesystem stage
This creates libboost_system.dylib, libboost_filesystem.dylib, and also .a equivalents in the stage/lib directory, I'm referencing them in the project directly from there.
Dynamic libs (dylibs) on OSX bake in the path that they should be loaded from. For example...
/usr/lib/some_awesome.dylib.
When you link to a dylib, the linker embeds this path in your executable as the place to look for it at runtime. This is fine and easy with installed libs, but for relative path linking it's more complicated.
When you build the boost libs, they just get their names embedded rather than a full or relative path (i.e. libboost_system.dylib rather than /usr/lib/libboost_filesystem.dylib). You should be able to change this with the dll-path option, but that seems broken currently.
To fix your problem you either need to get the correct path relative to your application embedded (e.g. #executable_path/libwhatever.dylib) into the dylibs somehow, which would probably require the bjam dll-path option to work, or instead you can fix your executable to look in a different location.
To do this, use something like the following as a script step in your build:
install_name_tool -change libboost_filesystem.dylib #executable_path/libboost_filesystem.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH
Note that if you have multiple dylibs that reference each other with broken paths, you'll need to fix the paths between them too, e.g.
install_name_tool -change libboost_system.dylib #executable_path/libboost_system.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_FOLDER_PATH/libboost_filesystem.dylib
The following is a good article on this: Creating working dylibs
The issue is that boost needs to be installed e.g. b2 ..... install. This copies the libraries and headers into /usr/local/lib and /usr/local/include.
OSX dynamic libraries only run from the directory that they are built for.
You can change the install directory by using the -prefix argument to boost build. However the libraries would still need to be in the same directory for all users.
There should be a way of building boost as a framework and/or embedding #executable_path in the library.
An alternative is to use boost's static libraries - build the static only or delete the dynamic ones, Xcode looks for dynamic before static. If using static then the path to the libraries does not matter at run time as all the code is now in the executable.
I think you need to add the path to the directory where you saved libboost_filesystem.a in the "library search paths"
Click on your project profile -> build settings -> expand "Search path" -> "library search paths"

eclipse sfml library issues

I pulled out an application that I wrote in C++ using the sfml library, but I'm having trouble setting up the library in Eclipse. I specified the include path, the lib path and included all the necessary .so libraries to link to. the application compiles fine but it complains at runtime about missing libraries. Why is this happening? Didn't I include the path to the libraries in the project settings already? I have even tried to place all the .so's in the executable directory with no luck.
There is only the name of the shared lib stored in the executable. At program startup the dynamic linker then searches for the specified libs in its search paths. You can add/specify search paths by placing them colon separated in the environment variable LD_LIBRARY_PATH or by specifying them in /etc/ld.so.conf (at least if you use some unix based OS). On windows the whole PATH environment variable is used when searching for dynamic-link libraries (DLL).
To see the paths of shared libraries used by a given application run ldd applicationPath.