Adding a third party shared object library as a framework
The scenario here is that we have a third party shared object library that is built by an external makefile. This is fine but we want to try and maintain the OS X bundle structure and install the library within a framework.
Now there is nothing mystical about a framework as this document explains.
So a framework is nothing but our library placed into a folder with a framework extension. Our make file might build the shared library with a .so extension but it doesn't matter. A standalone OS X dynamic library normally has a .dylib extension but within a framework bundle it appears without this extension. In either case we just rename the shared library as appropriate.
We can make use of the versioning hierarchy if we want enabling us to link against a current version or against any specified version. A symlink in the root folder points directly to the current version of the dynamic library.
If we are building the library in Xcode we simply create a framework project. But in the external make file situation we can simply add a copy files build phase (or phases) to the app target that copies our library and headers into the required locations within the application bundle framework folder.
In this case I use a copy files build phase to copy libCint.so to [some app target]/Frameworks/Cint.framework/Versions/A.
A run script phase massages the library, renaming the shared object and inserting a symbolic link.
Note that we also need to change the library install name recorded within the executable binary to enable the dynamic linker find the library at run time. When the app is linked at compile time it will be linked against the original shared library and that install name will be inserted into the application binary. We need this install name to point to our framework so we change the install name within the binary using the install_name_tool.
cd "$BUILD_DIR/$BUILD_STYLE/$FULL_PRODUCT_NAME/Contents/Frameworks/Cint.framework"# rename the shared object library
dylib="Cint"
version="Versions/A"
soVersion="$version/libCint.so"
dylibVersion="$version/$dylib"if [ -e $soVersion ]; then
mv $soVersion $dylibVersion
fi# make root link
if [ ! -e $dylib ]; then
ln -s $dylibVersion $dylib
fi# patch the executable so that it knows where to look for the framework
cd "$BUILD_DIR/$BUILD_STYLE/$FULL_PRODUCT_NAME/Contents/MacOS"
install_name_tool -change lib/libCint.so "@executable_path/../Frameworks/Cint.framework/$dylibVersion" KosmicTaskCINTRunner
If the framework is private to the app then there is not much to gain by using the bundle version hierarchy beyond conformity. The possibility of adding additional resources (licensing info etc) associated with the shared library is a good reason to adopt this approach even for private frameworks.
