Embedded Firebird on MacOSX
I have ported to OSX a firebird setup originally developed by Milan Babuskov for Linux: http://www.firebirdfaq.org/FirebirdEmbedded-Linux-HOWTO.html
First I copied the files that I needed from the Firebird Framework folders to another folder. For example, let's call it /Users/fulvio/firebird_runtime. Then I renamed the Firebird file to libfbembed.dylib: this is probably not necessary but I feel better using the same filename as is used on other platforms.
Files Structure
I create my application as a bundle. The executable file is stored in the folder Contents/MacOS inside the bundle. In this same folder I also store:
firebird.conf firebird - (a folder) firebird.msg libfbembed.dylib libicudata.dylib libicui18n.dylib libicuuc.dylib security2.fdb bin - (a folder) fb_lock_mgr gbak isql intl - (a folder) fbintl.conf fbintl.dylib
Indented files are stored into the folder above them so, for example, gbak is stored in the bundle as Contents/MacOS/firebird/bin/gbak.
I added some "copy files" build phase in XCode to copy the Firebird files from /Users/fulvio/firebird_runtime to the bundle.
Linking
I link the program against /Users/fulvio/firebird_runtime/libfbembed.dylib adding the following text to Other linker flags:
-L/Users/fulvio/firebird_runtime
and adding the Firebird .dylib files to the "Link Binary With Libraries" build phase in XCode.
Environment variables
The next step is to set the FIREBIRD environment variable to the executable folder. The command line is "export FIREBIRD=." The same result can be obtained adding:
<key>LSEnvironment</key> <dict> <key>FIREBIRD</key> <string>.</string> </dict>
to the Info.plist file contained in the bundle.
firebird.conf
Open the "firebird.conf" file and look for #RootDirectory. The leading pound sign means that the line is commented. Change it to:
RootDirectory = ./firebird
note that the line is not commented any more.
Patching
The bundle still doesn't work because the program looks for the libraries in the original framework's location, not in the bundle.
.dylib files contain their original full path and the original full path of all the used libraries, and executable files do the same. You can verify this running the otool -L and otool -D commands. I solved this problem using the install_name_tool command that changes the file reference contained in libraries and executables. It only works if the new paths are not longer than the old ones, but this is not a problem for us. I use a "Run Script" build phase in XCode to execute the following script:
#!/bin/bash EXECFILE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH} LIBPATH=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}/firebird NEWLIBPATH="@executable_path/firebird" OLDLIBPATH="/Library/Frameworks/Firebird.framework/Versions/A/Libraries" OLDLIBFBEMBEDFILENAME="/Library/Frameworks/Firebird.framework/Versions/A/Firebird" for TARGET in libfbembed.dylib libicudata.dylib libicui18n.dylib libicuuc.dylib ; do LIBFILE=${LIBPATH}/${TARGET} OLDTARGETID=${OLDLIBPATH}/${TARGET} NEWTARGETID=${NEWLIBPATH}/${TARGET} install_name_tool -id ${NEWTARGETID} ${LIBFILE} install_name_tool -change ${OLDTARGETID} ${NEWTARGETID} ${EXECFILE} for POSSIBLECALLERNAME in libfbembed.dylib libicudata.dylib libicui18n.dylib libicuuc.dylib ; do POSSIBLECALLERFILE=${LIBPATH}/${POSSIBLECALLERNAME} install_name_tool -change ${OLDTARGETID} ${NEWTARGETID} ${POSSIBLECALLERFILE} done done # change the reference to libfbembed into the caller program, that contains a reference to a different name (the framework name) NEWTARGETID=${NEWLIBPATH}/libfbembed.dylib install_name_tool -change ${OLDLIBFBEMBEDFILENAME} ${NEWTARGETID} ${EXECFILE}
I realize that the script is a little bit of overkill, but I am not an expert and it works, so I am satisfied.
Summary
I have described a method to use Firebird in a truly embedded way, without the need to separately install the database and without conflicts with other installations. I am not an OSX expert, so probably there are simpler ways to do the same thing, but this method can be used as a starting point.