For Linux and OS X it is possible to use the CMake INSTALL command. This command creates an INSTALL target in your development tool: buiding that target will copy files to the folder specified by the CMAKE_INSTALL_PREFIX variable.
This can be used to copy the compiled program, the Firebird runtime and other files as needed to the install folder. Then the install folder will contain a ready to run copy of the program, with all the needed files.
First use a variable to store the path of the files used by the Firebird embedded server. I keep them in a folder that has the same structure as the deployed files. Here is an example:
# look for the folder containing the firebird embedded files to ship with the program
find_path( FB_EMBEDDED_PATH firebird.conf ${PROJECT_SOURCE_DIR}/firebird_runtime ${PROJECT_SOURCE_DIR}/../../firebird_embedded_2.0.4_runtime )
message( STATUS "Embedded firebird files path: " ${FB_EMBEDDED_PATH} )
find_path( FB_EMBEDDED_PATH firebird.conf ${PROJECT_SOURCE_DIR}/firebird_runtime ${PROJECT_SOURCE_DIR}/../../firebird_embedded_2.0.4_runtime )
message( STATUS "Embedded firebird files path: " ${FB_EMBEDDED_PATH} )
At the end of CMakeLists.txt add code like this:
install( TARGETS vvv DESTINATION . )
if( APPLE )
# copy the Firebird runtime
install( DIRECTORY ${FB_EMBEDDED_PATH}/ DESTINATION vvv.app/Contents/MacOS USE_SOURCE_PERMISSIONS )
install( FILES ${FB_EMBEDDED_PATH}/firebird/firebird.msg DESTINATION vvv.app/Contents/MacOS/firebird/bin/firebird )
# fix filename references in the runtime
set( FIXUP_COMMAND ${PROJECT_SOURCE_DIR}/MACOSX_fixup_bundle.sh " " ${CMAKE_INSTALL_PREFIX}/vvv.app )
install( CODE "execute_process( COMMAND ${FIXUP_COMMAND} )" )
endif( APPLE )
if( UNIX AND NOT APPLE )
# copy the Firebird runtime
install( DIRECTORY ${FB_EMBEDDED_PATH}/ DESTINATION . USE_SOURCE_PERMISSIONS )
# copy other files used only for the Linux version
install( FILES ${PROJECT_SOURCE_DIR}/linux_specific/readme.txt
${PROJECT_SOURCE_DIR}/linux_specific/License.txt
DESTINATION . )
install( FILES ${PROJECT_SOURCE_DIR}/linux_specific/vvv-start.sh
DESTINATION . PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE
GROUP_READ WORLD_READ WORLD_EXECUTE )
endif( UNIX AND NOT APPLE )
if( UNIX )
# set the installation path of the executable file and the resources (in OS X they are inside the bundle )
if( APPLE )
set( EXECUTABLE_INTALL_PATH vvv.app/Contents/MacOS )
set( RESOURCES_INTALL_PATH vvv.app/Contents/Resources )
else( APPLE )
set( EXECUTABLE_INTALL_PATH . )
set( RESOURCES_INTALL_PATH . )
endif( APPLE )
install( FILES ${PROJECT_SOURCE_DIR}/vvv-struct-update.fdb
${PROJECT_SOURCE_DIR}/VVV.fbk
${PROJECT_SOURCE_DIR}/help/en/vvv.htb
DESTINATION ${EXECUTABLE_INTALL_PATH} )
endif( UNIX )
Under OS X CMake will execute a script named MACOSX_fixup_bundle.sh to patch the dylibs as described here. CMake has some support to automatically fix things like these: I struggled for some time but I was not able to understand how it works. Documentation is scarce to I gave up and I decided to directly run a script.
Here is the script used by CMake:
#!/bin/bash
# this script will fix the components of the Firebird runtime to make it run from any location
# the script receives the path of the bundle to fix
BUNDLEPATH=$*
# the following line contains the name of the executable file that will be patched
# it is the only line that should be changed when copying this file to another project
EXECFILE=${BUNDLEPATH}/Contents/MacOS/vvv
LIBPATH=${BUNDLEPATH}/Contents/MacOS/firebird
LIBBINPATH=${BUNDLEPATH}/Contents/MacOS/firebird/bin
# path of library files relative to the main executable
NEWLIBPATH="@executable_path/firebird"
# path of library files relative to other library files
NEWLIBPATH_FOR_LIBS="@loader_path"
# path of library files relative to executables in the "firebird/bin" folder
NEWLIBPATH_FROM_BIN="@loader_path/.."
OLDLIBPATH="/Library/Frameworks/Firebird.framework/Versions/A/Libraries"
OLDLIBFBEMBEDFILENAME="/Library/Frameworks/Firebird.framework/Versions/A/Firebird"
# change the references in the files contained in the "firebird" folder
for TARGET in libfbembed.dylib libicudata.dylib libicui18n.dylib libicuuc.dylib ; do
LIBFILE=${LIBPATH}/${TARGET}
OLDTARGETID=${OLDLIBPATH}/${TARGET}
NEWTARGETID=${NEWLIBPATH}/${TARGET}
NEWTARGETID_FOR_LIBS=${NEWLIBPATH_FOR_LIBS}/${TARGET}
install_name_tool -id ${NEWTARGETID_FOR_LIBS} ${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_FOR_LIBS} ${POSSIBLECALLERFILE}
done
done
# change the references in the files contained in the "firebird/bin" folder
for TARGET in gbak isql ; do
FILE=${LIBBINPATH}/${TARGET}
for POSSIBLECALLEDNAME in libfbembed.dylib libicudata.dylib libicui18n.dylib libicuuc.dylib ; do
OLDTARGETID=${OLDLIBPATH}/${POSSIBLECALLEDNAME}
NEWTARGETID=${NEWLIBPATH_FROM_BIN}/${POSSIBLECALLEDNAME}
install_name_tool -change ${OLDTARGETID} ${NEWTARGETID} ${FILE}
done
# change the reference to libfbembed into the program, that contains a reference to a different name (the framework name)
NEWTARGETID=${NEWLIBPATH_FROM_BIN}/libfbembed.dylib
install_name_tool -change ${OLDLIBFBEMBEDFILENAME} ${NEWTARGETID} ${FILE}
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}
You will need to edit the EXECFILE definition (near the file top) to change the name from "vvv" to your program's name.
No comments:
Post a Comment