Boost libraries on OSX - first obstacles
Building the boost/filesystem library was quite easy, using it in a program not so much. It compiled fine but when I started I got
dyld: Library not loaded: libboost_filesystem.dylib
Referenced from: ___path_to_the_program_I_started___
Reason: image not found
It's a dynamic library, which means that I must take care of the application bundle on OSX. When I transfer the application to another Mac that has - certainly - not its own copy of the libraries. But on my own computer?
Let's have a look. Walked in the directory with the .dylib
file.
otool -L ./libboost_filesystem.dylib
./libboost_filesystem.dylib:
libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
Looks not so bad, there is no absolute path to /usr/somewhere
in the library file. But hat also means that the system can not find the library while starting the program. And that brings me back to the "copy them to your application bundle" problem.
No absolute path is not perfect in the OSX world, there is a need for a @executable_path/../Frameworks
path in the library. So a compiled program will look in the Frameworks folder, relative from its own position.
Do I really need to recompile the Boost libraries or can I tell QtCreator to do the job for me? In the Qt helpfiles is a chapter called Qt for Mac OS X - Specific Issues where it reads
If you want to use some dynamic libraries in your Mac OS X application bundle (the application directory), create a subdirectory named "Frameworks" in the application bundle directory and place your dynamic libraries there. The application will find a dynamic library if it has the install name
@executable_path/../Frameworks/libname.dylib
(that goes for both, the program binary and the library). If you use qmake and Makefiles, use the QMAKE_LFLAGS_SONAME setting:
MAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/
A quick lookup in the qmake Variable Reference
is not very enlightening:
This variable specifies the link flags to set the name of shared objects, such as .so or .dll. The value of this variable is typically handled by qmake or qmake.conf and rarely needs to be modified.
The Qt project claims to have a good documentation. Well, I beg to differ. So far every time the tiny bits are missing when it goes into the important details that everyone will come across on the OSX platform or using Qt in general. If you are experienced in using compilers that question may never come up, but for a C++ novice like me it is fundamental. I don't know if the qmake variable is simply a placeholder for a compiler setting. And if it is, I'd like to know that it is that way and where to look for the meaning of it.
Lazy solution
Removing the *.dylib
files from the boost_1_53_0/stage/lib
directory forces the linker to use the *.a
files and that results in static linking. Easy way out but not a perfect solution. There are libraries that can't be used with static linking and be it just for licensing reasons. This article from qt.project.org goes into some of the details. Using the The Mac Deployment Tool will be covered in another post.