Embedding a Dynamic Library in a Cocoa Application
Objective
Your application depends on a Dynamic Library that may not be on the users machine, and you don’t want to ship your application with an installer. The solution is to include the dylib in your application’s bundle. The problem is that dylibs have their path hard-coded in them. The solution is to use the Apple supplied command line tool install_name_tool
to modify the path inside the dylib to match its location inside your application bundle.
Steps
- Add a new Copy Files build phase
- Add a Shell Script build phase
Note: These build phases need be added before the Link Binary Libraries build phase
Copy Files Build Phase
Click the + button, click on the dynamic library already added to the Xcode project.
Destination = Shared Support
Subpath = leave blank
Copy Only When Installing = unchecked
Shell Script Build Phase
This buid phase needs to be after the Copy Files phase.
Here’s the soure code, which I downloaded from here. I had to play around with ynniv’s script to accound for spaces in path names. I’m guessing his projects didn’t have any spaces and he never ran into that problem.
#!/bin/bash
# In Xcode you actually enter the path for the shell
# you want to use in a text field about the shell source.
# So, !/bin/bash might not be necessary.
# Space separated list of libraries.
# Enter any dylibs you have in your Copy File Phase.
TARGETS=libusb-1.0.0.dylib
EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}
LIBPATH=${BUILT_PRODUCTS_DIR}/${SHARED_SUPPORT_FOLDER_PATH}
NEWLIBPATH=@executable_path/../SharedSupport
for TARGET in ${TARGETS} ; do
LIBFILE=${LIBPATH}/${TARGET}
TARGETID=`otool -DX "${LIBPATH}/$TARGET"`
NEWTARGETID=${NEWLIBPATH}/${TARGET}
install_name_tool -id "${NEWTARGETID}" "${LIBFILE}"
install_name_tool -change ${TARGETID} ${NEWTARGETID} "${EXECFILE}"
done
Reader Comments